saturate MDCT output
authorJean-Marc Valin <jmvalin@jmvalin.ca>
Thu, 21 Jul 2016 23:48:55 +0000 (19:48 -0400)
committerJean-Marc Valin <jmvalin@jmvalin.ca>
Fri, 22 Jul 2016 19:57:01 +0000 (15:57 -0400)
celt/arch.h
celt/mdct.c

index 05e434b..1615af3 100644 (file)
@@ -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
 
index 5c6dab5..a8497c6 100644 (file)
@@ -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;
       }