shithub: opus

Download patch

ref: 42667b0a5f4fde51f211e50b5eb78a1d5c98b1d0
parent: 4508ebd58562e23980157a3e954085bf31640870
author: Jean-Marc Valin <[email protected]>
date: Mon Feb 25 04:47:25 EST 2008

real fft no longer needs an internal buffer.

--- a/libcelt/kiss_fft.c
+++ b/libcelt/kiss_fft.c
@@ -478,8 +478,8 @@
 
 static
 void compute_bitrev_table(
-         int * Fout,
-         int f,
+         int Fout,
+         int *f,
          const size_t fstride,
          int in_stride,
          int * factors,
@@ -495,7 +495,7 @@
       int j;
       for (j=0;j<p;j++)
       {
-         Fout[j] = f;
+         *f = Fout+j;
          f += fstride*in_stride;
       }
    } else {
@@ -539,18 +539,18 @@
     }    
 }
 
-static
-      void ki_work(
-                   kiss_fft_cpx * Fout,
-                   const kiss_fft_cpx * f,
-                   const size_t fstride,
-                   int in_stride,
-                   int * factors,
-                   const kiss_fft_cfg st,
-                   int N,
-                   int s2,
-                   int m2
-                  )
+
+void ki_work(
+             kiss_fft_cpx * Fout,
+             const kiss_fft_cpx * f,
+             const size_t fstride,
+             int in_stride,
+             int * factors,
+             const kiss_fft_cfg st,
+             int N,
+             int s2,
+             int m2
+            )
 {
    int i;
    kiss_fft_cpx * Fout_beg=Fout;
@@ -636,7 +636,7 @@
         
         /* bitrev */
         st->bitrev = (int*)((char*)st + memneeded - sizeof(int)*nfft);
-        compute_bitrev_table(st->bitrev, 0, 1,1, st->factors,st);
+        compute_bitrev_table(0, st->bitrev, 1,1, st->factors,st);
     }
     return st;
 }
@@ -654,10 +654,10 @@
        int i;
        for (i=0;i<st->nfft;i++)
        {
-          fout[i] = fin[st->bitrev[i]];
+          fout[st->bitrev[i]] = fin[i];
 #ifndef FIXED_POINT
-          fout[i].r *= st->scale;
-          fout[i].i *= st->scale;
+          fout[st->bitrev[i]].r *= st->scale;
+          fout[st->bitrev[i]].i *= st->scale;
 #endif
        }
        kf_work( fout, fin, 1,in_stride, st->factors,st, 1, in_stride, 1);
@@ -678,7 +678,7 @@
       /* Bit-reverse the input */
       int i;
       for (i=0;i<st->nfft;i++)
-         fout[i] = fin[st->bitrev[i]];
+         fout[st->bitrev[i]] = fin[i];
       ki_work( fout, fin, 1,in_stride, st->factors,st, 1, in_stride, 1);
    }
 }
--- a/libcelt/kiss_fft.h
+++ b/libcelt/kiss_fft.h
@@ -85,6 +85,10 @@
 
 kiss_fft_cfg kiss_fft_alloc(int nfft,void * mem,size_t * lenmem); 
 
+/** Internal function. Can be useful when you want to do the bit-reversing yourself */
+void ki_work(kiss_fft_cpx * Fout, const kiss_fft_cpx * f, const size_t fstride,
+             int in_stride,int * factors,const kiss_fft_cfg st,int N,int s2,int m2);
+
 /**
  * kiss_fft(cfg,in_out_buf)
  *
--- a/libcelt/kiss_fftr.c
+++ b/libcelt/kiss_fftr.c
@@ -26,7 +26,6 @@
 
 struct kiss_fftr_state{
     kiss_fft_cfg substate;
-    kiss_fft_cpx * tmpbuf;
     kiss_twiddle_cpx * super_twiddles;
 #ifdef USE_SIMD    
     long pad;
@@ -46,7 +45,7 @@
     nfft >>= 1;
 
     kiss_fft_alloc (nfft, NULL, &subsize);
-    memneeded = sizeof(struct kiss_fftr_state) + subsize + sizeof(kiss_fft_cpx) * ( nfft) + sizeof(kiss_twiddle_cpx)*nfft;
+    memneeded = sizeof(struct kiss_fftr_state) + subsize + sizeof(kiss_twiddle_cpx)*nfft;
 
     if (lenmem == NULL) {
         st = (kiss_fftr_cfg) KISS_FFT_MALLOC (memneeded);
@@ -59,8 +58,7 @@
         return NULL;
 
     st->substate = (kiss_fft_cfg) (st + 1); /*just beyond kiss_fftr_state struct */
-    st->tmpbuf = (kiss_fft_cpx *) (((char *) st->substate) + subsize);
-    st->super_twiddles = (kiss_twiddle_cpx*)(st->tmpbuf + nfft);
+    st->super_twiddles = (kiss_twiddle_cpx*) (((char *) st->substate) + subsize);
     kiss_fft_alloc(nfft, st->substate, &subsize);
 #ifndef FIXED_POINT
     st->substate->scale *= .5;
@@ -135,26 +133,25 @@
 
    ncfft = st->substate->nfft;
 
-   st->tmpbuf[0].r = freqdata[0] + freqdata[1];
-   st->tmpbuf[0].i = freqdata[0] - freqdata[1];
-
+   timedata[2*st->substate->bitrev[0]] = freqdata[0] + freqdata[1];
+   timedata[2*st->substate->bitrev[0]+1] = freqdata[0] - freqdata[1];
    for (k = 1; k <= ncfft / 2; ++k) {
       kiss_fft_cpx fk, fnkc, fek, fok, tmp;
+      int k1, k2;
+      k1 = st->substate->bitrev[k];
+      k2 = st->substate->bitrev[ncfft-k];
       fk.r = freqdata[2*k];
       fk.i = freqdata[2*k+1];
-      fnkc.r = freqdata[2*(ncfft - k)];
-      fnkc.i = -freqdata[2*(ncfft - k)+1];
+      fnkc.r = freqdata[2*(ncfft-k)];
+      fnkc.i = -freqdata[2*(ncfft-k)+1];
 
       C_ADD (fek, fk, fnkc);
       C_SUB (tmp, fk, fnkc);
       C_MUL (fok, tmp, st->super_twiddles[k]);
-      C_ADD (st->tmpbuf[k],     fek, fok);
-      C_SUB (st->tmpbuf[ncfft - k], fek, fok);
-#ifdef USE_SIMD        
-      st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0);
-#else
-      st->tmpbuf[ncfft - k].i *= -1;
-#endif
+      timedata[2*k1] = fek.r + fok.r;
+      timedata[2*k1+1] = fek.i + fok.i;
+      timedata[2*k2] = fek.r - fok.r;
+      timedata[2*k2+1] = fok.i - fek.i;
    }
-   kiss_ifft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata);
+   ki_work((kiss_fft_cpx*)timedata, NULL, 1,1, st->substate->factors,st->substate, 1, 1, 1);
 }