shithub: opus

Download patch

ref: e1dc1e22384e6b632d7a8f9d54a0e693ebc77624
parent: dbb96ab5cc42491167e063cadc90e420c53b08be
author: Jean-Marc Valin <[email protected]>
date: Sun Dec 29 08:34:17 EST 2013

Unifying scaling of fixed-point and float FFT

--- a/celt/dump_modes/dump_modes.c
+++ b/celt/dump_modes/dump_modes.c
@@ -172,8 +172,9 @@
          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, "{");
--- a/celt/kiss_fft.c
+++ b/celt/kiss_fft.c
@@ -405,7 +405,13 @@
         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,16 +513,14 @@
 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 */
@@ -523,13 +527,8 @@
    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);
 }
--- a/celt/kiss_fft.h
+++ b/celt/kiss_fft.h
@@ -79,8 +79,9 @@
 
 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];
--- a/celt/mdct.c
+++ b/celt/mdct.c
@@ -121,22 +121,12 @@
    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;
--- a/celt/static_modes_fixed.h
+++ b/celt/static_modes_fixed.h
@@ -426,6 +426,8 @@
 #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 @@
 #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 @@
 #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 @@
 #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 */