Inverse MDCT no longer requires any scratch space
authorJean-Marc Valin <jmvalin@jmvalin.ca>
Mon, 23 Dec 2013 07:26:03 +0000 (02:26 -0500)
committerJean-Marc Valin <jmvalin@jmvalin.ca>
Mon, 23 Dec 2013 07:26:03 +0000 (02:26 -0500)
celt/mdct.c

index db6314c..5e3be84 100644 (file)
@@ -241,13 +241,10 @@ void clt_mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scala
    int i;
    int N, N2, N4;
    kiss_twiddle_scalar sine;
-   VARDECL(kiss_fft_cpx, f2);
-   SAVE_STACK;
    N = l->n;
    N >>= shift;
    N2 = N>>1;
    N4 = N>>2;
-   ALLOC(f2, N4, kiss_fft_cpx);
    /* sin(x) ~= x here */
 #ifdef FIXED_POINT
    sine = TRIG_UPSCALE*(QCONST16(0.7853981f, 15)+N2)/N;
@@ -260,27 +257,27 @@ void clt_mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scala
       /* Temp pointers to make it really clear to the compiler what we're doing */
       const kiss_fft_scalar * OPUS_RESTRICT xp1 = in;
       const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+stride*(N2-1);
-      kiss_fft_cpx * OPUS_RESTRICT yp = f2;
+      kiss_fft_scalar * OPUS_RESTRICT yp = out+(overlap>>1);
       const kiss_twiddle_scalar * OPUS_RESTRICT t = &l->trig[0];
       const opus_int16 * OPUS_RESTRICT bitrev = l->kfft[shift]->bitrev;
       for(i=0;i<N4;i++)
       {
+         int rev;
          kiss_fft_scalar yr, yi;
-         kiss_fft_cpx yc;
+         rev = *bitrev++;
          yr = -S_MUL(*xp2, t[i<<shift]) + S_MUL(*xp1,t[(N4-i)<<shift]);
          yi =  -S_MUL(*xp2, t[(N4-i)<<shift]) - S_MUL(*xp1,t[i<<shift]);
          /* Works because the cos is nearly one. We swap real and imag because we
             use an FFT instead of an IFFT. */
-         yc.i = yr - S_MUL(yi,sine);
-         yc.r = yi + S_MUL(yr,sine);
+         yp[2*rev+1] = yr - S_MUL(yi,sine);
+         yp[2*rev] = yi + S_MUL(yr,sine);
          /* Storing the pre-rotation directly in the bitrev order. */
-         yp[*bitrev++] = yc;
          xp1+=2*stride;
          xp2-=2*stride;
       }
    }
 
-   opus_fft_impl(l->kfft[shift], f2);
+   opus_fft_impl(l->kfft[shift], (kiss_fft_cpx*)(out+(overlap>>1)));
 
    /* Post-rotate and de-shuffle from both ends of the buffer at once to make
       it in-place. */
@@ -295,16 +292,16 @@ void clt_mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scala
          kiss_fft_scalar re, im, yr, yi;
          kiss_twiddle_scalar t0, t1;
          /* We swap real and imag because we're using an FFT instead of an IFFT. */
-         re = f2[i].i;
-         im = f2[i].r;
+         re = yp0[1];
+         im = yp0[0];
          t0 = t[i<<shift];
          t1 = t[(N4-i)<<shift];
          /* We'd scale up by 2 here, but instead it's done when mixing the windows */
          yr = S_MUL(re,t0) - S_MUL(im,t1);
          yi = S_MUL(im,t0) + S_MUL(re,t1);
          /* We swap real and imag because we're using an FFT instead of an IFFT. */
-         re = f2[N4-i-1].i;
-         im = f2[N4-i-1].r;
+         re = yp1[1];
+         im = yp1[0];
          /* works because the cos is nearly one */
          yp0[0] = -(yr - S_MUL(yi,sine));
          yp1[1] = yi + S_MUL(yr,sine);
@@ -340,5 +337,4 @@ void clt_mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scala
          wp2--;
       }
    }
-   RESTORE_STACK;
 }