ref: 5c13840b53e6124fa52ba3e83a42c4f528626211
parent: 7b317ceb12f33499b32690762d07f5f220a321fa
author: Jean-Marc Valin <jeanmarcv@google.com>
date: Thu Jul 4 17:25:45 EDT 2024
Saturate de-emphasis so we can increase SIG_SAT We were originally saturating the comb filter with enough margin that the de-emphasis couldn't overflow at low frequency (1/(1-.85) gain). The problem is that didn't leave enough headroom for a full-scale HF signal.
--- a/celt/arch.h
+++ b/celt/arch.h
@@ -132,9 +132,14 @@
#define Q15ONE 32767
#define SIG_SHIFT 12
-/* Safe saturation value for 32-bit signals. Should be less than
- 2^31*(1-0.85) to avoid blowing up on DC at deemphasis.*/
-#define SIG_SAT (300000000)
+/* Safe saturation value for 32-bit signals. We need to make sure that we can
+ add two sig values and that the first stages of the MDCT don't cause an overflow.
+ The most constraining is the ARM_ASM comb filter where we shift left by one
+ and then add two values. Because of that, we use 2^29-1. SIG_SAT must be large
+ enough to fit a full-scale high-freq tone through the prefilter and comb filter,
+ meaning 1.85*1.75*2^(15+SIG_SHIFT) = 434529895.
+ so the limit should be about 2^31*sqrt(.5). */
+#define SIG_SAT (536870911)
#define NORM_SCALING 16384
--- a/celt/celt_decoder.c
+++ b/celt/celt_decoder.c
@@ -261,8 +261,8 @@
{
celt_sig tmp0, tmp1;
/* Add VERY_SMALL to x[] first to reduce dependency chain. */
- tmp0 = x0[j] + VERY_SMALL + m0;
- tmp1 = x1[j] + VERY_SMALL + m1;
+ tmp0 = SATURATE(x0[j] + VERY_SMALL + m0, SIG_SAT);
+ tmp1 = SATURATE(x1[j] + VERY_SMALL + m1, SIG_SAT);
m0 = MULT16_32_Q15(coef0, tmp0);
m1 = MULT16_32_Q15(coef0, tmp1);
pcm[2*j ] = SCALEOUT(SIG2WORD16(tmp0));
@@ -314,7 +314,7 @@
opus_val16 coef3 = coef[3];
for (j=0;j<N;j++)
{
- celt_sig tmp = x[j] + m + VERY_SMALL;
+ celt_sig tmp = SATURATE(x[j] + m + VERY_SMALL, SIG_SAT);
m = MULT16_32_Q15(coef0, tmp)
- MULT16_32_Q15(coef1, x[j]);
tmp = SHL32(MULT16_32_Q15(coef3, tmp), 2);
@@ -328,7 +328,7 @@
/* Shortcut for the standard (non-custom modes) case */
for (j=0;j<N;j++)
{
- celt_sig tmp = x[j] + VERY_SMALL + m;
+ celt_sig tmp = SATURATE(x[j] + VERY_SMALL + m, SIG_SAT);
m = MULT16_32_Q15(coef0, tmp);
scratch[j] = tmp;
}
@@ -340,7 +340,7 @@
{
for (j=0;j<N;j++)
{
- celt_sig tmp = x[j] + m + VERY_SMALL;
+ celt_sig tmp = SATURATE(x[j] + m + VERY_SMALL, SIG_SAT);
m = MULT16_32_Q15(coef0, tmp);
y[j*C] = SAT16(ADD32(y[j*C], SCALEOUT(SIG2WORD16(tmp))));
}
@@ -349,7 +349,7 @@
{
for (j=0;j<N;j++)
{
- celt_sig tmp = x[j] + VERY_SMALL + m;
+ celt_sig tmp = SATURATE(x[j] + VERY_SMALL + m, SIG_SAT);
m = MULT16_32_Q15(coef0, tmp);
y[j*C] = SCALEOUT(SIG2WORD16(tmp));
}
--
⑨