Skip to content

Commit

Permalink
Saturate de-emphasis so we can increase SIG_SAT
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jmvalin committed Sep 27, 2024
1 parent f98caf6 commit 3927515
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 9 deletions.
11 changes: 8 additions & 3 deletions celt/arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
12 changes: 6 additions & 6 deletions celt/celt_decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -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<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);
Expand All @@ -328,7 +328,7 @@ void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, c
/* 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;
}
Expand All @@ -340,7 +340,7 @@ void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, c
{
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))));
}
Expand All @@ -349,7 +349,7 @@ void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, c
{
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));
}
Expand Down

0 comments on commit 3927515

Please sign in to comment.