diff options
-rw-r--r-- | sound/mixer.cpp | 10 | ||||
-rw-r--r-- | sound/rate.cpp | 22 | ||||
-rw-r--r-- | sound/rate.h | 30 |
3 files changed, 36 insertions, 26 deletions
diff --git a/sound/mixer.cpp b/sound/mixer.cpp index c8d0d5abe6..69d4e0d5af 100644 --- a/sound/mixer.cpp +++ b/sound/mixer.cpp @@ -654,9 +654,8 @@ ChannelRaw::ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *soun _id = id; _ptr = (byte *)sound; _flags = flags; - -#ifdef SOX_HACK +#ifdef SOX_HACK // Create the input stream if (flags & SoundMixer::FLAG_LOOP) { if (loopEnd == 0) { @@ -671,8 +670,9 @@ ChannelRaw::ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *soun // TODO: add support for SoundMixer::FLAG_REVERSE_STEREO // Get a rate converter instance - _converter = makeRateConverter(rate, mixer->getOutputRate(), _input->isStereo()); -// printf(" data has %d bits and is %s\n", + _converter = makeRateConverter(rate, mixer->getOutputRate(), _input->isStereo(), (flags & SoundMixer::FLAG_REVERSE_STEREO) != 0); +// printf("inrate %d, outrate %d, %d bits, %s\n", +// rate, mixer->getOutputRate(), // ((flags & SoundMixer::FLAG_16BITS) ? 16 : 8), // ((flags & SoundMixer::FLAG_UNSIGNED) ? "unsigned" : "signed")); #else @@ -760,7 +760,7 @@ ChannelStream::ChannelStream(SoundMixer *mixer, PlayingSoundHandle *handle, void // TODO: add support for SoundMixer::FLAG_REVERSE_STEREO // Get a rate converter instance - _converter = makeRateConverter(rate, mixer->getOutputRate(), _input->isStereo()); + _converter = makeRateConverter(rate, mixer->getOutputRate(), _input->isStereo(), (flags & SoundMixer::FLAG_REVERSE_STEREO) != 0); // printf(" data has %d bits and is %s\n", // ((flags & SoundMixer::FLAG_16BITS) ? 16 : 8), // ((flags & SoundMixer::FLAG_UNSIGNED) ? "unsigned" : "signed")); diff --git a/sound/rate.cpp b/sound/rate.cpp index f28aa035e3..18ec57fc66 100644 --- a/sound/rate.cpp +++ b/sound/rate.cpp @@ -99,7 +99,7 @@ int st_rate_start(eff_t effp, st_rate_t inrate, st_rate_t outrate) * Processed signed long samples from ibuf to obuf. * Return number of samples processed. */ -template<bool stereo> +template<bool stereo, int leftChannel> int st_rate_flow(eff_t effp, AudioInputStream &input, st_sample_t *obuf, st_size_t *osamp, st_volume_t vol) { rate_t rate = (rate_t) effp->priv; @@ -107,6 +107,8 @@ int st_rate_flow(eff_t effp, AudioInputStream &input, st_sample_t *obuf, st_size st_sample_t out; unsigned long tmp; + assert(leftChannel == 0 || leftChannel == 1); + ostart = obuf; oend = obuf + *osamp * 2; @@ -132,7 +134,7 @@ int st_rate_flow(eff_t effp, AudioInputStream &input, st_sample_t *obuf, st_size while (rate->ipos > rate->opos + 1) { // interpolate - out = (st_sample_t) (rate->ilast[0] + (((rate->icur[0] - rate->ilast[0]) * rate->opos_frac + (1UL << (FRAC_BITS-1))) >> FRAC_BITS)); + out = (st_sample_t) (rate->ilast[leftChannel] + (((rate->icur[leftChannel] - rate->ilast[leftChannel]) * rate->opos_frac + (1UL << (FRAC_BITS-1))) >> FRAC_BITS)); // adjust volume out = out * vol / 256; @@ -141,7 +143,7 @@ int st_rate_flow(eff_t effp, AudioInputStream &input, st_sample_t *obuf, st_size if (stereo) { // interpolate - out = (st_sample_t) (rate->ilast[1] + (((rate->icur[1] - rate->ilast[1]) * rate->opos_frac + (1UL << (FRAC_BITS-1))) >> FRAC_BITS)); + out = (st_sample_t) (rate->ilast[1-leftChannel] + (((rate->icur[1-leftChannel] - rate->ilast[1-leftChannel]) * rate->opos_frac + (1UL << (FRAC_BITS-1))) >> FRAC_BITS)); // adjust volume out = out * vol / 256; } @@ -165,15 +167,19 @@ the_end: return (ST_SUCCESS); } -LinearRateConverter::LinearRateConverter(st_rate_t inrate, st_rate_t outrate) { +LinearRateConverter::LinearRateConverter(st_rate_t inrate, st_rate_t outrate, bool reverseStereo) { + _reverseStereo = reverseStereo; st_rate_start(&effp, inrate, outrate); } int LinearRateConverter::flow(AudioInputStream &input, st_sample_t *obuf, st_size_t *osamp, st_volume_t vol) { - if (input.isStereo()) - return st_rate_flow<true>(&effp, input, obuf, osamp, vol); - else - return st_rate_flow<false>(&effp, input, obuf, osamp, vol); + if (input.isStereo()) { + if (_reverseStereo) + return st_rate_flow<true, 1>(&effp, input, obuf, osamp, vol); + else + return st_rate_flow<true, 0>(&effp, input, obuf, osamp, vol); + } else + return st_rate_flow<false, 0>(&effp, input, obuf, osamp, vol); } int LinearRateConverter::drain(st_sample_t *obuf, st_size_t *osamp, st_volume_t vol) { diff --git a/sound/rate.h b/sound/rate.h index 9a33e4ee2a..d7691538f3 100644 --- a/sound/rate.h +++ b/sound/rate.h @@ -58,8 +58,9 @@ public: }; class LinearRateConverter : public RateConverter { + bool _reverseStereo; public: - LinearRateConverter(st_rate_t inrate, st_rate_t outrate); + LinearRateConverter(st_rate_t inrate, st_rate_t outrate, bool reverseStereo); virtual int flow(AudioInputStream &input, st_sample_t *obuf, st_size_t *osamp, st_volume_t vol); virtual int drain(st_sample_t *obuf, st_size_t *osamp, st_volume_t vol); }; @@ -72,19 +73,19 @@ public: virtual int drain(st_sample_t *obuf, st_size_t *osamp, st_volume_t vol); }; -template<bool stereo> +template<bool stereo, bool reverseStereo> class CopyRateConverter : public RateConverter { public: virtual int flow(AudioInputStream &input, st_sample_t *obuf, st_size_t *osamp, st_volume_t vol) { - int16 tmp; + int16 tmp[2]; st_size_t len = *osamp; assert(input.isStereo() == stereo); while (!input.eof() && len--) { - tmp = input.read() * vol / 256; - clampedAdd(*obuf++, tmp); + tmp[0] = tmp[1] = input.read() * vol / 256; if (stereo) - tmp = input.read() * vol / 256; - clampedAdd(*obuf++, tmp); + tmp[reverseStereo ? 0 : 1] = input.read() * vol / 256; + clampedAdd(*obuf++, tmp[0]); + clampedAdd(*obuf++, tmp[1]); } return (ST_SUCCESS); } @@ -93,15 +94,18 @@ public: } }; -static inline RateConverter *makeRateConverter(st_rate_t inrate, st_rate_t outrate, bool stereo) { +static inline RateConverter *makeRateConverter(st_rate_t inrate, st_rate_t outrate, bool stereo, bool reverseStereo = false) { if (inrate != outrate) { - return new LinearRateConverter(inrate, outrate); + return new LinearRateConverter(inrate, outrate, reverseStereo); //return new ResampleRateConverter(inrate, outrate, 1); } else { - if (stereo) - return new CopyRateConverter<true>(); - else - return new CopyRateConverter<false>(); + if (stereo) { + if (reverseStereo) + return new CopyRateConverter<true, true>(); + else + return new CopyRateConverter<true, false>(); + } else + return new CopyRateConverter<false, false>(); } } |