shithub: opus

Download patch

ref: a6b4e25628b3ea2671aec87058805b83c5b48b34
parent: dbeb86fd0531b618b501a76414536b27d8d4484f
author: Jean-Marc Valin <[email protected]>
date: Mon Aug 15 06:20:06 EDT 2011

Making the MDCT produce interleaved data

--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -401,32 +401,24 @@
    if (C==1 && !shortBlocks)
    {
       const int overlap = OVERLAP(mode);
-      clt_mdct_forward(&mode->mdct, in, out, mode->window, overlap, mode->maxLM-LM);
+      clt_mdct_forward(&mode->mdct, in, out, mode->window, overlap, mode->maxLM-LM, 1);
    } else {
       const int overlap = OVERLAP(mode);
       int N = mode->shortMdctSize<<LM;
       int B = 1;
       int b, c;
-      VARDECL(opus_val32, tmp);
-      SAVE_STACK;
       if (shortBlocks)
       {
-         /*lookup = &mode->mdct[0];*/
          N = mode->shortMdctSize;
          B = shortBlocks;
       }
-      ALLOC(tmp, N, opus_val32);
       c=0; do {
          for (b=0;b<B;b++)
          {
-            int j;
-            clt_mdct_forward(&mode->mdct, in+c*(B*N+overlap)+b*N, tmp, mode->window, overlap, shortBlocks ? mode->maxLM : mode->maxLM-LM);
-            /* Interleaving the sub-frames */
-            for (j=0;j<N;j++)
-               out[(j*B+b)+c*N*B] = tmp[j];
+            /* Interleaving the sub-frames while doing the MDCTs */
+            clt_mdct_forward(&mode->mdct, in+c*(B*N+overlap)+b*N, &out[b+c*N*B], mode->window, overlap, shortBlocks ? mode->maxLM : mode->maxLM-LM, B);
          }
       } while (++c<C);
-      RESTORE_STACK;
    }
 }
 
--- a/libcelt/mdct.c
+++ b/libcelt/mdct.c
@@ -99,7 +99,8 @@
 
 #endif /* CUSTOM_MODES */
 
-void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * restrict out, const opus_val16 *window, int overlap, int shift)
+void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * restrict out,
+      const opus_val16 *window, int overlap, int shift, int stride)
 {
    int i;
    int N, N2, N4;
@@ -124,7 +125,7 @@
       /* Temp pointers to make it really clear to the compiler what we're doing */
       const kiss_fft_scalar * restrict xp1 = in+(overlap>>1);
       const kiss_fft_scalar * restrict xp2 = in+N2-1+(overlap>>1);
-      kiss_fft_scalar * restrict yp = out;
+      kiss_fft_scalar * restrict yp = f;
       const opus_val16 * restrict wp1 = window+(overlap>>1);
       const opus_val16 * restrict wp2 = window+(overlap>>1)-1;
       for(i=0;i<(overlap>>2);i++)
@@ -160,7 +161,7 @@
    }
    /* Pre-rotation */
    {
-      kiss_fft_scalar * restrict yp = out;
+      kiss_fft_scalar * restrict yp = f;
       const kiss_twiddle_scalar *t = &l->trig[0];
       for(i=0;i<N4;i++)
       {
@@ -176,14 +177,14 @@
    }
 
    /* N/4 complex FFT, down-scales by 4/N */
-   opus_fft(l->kfft[shift], (kiss_fft_cpx *)out, (kiss_fft_cpx *)f);
+   opus_fft(l->kfft[shift], (kiss_fft_cpx *)f, (kiss_fft_cpx *)in);
 
    /* Post-rotate */
    {
       /* Temp pointers to make it really clear to the compiler what we're doing */
-      const kiss_fft_scalar * restrict fp = f;
+      const kiss_fft_scalar * restrict fp = in;
       kiss_fft_scalar * restrict yp1 = out;
-      kiss_fft_scalar * restrict yp2 = out+N2-1;
+      kiss_fft_scalar * restrict yp2 = out+stride*(N2-1);
       const kiss_twiddle_scalar *t = &l->trig[0];
       /* Temp pointers to make it really clear to the compiler what we're doing */
       for(i=0;i<N4;i++)
@@ -195,8 +196,8 @@
          *yp1 = yr - S_MUL(yi,sine);
          *yp2 = yi + S_MUL(yr,sine);;
          fp += 2;
-         yp1 += 2;
-         yp2 -= 2;
+         yp1 += 2*stride;
+         yp2 -= 2*stride;
       }
    }
    RESTORE_STACK;
--- a/libcelt/mdct.h
+++ b/libcelt/mdct.h
@@ -56,7 +56,8 @@
 void clt_mdct_clear(mdct_lookup *l);
 
 /** Compute a forward MDCT and scale by 4/N */
-void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar *out, const opus_val16 *window, int overlap, int shift);
+void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar *out,
+      const opus_val16 *window, int overlap, int shift, int stride);
 
 /** Compute a backward MDCT (no scaling) and performs weighted overlap-add
     (scales implicitly by 1/2) */
--- a/libcelt/tests/mdct-test.c
+++ b/libcelt/tests/mdct-test.c
@@ -93,6 +93,7 @@
     size_t buflen = sizeof(kiss_fft_scalar)*nfft;
 
     kiss_fft_scalar  * in = (kiss_fft_scalar*)malloc(buflen);
+    kiss_fft_scalar  * in_copy = (kiss_fft_scalar*)malloc(buflen);
     kiss_fft_scalar  * out= (kiss_fft_scalar*)malloc(buflen);
     opus_val16  * window= (opus_val16*)malloc(sizeof(opus_val16)*nfft/2);
     int k;
@@ -116,6 +117,8 @@
        }
     }
 
+    for (k=0;k<nfft;++k)
+       in_copy[k] = in[k];
     /*for (k=0;k<nfft;++k) printf("%d %d ", in[k].r, in[k].i);printf("\n");*/
 
     if (isinverse)
@@ -125,8 +128,8 @@
        clt_mdct_backward(&cfg,in,out, window, nfft/2, 0, 1);
        check_inv(in,out,nfft,isinverse);
     } else {
-       clt_mdct_forward(&cfg,in,out,window, nfft/2, 0);
-       check(in,out,nfft,isinverse);
+       clt_mdct_forward(&cfg,in,out,window, nfft/2, 0, 1);
+       check(in_copy,out,nfft,isinverse);
     }
     /*for (k=0;k<nfft;++k) printf("%d %d ", out[k].r, out[k].i);printf("\n");*/