mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-04 13:29:59 -05:00
sample-util: Fix "Darth Vader" panning bug
For muted channels, we forgot to increment a pointer, so if one channel was muted but not the other, sound became distorted in a Darth Vader like way. To test the difference, start two input streams and pan one of them hard left (or right). And hey, if you didn't think it sounded like Darth Vader, it's your imagination that's broken, not mine! ;-) BugLink: https://bugs.launchpad.net/bugs/928757 Signed-off-by: David Henningsson <david.henningsson@canonical.com>
This commit is contained in:
parent
0521db6cf7
commit
2ce7d38005
1 changed files with 78 additions and 91 deletions
|
|
@ -225,22 +225,21 @@ size_t pa_mix(
|
||||||
pa_mix_info *m = streams + i;
|
pa_mix_info *m = streams + i;
|
||||||
int32_t v, lo, hi, cv = m->linear[channel].i;
|
int32_t v, lo, hi, cv = m->linear[channel].i;
|
||||||
|
|
||||||
if (PA_UNLIKELY(cv <= 0))
|
if (PA_LIKELY(cv > 0)) {
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Multiplying the 32bit volume factor with the
|
/* Multiplying the 32bit volume factor with the
|
||||||
* 16bit sample might result in an 48bit value. We
|
* 16bit sample might result in an 48bit value. We
|
||||||
* want to do without 64 bit integers and hence do
|
* want to do without 64 bit integers and hence do
|
||||||
* the multiplication independently for the HI and
|
* the multiplication independently for the HI and
|
||||||
* LO part of the volume. */
|
* LO part of the volume. */
|
||||||
|
|
||||||
hi = cv >> 16;
|
hi = cv >> 16;
|
||||||
lo = cv & 0xFFFF;
|
lo = cv & 0xFFFF;
|
||||||
|
|
||||||
v = *((int16_t*) m->ptr);
|
|
||||||
v = ((v * lo) >> 16) + (v * hi);
|
|
||||||
sum += v;
|
|
||||||
|
|
||||||
|
v = *((int16_t*) m->ptr);
|
||||||
|
v = ((v * lo) >> 16) + (v * hi);
|
||||||
|
sum += v;
|
||||||
|
}
|
||||||
m->ptr = (uint8_t*) m->ptr + sizeof(int16_t);
|
m->ptr = (uint8_t*) m->ptr + sizeof(int16_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -269,16 +268,15 @@ size_t pa_mix(
|
||||||
pa_mix_info *m = streams + i;
|
pa_mix_info *m = streams + i;
|
||||||
int32_t v, lo, hi, cv = m->linear[channel].i;
|
int32_t v, lo, hi, cv = m->linear[channel].i;
|
||||||
|
|
||||||
if (PA_UNLIKELY(cv <= 0))
|
if (PA_LIKELY(cv > 0)) {
|
||||||
continue;
|
|
||||||
|
|
||||||
hi = cv >> 16;
|
hi = cv >> 16;
|
||||||
lo = cv & 0xFFFF;
|
lo = cv & 0xFFFF;
|
||||||
|
|
||||||
v = PA_INT16_SWAP(*((int16_t*) m->ptr));
|
|
||||||
v = ((v * lo) >> 16) + (v * hi);
|
|
||||||
sum += v;
|
|
||||||
|
|
||||||
|
v = PA_INT16_SWAP(*((int16_t*) m->ptr));
|
||||||
|
v = ((v * lo) >> 16) + (v * hi);
|
||||||
|
sum += v;
|
||||||
|
}
|
||||||
m->ptr = (uint8_t*) m->ptr + sizeof(int16_t);
|
m->ptr = (uint8_t*) m->ptr + sizeof(int16_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -308,13 +306,12 @@ size_t pa_mix(
|
||||||
int32_t cv = m->linear[channel].i;
|
int32_t cv = m->linear[channel].i;
|
||||||
int64_t v;
|
int64_t v;
|
||||||
|
|
||||||
if (PA_UNLIKELY(cv <= 0))
|
if (PA_LIKELY(cv > 0)) {
|
||||||
continue;
|
|
||||||
|
|
||||||
v = *((int32_t*) m->ptr);
|
|
||||||
v = (v * cv) >> 16;
|
|
||||||
sum += v;
|
|
||||||
|
|
||||||
|
v = *((int32_t*) m->ptr);
|
||||||
|
v = (v * cv) >> 16;
|
||||||
|
sum += v;
|
||||||
|
}
|
||||||
m->ptr = (uint8_t*) m->ptr + sizeof(int32_t);
|
m->ptr = (uint8_t*) m->ptr + sizeof(int32_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -344,13 +341,12 @@ size_t pa_mix(
|
||||||
int32_t cv = m->linear[channel].i;
|
int32_t cv = m->linear[channel].i;
|
||||||
int64_t v;
|
int64_t v;
|
||||||
|
|
||||||
if (PA_UNLIKELY(cv <= 0))
|
if (PA_LIKELY(cv > 0)) {
|
||||||
continue;
|
|
||||||
|
|
||||||
v = PA_INT32_SWAP(*((int32_t*) m->ptr));
|
|
||||||
v = (v * cv) >> 16;
|
|
||||||
sum += v;
|
|
||||||
|
|
||||||
|
v = PA_INT32_SWAP(*((int32_t*) m->ptr));
|
||||||
|
v = (v * cv) >> 16;
|
||||||
|
sum += v;
|
||||||
|
}
|
||||||
m->ptr = (uint8_t*) m->ptr + sizeof(int32_t);
|
m->ptr = (uint8_t*) m->ptr + sizeof(int32_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -380,13 +376,12 @@ size_t pa_mix(
|
||||||
int32_t cv = m->linear[channel].i;
|
int32_t cv = m->linear[channel].i;
|
||||||
int64_t v;
|
int64_t v;
|
||||||
|
|
||||||
if (PA_UNLIKELY(cv <= 0))
|
if (PA_LIKELY(cv > 0)) {
|
||||||
continue;
|
|
||||||
|
|
||||||
v = (int32_t) (PA_READ24NE(m->ptr) << 8);
|
|
||||||
v = (v * cv) >> 16;
|
|
||||||
sum += v;
|
|
||||||
|
|
||||||
|
v = (int32_t) (PA_READ24NE(m->ptr) << 8);
|
||||||
|
v = (v * cv) >> 16;
|
||||||
|
sum += v;
|
||||||
|
}
|
||||||
m->ptr = (uint8_t*) m->ptr + 3;
|
m->ptr = (uint8_t*) m->ptr + 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -416,13 +411,12 @@ size_t pa_mix(
|
||||||
int32_t cv = m->linear[channel].i;
|
int32_t cv = m->linear[channel].i;
|
||||||
int64_t v;
|
int64_t v;
|
||||||
|
|
||||||
if (PA_UNLIKELY(cv <= 0))
|
if (PA_LIKELY(cv > 0)) {
|
||||||
continue;
|
|
||||||
|
|
||||||
v = (int32_t) (PA_READ24RE(m->ptr) << 8);
|
|
||||||
v = (v * cv) >> 16;
|
|
||||||
sum += v;
|
|
||||||
|
|
||||||
|
v = (int32_t) (PA_READ24RE(m->ptr) << 8);
|
||||||
|
v = (v * cv) >> 16;
|
||||||
|
sum += v;
|
||||||
|
}
|
||||||
m->ptr = (uint8_t*) m->ptr + 3;
|
m->ptr = (uint8_t*) m->ptr + 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -452,13 +446,12 @@ size_t pa_mix(
|
||||||
int32_t cv = m->linear[channel].i;
|
int32_t cv = m->linear[channel].i;
|
||||||
int64_t v;
|
int64_t v;
|
||||||
|
|
||||||
if (PA_UNLIKELY(cv <= 0))
|
if (PA_LIKELY(cv > 0)) {
|
||||||
continue;
|
|
||||||
|
|
||||||
v = (int32_t) (*((uint32_t*)m->ptr) << 8);
|
|
||||||
v = (v * cv) >> 16;
|
|
||||||
sum += v;
|
|
||||||
|
|
||||||
|
v = (int32_t) (*((uint32_t*)m->ptr) << 8);
|
||||||
|
v = (v * cv) >> 16;
|
||||||
|
sum += v;
|
||||||
|
}
|
||||||
m->ptr = (uint8_t*) m->ptr + sizeof(int32_t);
|
m->ptr = (uint8_t*) m->ptr + sizeof(int32_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -488,13 +481,12 @@ size_t pa_mix(
|
||||||
int32_t cv = m->linear[channel].i;
|
int32_t cv = m->linear[channel].i;
|
||||||
int64_t v;
|
int64_t v;
|
||||||
|
|
||||||
if (PA_UNLIKELY(cv <= 0))
|
if (PA_LIKELY(cv > 0)) {
|
||||||
continue;
|
|
||||||
|
|
||||||
v = (int32_t) (PA_UINT32_SWAP(*((uint32_t*) m->ptr)) << 8);
|
|
||||||
v = (v * cv) >> 16;
|
|
||||||
sum += v;
|
|
||||||
|
|
||||||
|
v = (int32_t) (PA_UINT32_SWAP(*((uint32_t*) m->ptr)) << 8);
|
||||||
|
v = (v * cv) >> 16;
|
||||||
|
sum += v;
|
||||||
|
}
|
||||||
m->ptr = (uint8_t*) m->ptr + 3;
|
m->ptr = (uint8_t*) m->ptr + 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -523,13 +515,12 @@ size_t pa_mix(
|
||||||
pa_mix_info *m = streams + i;
|
pa_mix_info *m = streams + i;
|
||||||
int32_t v, cv = m->linear[channel].i;
|
int32_t v, cv = m->linear[channel].i;
|
||||||
|
|
||||||
if (PA_UNLIKELY(cv <= 0))
|
if (PA_LIKELY(cv > 0)) {
|
||||||
continue;
|
|
||||||
|
|
||||||
v = (int32_t) *((uint8_t*) m->ptr) - 0x80;
|
|
||||||
v = (v * cv) >> 16;
|
|
||||||
sum += v;
|
|
||||||
|
|
||||||
|
v = (int32_t) *((uint8_t*) m->ptr) - 0x80;
|
||||||
|
v = (v * cv) >> 16;
|
||||||
|
sum += v;
|
||||||
|
}
|
||||||
m->ptr = (uint8_t*) m->ptr + 1;
|
m->ptr = (uint8_t*) m->ptr + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -558,16 +549,15 @@ size_t pa_mix(
|
||||||
pa_mix_info *m = streams + i;
|
pa_mix_info *m = streams + i;
|
||||||
int32_t v, hi, lo, cv = m->linear[channel].i;
|
int32_t v, hi, lo, cv = m->linear[channel].i;
|
||||||
|
|
||||||
if (PA_UNLIKELY(cv <= 0))
|
if (PA_LIKELY(cv > 0)) {
|
||||||
continue;
|
|
||||||
|
|
||||||
hi = cv >> 16;
|
hi = cv >> 16;
|
||||||
lo = cv & 0xFFFF;
|
lo = cv & 0xFFFF;
|
||||||
|
|
||||||
v = (int32_t) st_ulaw2linear16(*((uint8_t*) m->ptr));
|
|
||||||
v = ((v * lo) >> 16) + (v * hi);
|
|
||||||
sum += v;
|
|
||||||
|
|
||||||
|
v = (int32_t) st_ulaw2linear16(*((uint8_t*) m->ptr));
|
||||||
|
v = ((v * lo) >> 16) + (v * hi);
|
||||||
|
sum += v;
|
||||||
|
}
|
||||||
m->ptr = (uint8_t*) m->ptr + 1;
|
m->ptr = (uint8_t*) m->ptr + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -596,16 +586,15 @@ size_t pa_mix(
|
||||||
pa_mix_info *m = streams + i;
|
pa_mix_info *m = streams + i;
|
||||||
int32_t v, hi, lo, cv = m->linear[channel].i;
|
int32_t v, hi, lo, cv = m->linear[channel].i;
|
||||||
|
|
||||||
if (PA_UNLIKELY(cv <= 0))
|
if (PA_LIKELY(cv > 0)) {
|
||||||
continue;
|
|
||||||
|
|
||||||
hi = cv >> 16;
|
hi = cv >> 16;
|
||||||
lo = cv & 0xFFFF;
|
lo = cv & 0xFFFF;
|
||||||
|
|
||||||
v = (int32_t) st_alaw2linear16(*((uint8_t*) m->ptr));
|
|
||||||
v = ((v * lo) >> 16) + (v * hi);
|
|
||||||
sum += v;
|
|
||||||
|
|
||||||
|
v = (int32_t) st_alaw2linear16(*((uint8_t*) m->ptr));
|
||||||
|
v = ((v * lo) >> 16) + (v * hi);
|
||||||
|
sum += v;
|
||||||
|
}
|
||||||
m->ptr = (uint8_t*) m->ptr + 1;
|
m->ptr = (uint8_t*) m->ptr + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -634,13 +623,12 @@ size_t pa_mix(
|
||||||
pa_mix_info *m = streams + i;
|
pa_mix_info *m = streams + i;
|
||||||
float v, cv = m->linear[channel].f;
|
float v, cv = m->linear[channel].f;
|
||||||
|
|
||||||
if (PA_UNLIKELY(cv <= 0))
|
if (PA_LIKELY(cv > 0)) {
|
||||||
continue;
|
|
||||||
|
|
||||||
v = *((float*) m->ptr);
|
|
||||||
v *= cv;
|
|
||||||
sum += v;
|
|
||||||
|
|
||||||
|
v = *((float*) m->ptr);
|
||||||
|
v *= cv;
|
||||||
|
sum += v;
|
||||||
|
}
|
||||||
m->ptr = (uint8_t*) m->ptr + sizeof(float);
|
m->ptr = (uint8_t*) m->ptr + sizeof(float);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -668,13 +656,12 @@ size_t pa_mix(
|
||||||
pa_mix_info *m = streams + i;
|
pa_mix_info *m = streams + i;
|
||||||
float v, cv = m->linear[channel].f;
|
float v, cv = m->linear[channel].f;
|
||||||
|
|
||||||
if (PA_UNLIKELY(cv <= 0))
|
if (PA_LIKELY(cv > 0)) {
|
||||||
continue;
|
|
||||||
|
|
||||||
v = PA_FLOAT32_SWAP(*(float*) m->ptr);
|
|
||||||
v *= cv;
|
|
||||||
sum += v;
|
|
||||||
|
|
||||||
|
v = PA_FLOAT32_SWAP(*(float*) m->ptr);
|
||||||
|
v *= cv;
|
||||||
|
sum += v;
|
||||||
|
}
|
||||||
m->ptr = (uint8_t*) m->ptr + sizeof(float);
|
m->ptr = (uint8_t*) m->ptr + sizeof(float);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue