Permalink
Browse files

Avoid wrapping when shifting down the audio after scaling by a 20-bit…

… value. Fixes #9967
  • Loading branch information...
hrydgard committed Nov 30, 2017
1 parent d884eed commit 407812916d9cdab05a57ffeb69b6a5e254b5b21f
Showing with 31 additions and 7 deletions.
  1. +15 −4 Core/Util/AudioFormat.cpp
  2. +6 −0 Core/Util/AudioFormat.h
  3. +10 −3 Core/Util/AudioFormatNEON.cpp
@@ -37,7 +37,10 @@ void AdjustVolumeBlockStandard(s16 *out, s16 *in, size_t size, int leftVol, int
out += 16;
size -= 16;
}
} else {
}
#if 0
// This path wraps instead of clamps in _mm_slli_epi16. Needs fixing.
else {
// We have to shift inside the loop to avoid the signed 16-bit multiply issue.
int leftShift = 0;
int leftVol16 = leftVol;
@@ -63,9 +66,17 @@ void AdjustVolumeBlockStandard(s16 *out, s16 *in, size_t size, int leftVol, int
}
}
#endif
for (size_t i = 0; i < size; i += 2) {
out[i] = ApplySampleVolume(in[i], leftVol);
out[i + 1] = ApplySampleVolume(in[i + 1], rightVol);
#endif
if (leftVol <= 0x7fff && -leftVol <= 0x8000 && rightVol <= 0x7fff && -rightVol <= 0x8000) {
for (size_t i = 0; i < size; i += 2) {
out[i] = ApplySampleVolume(in[i], leftVol);
out[i + 1] = ApplySampleVolume(in[i + 1], rightVol);
}
} else {
for (size_t i = 0; i < size; i += 2) {
out[i] = ApplySampleVolume20Bit(in[i], leftVol);
out[i + 1] = ApplySampleVolume20Bit(in[i + 1], rightVol);
}
}
}
@@ -59,6 +59,12 @@ static inline s16 ApplySampleVolume(s16 sample, int vol) {
#endif
}
// We sacrifice a little volume precision to fit in 32 bits, for speed.
// Probably not worth it to make a special path for 64-bit CPUs.
static inline s16 ApplySampleVolume20Bit(s16 sample, int vol20) {
return clamp_s16((sample * (vol20 >> 4)) >> 12);
}
void SetupAudioFormats();
void AdjustVolumeBlockStandard(s16 *out, s16 *in, size_t size, int leftVol, int rightVol);
void ConvertS16ToF32(float *ou, const s16 *in, size_t size);
@@ -58,9 +58,16 @@ void AdjustVolumeBlockNEON(s16 *out, s16 *in, size_t size, int leftVol, int righ
}
}
for (size_t i = 0; i < size; i += 2) {
out[i] = ApplySampleVolume(in[i], leftVol);
out[i + 1] = ApplySampleVolume(in[i + 1], rightVol);
if (leftVol <= 0x7fff && -leftVol <= 0x8000 && rightVol <= 0x7fff && -rightVol <= 0x8000) {
for (size_t i = 0; i < size; i += 2) {
out[i] = ApplySampleVolume(in[i], leftVol);
out[i + 1] = ApplySampleVolume(in[i + 1], rightVol);
}
} else {
for (size_t i = 0; i < size; i += 2) {
out[i] = ApplySampleVolume20Bit(in[i], leftVol);
out[i + 1] = ApplySampleVolume20Bit(in[i + 1], rightVol);
}
}
}

0 comments on commit 4078129

Please sign in to comment.