Unifying scaling of fixed-point and float FFT
authorJean-Marc Valin <jmvalin@jmvalin.ca>
Sun, 29 Dec 2013 18:34:17 +0000 (13:34 -0500)
committerJean-Marc Valin <jmvalin@jmvalin.ca>
Sun, 29 Dec 2013 18:34:17 +0000 (13:34 -0500)
celt/dump_modes/dump_modes.c
celt/kiss_fft.c
celt/kiss_fft.h
celt/mdct.c
celt/static_modes_fixed.h

index c2c5809..4759ae1 100644 (file)
@@ -172,8 +172,9 @@ void dump_modes(FILE *file, CELTMode **modes, int nb_modes)
          fprintf (file, "static const kiss_fft_state fft_state%d_%d_%d = {\n",
                mode->Fs, mdctSize, k);
          fprintf (file, "%d,\t/* nfft */\n", mode->mdct.kfft[k]->nfft);
-#ifndef FIXED_POINT
-         fprintf (file, "%0.9ff,\t/* scale */\n", mode->mdct.kfft[k]->scale);
+         fprintf (file, WORD16 ",\t/* scale */\n", mode->mdct.kfft[k]->scale);
+#ifdef FIXED_POINT
+         fprintf (file, "%d,\t/* scale_shift */\n", mode->mdct.kfft[k]->scale_shift);
 #endif
          fprintf (file, "%d,\t/* shift */\n", mode->mdct.kfft[k]->shift);
          fprintf (file, "{");
index df4c024..a2dadef 100644 (file)
@@ -405,7 +405,13 @@ kiss_fft_state *opus_fft_alloc_twiddles(int nfft,void * mem,size_t * lenmem,  co
         kiss_twiddle_cpx *twiddles;
 
         st->nfft=nfft;
-#ifndef FIXED_POINT
+#ifdef FIXED_POINT
+        st->scale_shift = celt_ilog2(st->nfft);
+        if (st->nfft == 1<<st->scale_shift)
+           st->scale = Q15ONE;
+        else
+           st->scale = (1073741824+st->nfft/2)/st->nfft>>(15-st->scale_shift);
+#else
         st->scale = 1.f/nfft;
 #endif
         if (base != NULL)
@@ -507,29 +513,22 @@ void opus_fft_impl(const kiss_fft_state *st,kiss_fft_cpx *fout)
 void opus_fft(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)
 {
    int i;
-#ifdef FIXED_POINT
-   /* FIXME: This should eventually just go in the state. */
    opus_val16 scale;
-   int scale_shift;
-   scale_shift = celt_ilog2(st->nfft);
-   if (st->nfft == 1<<scale_shift)
-      scale = Q15ONE;
-   else
-      scale = (1073741824+st->nfft/2)/st->nfft>>(15-scale_shift);
+#ifdef FIXED_POINT
+   /* Allows us to scale with MULT16_32_Q16(), which is faster than
+      MULT16_32_Q15() on ARM. */
+   int scale_shift = st->scale_shift-1;
 #endif
+   SAVE_STACK;
+   scale = st->scale;
 
    celt_assert2 (fin != fout, "In-place FFT not supported");
    /* Bit-reverse the input */
    for (i=0;i<st->nfft;i++)
    {
       kiss_fft_cpx x = fin[i];
-#ifdef FIXED_POINT
-      fout[st->bitrev[i]].r = SHR32(MULT16_32_Q15(scale, x.r), scale_shift);
-      fout[st->bitrev[i]].i = SHR32(MULT16_32_Q15(scale, x.i), scale_shift);
-#else
-      fout[st->bitrev[i]].r = st->scale*x.r;
-      fout[st->bitrev[i]].i = st->scale*x.i;
-#endif
+      fout[st->bitrev[i]].r = SHR32(MULT16_32_Q16(scale, x.r), scale_shift);
+      fout[st->bitrev[i]].i = SHR32(MULT16_32_Q16(scale, x.i), scale_shift);
    }
    opus_fft_impl(st, fout);
 }
index 67ac5f3..390b54d 100644 (file)
@@ -79,8 +79,9 @@ typedef struct {
 
 typedef struct kiss_fft_state{
     int nfft;
-#ifndef FIXED_POINT
-    kiss_fft_scalar scale;
+    opus_val16 scale;
+#ifdef FIXED_POINT
+    int scale_shift;
 #endif
     int shift;
     opus_int16 factors[2*MAXFACTORS];
index 39ebfcb..1634e8e 100644 (file)
@@ -121,22 +121,12 @@ void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar
    const kiss_twiddle_scalar *trig;
    opus_val16 scale;
 #ifdef FIXED_POINT
-   int scale_shift;
-#endif
-   SAVE_STACK;
-#ifdef FIXED_POINT
-   /* FIXME: This should eventually just go in the state. */
-   scale_shift = celt_ilog2(st->nfft);
-   if (st->nfft == 1<<scale_shift)
-      scale = Q15ONE;
-   else
-      scale = (1073741824+st->nfft/2)/st->nfft>>(15-scale_shift);
    /* Allows us to scale with MULT16_32_Q16(), which is faster than
       MULT16_32_Q15() on ARM. */
-   scale_shift--;
-#else
-   scale = st->scale;
+   int scale_shift = st->scale_shift-1;
 #endif
+   SAVE_STACK;
+   scale = st->scale;
 
    N = l->n;
    trig = l->trig;
index ae7b460..7c5750c 100644 (file)
@@ -426,6 +426,8 @@ static const opus_int16 fft_bitrev60[60] = {
 #define FFT_STATE48000_960_0
 static const kiss_fft_state fft_state48000_960_0 = {
 480,    /* nfft */
+17476, /* scale */
+8,      /* scale_shift */
 -1,     /* shift */
 {5, 96, 3, 32, 2, 16, 4, 4, 4, 1, 0, 0, 0, 0, 0, 0, }, /* factors */
 fft_bitrev480,  /* bitrev */
@@ -437,6 +439,8 @@ fft_twiddles48000_960,  /* bitrev */
 #define FFT_STATE48000_960_1
 static const kiss_fft_state fft_state48000_960_1 = {
 240,    /* nfft */
+17476, /* scale */
+7,      /* scale_shift */
 1,      /* shift */
 {5, 48, 3, 16, 4, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, },  /* factors */
 fft_bitrev240,  /* bitrev */
@@ -448,6 +452,8 @@ fft_twiddles48000_960,  /* bitrev */
 #define FFT_STATE48000_960_2
 static const kiss_fft_state fft_state48000_960_2 = {
 120,    /* nfft */
+17476, /* scale */
+6,      /* scale_shift */
 2,      /* shift */
 {5, 24, 3, 8, 2, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, },   /* factors */
 fft_bitrev120,  /* bitrev */
@@ -459,6 +465,8 @@ fft_twiddles48000_960,  /* bitrev */
 #define FFT_STATE48000_960_3
 static const kiss_fft_state fft_state48000_960_3 = {
 60,     /* nfft */
+17476, /* scale */
+5,      /* scale_shift */
 3,      /* shift */
 {5, 12, 3, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },   /* factors */
 fft_bitrev60,   /* bitrev */