From b5a1204b38db912f82429f156c6c3e161ea0e9b3 Mon Sep 17 00:00:00 2001 From: Jean-Marc Valin Date: Thu, 4 Jul 2024 21:25:45 -0400 Subject: [PATCH] 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. --- celt/arch.h | 11 ++++++++--- celt/celt_decoder.c | 12 ++++++------ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/celt/arch.h b/celt/arch.h index 3845c3a08..c14b775eb 100644 --- a/celt/arch.h +++ b/celt/arch.h @@ -132,9 +132,14 @@ typedef opus_val32 celt_ener; #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 diff --git a/celt/celt_decoder.c b/celt/celt_decoder.c index 74e3e1917..ee927342a 100644 --- a/celt/celt_decoder.c +++ b/celt/celt_decoder.c @@ -261,8 +261,8 @@ static void deemphasis_stereo_simple(celt_sig *in[], opus_val16 *pcm, int N, con { 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 @@ void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, c opus_val16 coef3 = coef[3]; for (j=0;j