mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-11-04 13:30:08 -05:00
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:
parent
a256766c10
commit
bdf80e58af
1 changed files with 20 additions and 2 deletions
|
|
@ -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; \
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue