Saturate MDCT output post-TDAC rather than pre-
authorJean-Marc Valin <jmvalin@jmvalin.ca>
Sun, 24 Jul 2016 21:40:44 +0000 (17:40 -0400)
committerJean-Marc Valin <jmvalin@jmvalin.ca>
Mon, 25 Jul 2016 01:35:24 +0000 (21:35 -0400)
Gives us a tighter bound on the pitch postfilter input to avoid overflows

celt/celt_decoder.c
celt/mdct.c

index 6f7b34d..0d9364d 100644 (file)
@@ -345,6 +345,12 @@ void celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[],
             clt_mdct_backward(&mode->mdct, &freq[b], out_syn[c]+NB*b, mode->window, overlap, shift, B, arch);
       } while (++c<CC);
    }
+   /* Saturate IMDCT output so that we can't overflow in the pitch postfilter
+      or in the */
+   c=0; do {
+      for (i=0;i<N;i++)
+         out_syn[c][i] = SATURATE(out_syn[c][i], SIG_SAT);
+   } while (++c<CC);
    RESTORE_STACK;
 }
 
index a8497c6..5c6dab5 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] = SATURATE(yr, SIG_SAT);
-         yp1[1] = SATURATE(yi, SIG_SAT);
+         yp0[0] = yr;
+         yp1[1] = yi;
 
          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] = SATURATE(yr, SIG_SAT);
-         yp0[1] = SATURATE(yi, SIG_SAT);
+         yp1[0] = yr;
+         yp0[1] = yi;
          yp0 += 2;
          yp1 -= 2;
       }