mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-20 19:21:46 +00:00
optimized channel volume/pan handling
svn-id: r10028
This commit is contained in:
parent
457f2fc211
commit
eac128f011
@ -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
|
||||
|
@ -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<stereo, reverseStereo>::LinearRateConverter(st_rate_t inrate
|
||||
* Return number of samples processed.
|
||||
*/
|
||||
template<bool stereo, bool reverseStereo>
|
||||
int LinearRateConverter<stereo, reverseStereo>::flow(AudioInputStream &input, st_sample_t *obuf, st_size_t osamp, st_volume_t vol, byte vol_p, int8 pan)
|
||||
int LinearRateConverter<stereo, reverseStereo>::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<stereo, reverseStereo>::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<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, 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);
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user