diff options
author | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2016-07-22 02:48:55 +0300 |
---|---|---|
committer | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2016-07-22 22:57:01 +0300 |
commit | 382ab797cfdb405b0a634629e926cee8590c99c2 (patch) | |
tree | 483ff3cc656106f870357f76f12bbbeaf58a967d | |
parent | 273906404c1647ef9f43c27fc1efced3c7af96f4 (diff) |
saturate MDCT output
-rw-r--r-- | celt/arch.h | 3 | ||||
-rw-r--r-- | celt/mdct.c | 8 |
2 files changed, 7 insertions, 4 deletions
diff --git a/celt/arch.h b/celt/arch.h index 05e434b9..1615af39 100644 --- a/celt/arch.h +++ b/celt/arch.h @@ -101,6 +101,9 @@ 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) #define NORM_SCALING 16384 diff --git a/celt/mdct.c b/celt/mdct.c index 5c6dab5b..a8497c66 100644 --- a/celt/mdct.c +++ b/celt/mdct.c @@ -306,16 +306,16 @@ void clt_mdct_backward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_sca /* We swap real and imag because we're using an FFT instead of an IFFT. */ re = yp1[1]; im = yp1[0]; - yp0[0] = yr; - yp1[1] = yi; + yp0[0] = SATURATE(yr, SIG_SAT); + yp1[1] = SATURATE(yi, SIG_SAT); t0 = t[(N4-i-1)]; t1 = t[(N2-i-1)]; /* We'd scale up by 2 here, but instead it's done when mixing the windows */ yr = ADD32_ovflw(S_MUL(re,t0), S_MUL(im,t1)); yi = SUB32_ovflw(S_MUL(re,t1), S_MUL(im,t0)); - yp1[0] = yr; - yp0[1] = yi; + yp1[0] = SATURATE(yr, SIG_SAT); + yp0[1] = SATURATE(yi, SIG_SAT); yp0 += 2; yp1 -= 2; } |