aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sound/mixer.cpp10
-rw-r--r--sound/rate.cpp22
-rw-r--r--sound/rate.h30
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>();
}
}