From eac128f0118314578a19faf4cdcfdca25ca8666f Mon Sep 17 00:00:00 2001 From: Max Horn Date: Fri, 5 Sep 2003 23:27:11 +0000 Subject: optimized channel volume/pan handling svn-id: r10028 --- sound/mixer.cpp | 25 ++++++++++++++++++------- sound/rate.cpp | 51 +++++++++++++++++++-------------------------------- sound/rate.h | 2 +- 3 files changed, 38 insertions(+), 40 deletions(-) (limited to 'sound') diff --git a/sound/mixer.cpp b/sound/mixer.cpp index fe9c43a65c..1f8ba5ce39 100644 --- a/sound/mixer.cpp +++ b/sound/mixer.cpp @@ -68,8 +68,6 @@ public: _volume = volume; } virtual void setChannelPan(const int8 pan) { - if (pan != 0) - printf("Pan set to %d\n", pan); _pan = pan; } virtual int getVolume() const { @@ -503,7 +501,21 @@ void Channel::mix(int16 *data, uint len) { destroy(); } else { assert(_converter); - _converter->flow(*_input, data, len, getVolume(), _volume, _pan); + + // The pan value ranges from -127 to +127. That's 255 different values. + // From the channel pan/volume and the global volume, we compute the + // effective volume for the left and right channel. + // Note the slightly odd divisor: the 255 reflects the fact that + // the maximal value for _volume is 255, while the 254 is there + // because the maximal left/right pan value is 2*127 = 254. + // The value getVolume() returns is in the range 0 - 256. + // Hence, the vol_l/vol_r values will be in that range, too + + int vol = getVolume() * _volume; + st_volume_t vol_l = (127 - _pan) * vol / (255 * 254); + st_volume_t vol_r = (127 + _pan) * vol / (255 * 254); + + _converter->flow(*_input, data, len, vol_l, vol_r); } } @@ -575,11 +587,10 @@ void ChannelStream::mix(int16 *data, uint len) { if (_finished) { destroy(); } - return; + } else { + // Invoke the parent implementation. + Channel::mix(data, len); } - - assert(_converter); - _converter->flow(*_input, data, len, getVolume(), _volume, _pan); } #ifdef USE_MAD diff --git a/sound/rate.cpp b/sound/rate.cpp index e4f9fb6b19..e7e5209325 100644 --- a/sound/rate.cpp +++ b/sound/rate.cpp @@ -80,7 +80,7 @@ protected: public: LinearRateConverter(st_rate_t inrate, st_rate_t outrate); - int flow(AudioInputStream &input, st_sample_t *obuf, st_size_t osamp, st_volume_t vol, byte vol_p, int8 pan); + int flow(AudioInputStream &input, st_sample_t *obuf, st_size_t osamp, st_volume_t vol_l, st_volume_t vol_r); int drain(st_sample_t *obuf, st_size_t osamp, st_volume_t vol) { return (ST_SUCCESS); } @@ -124,10 +124,10 @@ LinearRateConverter::LinearRateConverter(st_rate_t inrate * Return number of samples processed. */ template -int LinearRateConverter::flow(AudioInputStream &input, st_sample_t *obuf, st_size_t osamp, st_volume_t vol, byte vol_p, int8 pan) +int LinearRateConverter::flow(AudioInputStream &input, st_sample_t *obuf, st_size_t osamp, st_volume_t vol_l, st_volume_t vol_r) { st_sample_t *ostart, *oend; - st_sample_t out[2], tmpOut; + st_sample_t out[2]; const int numChannels = stereo ? 2 : 1; int i; @@ -159,30 +159,19 @@ int LinearRateConverter::flow(AudioInputStream &input, st while (ipos > opos) { // interpolate - tmpOut = (st_sample_t)(ilast[0] + (((icur[0] - ilast[0]) * opos_frac + (1UL << (FRAC_BITS-1))) >> FRAC_BITS)); - // adjust volume - out[0] = out[1] = (st_sample_t)((tmpOut * vol) >> 8); - + out[0] = out[1] = (st_sample_t)(ilast[0] + (((icur[0] - ilast[0]) * opos_frac + (1UL << (FRAC_BITS-1))) >> FRAC_BITS)); + if (stereo) { // interpolate - tmpOut = (st_sample_t)(ilast[1] + (((icur[1] - ilast[1]) * opos_frac + (1UL << (FRAC_BITS-1))) >> FRAC_BITS)); - // adjust volume - out[reverseStereo ? 0 : 1] = (st_sample_t)((tmpOut * vol) >> 8); + out[reverseStereo ? 0 : 1] = (st_sample_t)(ilast[1] + (((icur[1] - ilast[1]) * opos_frac + (1UL << (FRAC_BITS-1))) >> FRAC_BITS)); } - - byte pan_l = abs(pan - 128); - byte pan_r = abs(pan + 128); - out[0] = (st_sample_t)((out[0] * vol_p) >> 8); - out[1] = (st_sample_t)((out[1] * vol_p) >> 8); - out[0] = (st_sample_t)((out[0] * pan_l) >> 8); - out[1] = (st_sample_t)((out[1] * pan_r) >> 8); // output left channel - clampedAdd(*obuf++, out[0]); - + clampedAdd(*obuf++, (out[0] * (int)vol_l) >> 8); + // output right channel - clampedAdd(*obuf++, out[1]); - + clampedAdd(*obuf++, (out[1] * (int)vol_r) >> 8); + // Increment output position unsigned long tmp = opos_frac + opos_inc_frac; opos += opos_inc + (tmp >> FRAC_BITS); @@ -208,22 +197,20 @@ the_end: template class CopyRateConverter : public RateConverter { public: - virtual int flow(AudioInputStream &input, st_sample_t *obuf, st_size_t osamp, st_volume_t vol, byte vol_p, int8 pan) { + virtual int flow(AudioInputStream &input, st_sample_t *obuf, st_size_t osamp, st_volume_t vol_l, st_volume_t vol_r) { int16 tmp[2]; st_size_t len = osamp; assert(input.isStereo() == stereo); while (!input.eos() && len--) { - tmp[0] = tmp[1] = (input.read() * vol) >> 8; + tmp[0] = tmp[1] = input.read(); if (stereo) - tmp[reverseStereo ? 0 : 1] = (input.read() * vol) >> 8; - byte pan_l = abs(pan - 128); - byte pan_r = abs(pan + 128); - tmp[0] = ((tmp[0] * vol_p) >> 8); - tmp[1] = ((tmp[1] * vol_p) >> 8); - tmp[0] = ((tmp[0] * pan_l) >> 8); - tmp[1] = ((tmp[1] * pan_r) >> 8); - clampedAdd(*obuf++, tmp[0]); - clampedAdd(*obuf++, tmp[1]); + tmp[reverseStereo ? 0 : 1] = input.read(); + + // output left channel + clampedAdd(*obuf++, (tmp[0] * (int)vol_l) >> 8); + + // output right channel + clampedAdd(*obuf++, (tmp[1] * (int)vol_r) >> 8); } return (ST_SUCCESS); } diff --git a/sound/rate.h b/sound/rate.h index c693a165bd..e1f72065bd 100644 --- a/sound/rate.h +++ b/sound/rate.h @@ -62,7 +62,7 @@ class RateConverter { public: RateConverter() {} virtual ~RateConverter() {} - virtual int flow(AudioInputStream &input, st_sample_t *obuf, st_size_t osamp, st_volume_t vol, byte vol_p, int8 pan) = 0; + virtual int flow(AudioInputStream &input, st_sample_t *obuf, st_size_t osamp, st_volume_t vol_l, st_volume_t vol_r) = 0; virtual int drain(st_sample_t *obuf, st_size_t osamp, st_volume_t vol) = 0; }; -- cgit v1.2.3