Float FFT now does the same scaling as the fixed-point FFT
authorJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Sun, 24 Feb 2008 11:36:05 +0000 (22:36 +1100)
committerJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Sun, 24 Feb 2008 11:36:05 +0000 (22:36 +1100)
libcelt/_kiss_fft_guts.h
libcelt/kiss_fft.c
libcelt/kiss_fftr.c
libcelt/mdct.c
tests/dft-test.c
tests/real-fft-test.c

index 57695cc..e0bde06 100644 (file)
@@ -29,6 +29,9 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 
 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];
index d774f72..33a1c69 100644 (file)
@@ -617,6 +617,9 @@ kiss_fft_cfg kiss_fft_alloc(int nfft,void * mem,size_t * lenmem )
     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 @@ void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,
        /* 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);
     }
 }
index bb8dc98..6d829e8 100644 (file)
@@ -62,6 +62,9 @@ kiss_fftr_cfg kiss_fftr_alloc(int nfft,void * mem,size_t * lenmem)
     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) {
index af7a8d8..d019a17 100644 (file)
@@ -114,8 +114,8 @@ void mdct_forward(mdct_lookup *l, celt_sig_t *in, celt_sig_t *out)
    /* 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];
    }
 }
 
index b546d89..7f15331 100644 (file)
@@ -25,13 +25,11 @@ void check(kiss_fft_cpx  * in,kiss_fft_cpx  * out,int nfft,int isinverse)
             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;
index d645d6f..e0e5a1d 100644 (file)
@@ -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 @@ double snr_compare_scal( kiss_fft_scalar * vec1,kiss_fft_scalar * vec2, int n)
 
 int main(void)
 {
-    double ts,tfft,trfft;
     int i;
     kiss_fft_cpx cin[NFFT];
     kiss_fft_cpx cout[NFFT];
@@ -109,20 +98,6 @@ int main(void)
     
     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