pcm: Fix the sound distortions for S24_3LE stream in pcm_softvol plugin

This patch fixes sound distortions in alsa-lib "softvol"
for S24_3LE sound stream, when softvol slider is not at 0.0dB
position.

Signed-off-by: CannibalZerg <cnb_zerg@yahoo.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
Zerg Cannibal 2009-12-21 22:19:14 +01:00 committed by Jaroslav Kysela
parent a256766c10
commit bdf80e58af

View file

@ -107,7 +107,8 @@ static inline int MULTI_DIV_32x16(int a, unsigned short b)
v.i = a; v.i = a;
y.i = 0; y.i = 0;
#if __BYTE_ORDER == __LITTLE_ENDIAN #if __BYTE_ORDER == __LITTLE_ENDIAN
x.i = (unsigned int)v.s[0] * b; x.i = (unsigned short)v.s[0];
x.i *= b;
y.s[0] = x.s[1]; y.s[0] = x.s[1];
y.i += (int)v.s[1] * b; y.i += (int)v.s[1] * b;
#else #else
@ -135,6 +136,23 @@ static inline int MULTI_DIV_int(int a, unsigned int b, int swap)
return swap ? (int)bswap_32(fraction) : fraction; return swap ? (int)bswap_32(fraction) : fraction;
} }
/* always little endian */
static inline int MULTI_DIV_24(int a, unsigned int b)
{
unsigned int gain = b >> VOL_SCALE_SHIFT;
int fraction;
fraction = MULTI_DIV_32x16(a, b & VOL_SCALE_MASK);
if (gain) {
long long amp = (long long)a * gain + fraction;
if (amp > (int)0x7fffff)
amp = (int)0x7fffff;
else if (amp < (int)0x800000)
amp = (int)0x800000;
return (int)amp;
}
return fraction;
}
static inline short MULTI_DIV_short(short a, unsigned int b, int swap) static inline short MULTI_DIV_short(short a, unsigned int b, int swap)
{ {
unsigned int gain = b >> VOL_SCALE_SHIFT; unsigned int gain = b >> VOL_SCALE_SHIFT;
@ -223,7 +241,7 @@ static inline short MULTI_DIV_short(short a, unsigned int b, int swap)
tmp = src[0] | \ tmp = src[0] | \
(src[1] << 8) | \ (src[1] << 8) | \
(((signed char *) src)[2] << 16); \ (((signed char *) src)[2] << 16); \
tmp = MULTI_DIV_int(tmp, vol_scale, 0); \ tmp = MULTI_DIV_24(tmp, vol_scale); \
dst[0] = tmp; \ dst[0] = tmp; \
dst[1] = tmp >> 8; \ dst[1] = tmp >> 8; \
dst[2] = tmp >> 16; \ dst[2] = tmp >> 16; \