shithub: opus

Download patch

ref: 44830b044069aa5870906087aae3ccf78d5749f5
parent: e8b6830f538e41a5a0db076bd183db43e3b99b3e
author: Jean-Marc Valin <[email protected]>
date: Sun Feb 24 17:36:05 EST 2008

Float FFT now does the same scaling as the fixed-point FFT

--- a/libcelt/_kiss_fft_guts.h
+++ b/libcelt/_kiss_fft_guts.h
@@ -29,6 +29,9 @@
 
 struct kiss_fft_state{
     int nfft;
+#ifndef FIXED_POINT
+    kiss_fft_scalar scale;
+#endif
     int factors[2*MAXFACTORS];
     int *bitrev;
     kiss_twiddle_cpx twiddles[1];
--- a/libcelt/kiss_fft.c
+++ b/libcelt/kiss_fft.c
@@ -617,6 +617,9 @@
     if (st) {
         int i;
         st->nfft=nfft;
+#ifndef FIXED_POINT
+        st->scale = 1./nfft;
+#endif
 #if defined(FIXED_POINT) && (!defined(DOUBLE_PRECISION) || defined(MIXED_PRECISION))
         for (i=0;i<nfft;++i) {
             celt_word32_t phase = -i;
@@ -650,7 +653,13 @@
        /* Bit-reverse the input */
        int i;
        for (i=0;i<st->nfft;i++)
+       {
           fout[i] = fin[st->bitrev[i]];
+#ifndef FIXED_POINT
+          fout[i].r *= st->scale;
+          fout[i].i *= st->scale;
+#endif
+       }
        kf_work( fout, fin, 1,in_stride, st->factors,st, 1, in_stride, 1);
     }
 }
--- a/libcelt/kiss_fftr.c
+++ b/libcelt/kiss_fftr.c
@@ -62,6 +62,9 @@
     st->tmpbuf = (kiss_fft_cpx *) (((char *) st->substate) + subsize);
     st->super_twiddles = (kiss_twiddle_cpx*)(st->tmpbuf + nfft);
     kiss_fft_alloc(nfft, st->substate, &subsize);
+#ifndef FIXED_POINT
+    st->substate->scale *= .5;
+#endif
 
 #if defined (FIXED_POINT) && !defined(DOUBLE_PRECISION)
     for (i=0;i<nfft;++i) {
--- a/libcelt/mdct.c
+++ b/libcelt/mdct.c
@@ -114,8 +114,8 @@
    /* Post-rotate and apply the scaling if the FFT doesn't to it itself */
    for(i=0;i<N4;i++)
    {
-      out[2*i]      = l->scale * (-f[2*i+1]*l->trig[i+N4] + f[2*i]  *l->trig[i]);
-      out[N2-1-2*i] = l->scale * (-f[2*i]  *l->trig[i+N4] - f[2*i+1]*l->trig[i]);
+      out[2*i]      = -f[2*i+1]*l->trig[i+N4] + f[2*i]  *l->trig[i];
+      out[N2-1-2*i] = -f[2*i]  *l->trig[i+N4] - f[2*i+1]*l->trig[i];
    }
 }
 
--- a/tests/dft-test.c
+++ b/tests/dft-test.c
@@ -25,13 +25,11 @@
             if (isinverse)
                 im = -im;
 
-#ifdef FIXED_POINT
             if (!isinverse)
             {
                re /= nfft;
                im /= nfft;
             }
-#endif            
 
             ansr += in[k].r * re - in[k].i * im;
             ansi += in[k].r * im + in[k].i * re;
--- a/tests/real-fft-test.c
+++ b/tests/real-fft-test.c
@@ -4,21 +4,11 @@
 
 #include "kiss_fftr.h"
 #include "_kiss_fft_guts.h"
-#include <sys/times.h>
-#include <time.h>
-#include <unistd.h>
 #include <stdio.h>
 #include <string.h>
 
 int ret=0;
 
-static double cputime(void)
-{
-    struct tms t;
-    times(&t);
-    return (double)(t.tms_utime + t.tms_stime)/  sysconf(_SC_CLK_TCK) ;
-}
-
 static
 kiss_fft_scalar rand_scalar(void) 
 {
@@ -80,7 +70,6 @@
 
 int main(void)
 {
-    double ts,tfft,trfft;
     int i;
     kiss_fft_cpx cin[NFFT];
     kiss_fft_cpx cout[NFFT];
@@ -109,20 +98,6 @@
     
     printf( "nfft=%d, inverse=%d, snr=%g\n",
             NFFT,0, snr_compare(cout,sout,(NFFT/2)) );
-    ts = cputime();
-    for (i=0;i<NUMFFTS;++i) {
-        kiss_fft(kiss_fft_state,cin,cout);
-    }
-    tfft = cputime() - ts;
-    
-    ts = cputime();
-    for (i=0;i<NUMFFTS;++i) {
-        kiss_fftr( kiss_fftr_state, rin, sout );
-        /* kiss_fftri(kiss_fftr_state,cout,rin); */
-    }
-    trfft = cputime() - ts;
-
-    printf("%d complex ffts took %gs, real took %gs\n",NUMFFTS,tfft,trfft);
 
     memset(cin,0,sizeof(cin));
 #if 1