tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

kiss_fft.c (18531B)


      1 /*Copyright (c) 2003-2004, Mark Borgerding
      2  Lots of modifications by Jean-Marc Valin
      3  Copyright (c) 2005-2007, Xiph.Org Foundation
      4  Copyright (c) 2008,      Xiph.Org Foundation, CSIRO
      5 
      6  All rights reserved.
      7 
      8  Redistribution and use in source and binary forms, with or without
      9   modification, are permitted provided that the following conditions are met:
     10 
     11    * Redistributions of source code must retain the above copyright notice,
     12       this list of conditions and the following disclaimer.
     13    * Redistributions in binary form must reproduce the above copyright notice,
     14       this list of conditions and the following disclaimer in the
     15       documentation and/or other materials provided with the distribution.
     16 
     17  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     18  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     19  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     20  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     21  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     22  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     23  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     24  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     25  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     26  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     27  POSSIBILITY OF SUCH DAMAGE.*/
     28 
     29 /* This code is originally from Mark Borgerding's KISS-FFT but has been
     30   heavily modified to better suit Opus */
     31 
     32 #ifndef SKIP_CONFIG_H
     33 #  ifdef HAVE_CONFIG_H
     34 #    include "config.h"
     35 #  endif
     36 #endif
     37 
     38 #include "_kiss_fft_guts.h"
     39 #include "arch.h"
     40 #include "os_support.h"
     41 #include "mathops.h"
     42 #include "stack_alloc.h"
     43 
     44 #ifndef M_PI
     45 #define M_PI 3.141592653
     46 #endif
     47 
     48 /* The guts header contains all the multiplication and addition macros that are defined for
     49   complex numbers.  It also declares the kf_ internal functions.
     50 */
     51 
     52 static void kf_bfly2(
     53                     kiss_fft_cpx * Fout,
     54                     int m,
     55                     int N
     56                    )
     57 {
     58   kiss_fft_cpx * Fout2;
     59   int i;
     60   (void)m;
     61 #ifdef CUSTOM_MODES
     62   if (m==1)
     63   {
     64      celt_assert(m==1);
     65      for (i=0;i<N;i++)
     66      {
     67         kiss_fft_cpx t;
     68         Fout2 = Fout + 1;
     69         t = *Fout2;
     70         C_SUB( *Fout2 ,  *Fout , t );
     71         C_ADDTO( *Fout ,  t );
     72         Fout += 2;
     73      }
     74   } else
     75 #endif
     76   {
     77      celt_coef tw;
     78      tw = QCONST32(0.7071067812f, COEF_SHIFT-1);
     79      /* We know that m==4 here because the radix-2 is just after a radix-4 */
     80      celt_assert(m==4);
     81      for (i=0;i<N;i++)
     82      {
     83         kiss_fft_cpx t;
     84         Fout2 = Fout + 4;
     85         t = Fout2[0];
     86         C_SUB( Fout2[0] ,  Fout[0] , t );
     87         C_ADDTO( Fout[0] ,  t );
     88 
     89         t.r = S_MUL(ADD32_ovflw(Fout2[1].r, Fout2[1].i), tw);
     90         t.i = S_MUL(SUB32_ovflw(Fout2[1].i, Fout2[1].r), tw);
     91         C_SUB( Fout2[1] ,  Fout[1] , t );
     92         C_ADDTO( Fout[1] ,  t );
     93 
     94         t.r = Fout2[2].i;
     95         t.i = NEG32_ovflw(Fout2[2].r);
     96         C_SUB( Fout2[2] ,  Fout[2] , t );
     97         C_ADDTO( Fout[2] ,  t );
     98 
     99         t.r = S_MUL(SUB32_ovflw(Fout2[3].i, Fout2[3].r), tw);
    100         t.i = S_MUL(NEG32_ovflw(ADD32_ovflw(Fout2[3].i, Fout2[3].r)), tw);
    101         C_SUB( Fout2[3] ,  Fout[3] , t );
    102         C_ADDTO( Fout[3] ,  t );
    103         Fout += 8;
    104      }
    105   }
    106 }
    107 
    108 static void kf_bfly4(
    109                     kiss_fft_cpx * Fout,
    110                     const size_t fstride,
    111                     const kiss_fft_state *st,
    112                     int m,
    113                     int N,
    114                     int mm
    115                    )
    116 {
    117   int i;
    118 
    119   if (m==1)
    120   {
    121      /* Degenerate case where all the twiddles are 1. */
    122      for (i=0;i<N;i++)
    123      {
    124         kiss_fft_cpx scratch0, scratch1;
    125 
    126         C_SUB( scratch0 , *Fout, Fout[2] );
    127         C_ADDTO(*Fout, Fout[2]);
    128         C_ADD( scratch1 , Fout[1] , Fout[3] );
    129         C_SUB( Fout[2], *Fout, scratch1 );
    130         C_ADDTO( *Fout , scratch1 );
    131         C_SUB( scratch1 , Fout[1] , Fout[3] );
    132 
    133         Fout[1].r = ADD32_ovflw(scratch0.r, scratch1.i);
    134         Fout[1].i = SUB32_ovflw(scratch0.i, scratch1.r);
    135         Fout[3].r = SUB32_ovflw(scratch0.r, scratch1.i);
    136         Fout[3].i = ADD32_ovflw(scratch0.i, scratch1.r);
    137         Fout+=4;
    138      }
    139   } else {
    140      int j;
    141      kiss_fft_cpx scratch[6];
    142      const kiss_twiddle_cpx *tw1,*tw2,*tw3;
    143      const int m2=2*m;
    144      const int m3=3*m;
    145      kiss_fft_cpx * Fout_beg = Fout;
    146      for (i=0;i<N;i++)
    147      {
    148         Fout = Fout_beg + i*mm;
    149         tw3 = tw2 = tw1 = st->twiddles;
    150         /* m is guaranteed to be a multiple of 4. */
    151         for (j=0;j<m;j++)
    152         {
    153            C_MUL(scratch[0],Fout[m] , *tw1 );
    154            C_MUL(scratch[1],Fout[m2] , *tw2 );
    155            C_MUL(scratch[2],Fout[m3] , *tw3 );
    156 
    157            C_SUB( scratch[5] , *Fout, scratch[1] );
    158            C_ADDTO(*Fout, scratch[1]);
    159            C_ADD( scratch[3] , scratch[0] , scratch[2] );
    160            C_SUB( scratch[4] , scratch[0] , scratch[2] );
    161            C_SUB( Fout[m2], *Fout, scratch[3] );
    162            tw1 += fstride;
    163            tw2 += fstride*2;
    164            tw3 += fstride*3;
    165            C_ADDTO( *Fout , scratch[3] );
    166 
    167            Fout[m].r = ADD32_ovflw(scratch[5].r, scratch[4].i);
    168            Fout[m].i = SUB32_ovflw(scratch[5].i, scratch[4].r);
    169            Fout[m3].r = SUB32_ovflw(scratch[5].r, scratch[4].i);
    170            Fout[m3].i = ADD32_ovflw(scratch[5].i, scratch[4].r);
    171            ++Fout;
    172         }
    173      }
    174   }
    175 }
    176 
    177 
    178 #ifndef RADIX_TWO_ONLY
    179 
    180 static void kf_bfly3(
    181                     kiss_fft_cpx * Fout,
    182                     const size_t fstride,
    183                     const kiss_fft_state *st,
    184                     int m,
    185                     int N,
    186                     int mm
    187                    )
    188 {
    189   int i;
    190   size_t k;
    191   const size_t m2 = 2*m;
    192   const kiss_twiddle_cpx *tw1,*tw2;
    193   kiss_fft_cpx scratch[5];
    194   kiss_twiddle_cpx epi3;
    195 
    196   kiss_fft_cpx * Fout_beg = Fout;
    197 #ifdef FIXED_POINT
    198   /*epi3.r = -16384;*/ /* Unused */
    199   epi3.i = -QCONST32(0.86602540f, COEF_SHIFT-1);
    200 #else
    201   epi3 = st->twiddles[fstride*m];
    202 #endif
    203   for (i=0;i<N;i++)
    204   {
    205      Fout = Fout_beg + i*mm;
    206      tw1=tw2=st->twiddles;
    207      /* For non-custom modes, m is guaranteed to be a multiple of 4. */
    208      k=m;
    209      do {
    210 
    211         C_MUL(scratch[1],Fout[m] , *tw1);
    212         C_MUL(scratch[2],Fout[m2] , *tw2);
    213 
    214         C_ADD(scratch[3],scratch[1],scratch[2]);
    215         C_SUB(scratch[0],scratch[1],scratch[2]);
    216         tw1 += fstride;
    217         tw2 += fstride*2;
    218 
    219         Fout[m].r = SUB32_ovflw(Fout->r, HALF_OF(scratch[3].r));
    220         Fout[m].i = SUB32_ovflw(Fout->i, HALF_OF(scratch[3].i));
    221 
    222         C_MULBYSCALAR( scratch[0] , epi3.i );
    223 
    224         C_ADDTO(*Fout,scratch[3]);
    225 
    226         Fout[m2].r = ADD32_ovflw(Fout[m].r, scratch[0].i);
    227         Fout[m2].i = SUB32_ovflw(Fout[m].i, scratch[0].r);
    228 
    229         Fout[m].r = SUB32_ovflw(Fout[m].r, scratch[0].i);
    230         Fout[m].i = ADD32_ovflw(Fout[m].i, scratch[0].r);
    231 
    232         ++Fout;
    233      } while(--k);
    234   }
    235 }
    236 
    237 
    238 #ifndef OVERRIDE_kf_bfly5
    239 static void kf_bfly5(
    240                     kiss_fft_cpx * Fout,
    241                     const size_t fstride,
    242                     const kiss_fft_state *st,
    243                     int m,
    244                     int N,
    245                     int mm
    246                    )
    247 {
    248   kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4;
    249   int i, u;
    250   kiss_fft_cpx scratch[13];
    251   const kiss_twiddle_cpx *tw;
    252   kiss_twiddle_cpx ya,yb;
    253   kiss_fft_cpx * Fout_beg = Fout;
    254 
    255 #ifdef FIXED_POINT
    256   ya.r = QCONST32(0.30901699f, COEF_SHIFT-1);
    257   ya.i = -QCONST32(0.95105652f, COEF_SHIFT-1);
    258   yb.r = -QCONST32(0.80901699f, COEF_SHIFT-1);
    259   yb.i = -QCONST32(0.58778525f, COEF_SHIFT-1);
    260 #else
    261   ya = st->twiddles[fstride*m];
    262   yb = st->twiddles[fstride*2*m];
    263 #endif
    264   tw=st->twiddles;
    265 
    266   for (i=0;i<N;i++)
    267   {
    268      Fout = Fout_beg + i*mm;
    269      Fout0=Fout;
    270      Fout1=Fout0+m;
    271      Fout2=Fout0+2*m;
    272      Fout3=Fout0+3*m;
    273      Fout4=Fout0+4*m;
    274 
    275      /* For non-custom modes, m is guaranteed to be a multiple of 4. */
    276      for ( u=0; u<m; ++u ) {
    277         scratch[0] = *Fout0;
    278 
    279         C_MUL(scratch[1] ,*Fout1, tw[u*fstride]);
    280         C_MUL(scratch[2] ,*Fout2, tw[2*u*fstride]);
    281         C_MUL(scratch[3] ,*Fout3, tw[3*u*fstride]);
    282         C_MUL(scratch[4] ,*Fout4, tw[4*u*fstride]);
    283 
    284         C_ADD( scratch[7],scratch[1],scratch[4]);
    285         C_SUB( scratch[10],scratch[1],scratch[4]);
    286         C_ADD( scratch[8],scratch[2],scratch[3]);
    287         C_SUB( scratch[9],scratch[2],scratch[3]);
    288 
    289         Fout0->r = ADD32_ovflw(Fout0->r, ADD32_ovflw(scratch[7].r, scratch[8].r));
    290         Fout0->i = ADD32_ovflw(Fout0->i, ADD32_ovflw(scratch[7].i, scratch[8].i));
    291 
    292         scratch[5].r = ADD32_ovflw(scratch[0].r, ADD32_ovflw(S_MUL(scratch[7].r,ya.r), S_MUL(scratch[8].r,yb.r)));
    293         scratch[5].i = ADD32_ovflw(scratch[0].i, ADD32_ovflw(S_MUL(scratch[7].i,ya.r), S_MUL(scratch[8].i,yb.r)));
    294 
    295         scratch[6].r =  ADD32_ovflw(S_MUL(scratch[10].i,ya.i), S_MUL(scratch[9].i,yb.i));
    296         scratch[6].i = NEG32_ovflw(ADD32_ovflw(S_MUL(scratch[10].r,ya.i), S_MUL(scratch[9].r,yb.i)));
    297 
    298         C_SUB(*Fout1,scratch[5],scratch[6]);
    299         C_ADD(*Fout4,scratch[5],scratch[6]);
    300 
    301         scratch[11].r = ADD32_ovflw(scratch[0].r, ADD32_ovflw(S_MUL(scratch[7].r,yb.r), S_MUL(scratch[8].r,ya.r)));
    302         scratch[11].i = ADD32_ovflw(scratch[0].i, ADD32_ovflw(S_MUL(scratch[7].i,yb.r), S_MUL(scratch[8].i,ya.r)));
    303         scratch[12].r = SUB32_ovflw(S_MUL(scratch[9].i,ya.i), S_MUL(scratch[10].i,yb.i));
    304         scratch[12].i = SUB32_ovflw(S_MUL(scratch[10].r,yb.i), S_MUL(scratch[9].r,ya.i));
    305 
    306         C_ADD(*Fout2,scratch[11],scratch[12]);
    307         C_SUB(*Fout3,scratch[11],scratch[12]);
    308 
    309         ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4;
    310      }
    311   }
    312 }
    313 #endif /* OVERRIDE_kf_bfly5 */
    314 
    315 
    316 #endif
    317 
    318 
    319 #ifdef CUSTOM_MODES
    320 
    321 static
    322 void compute_bitrev_table(
    323         int Fout,
    324         opus_int16 *f,
    325         const size_t fstride,
    326         int in_stride,
    327         opus_int16 * factors,
    328         const kiss_fft_state *st
    329            )
    330 {
    331   const int p=*factors++; /* the radix  */
    332   const int m=*factors++; /* stage's fft length/p */
    333 
    334    /*printf ("fft %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N);*/
    335   if (m==1)
    336   {
    337      int j;
    338      for (j=0;j<p;j++)
    339      {
    340         *f = Fout+j;
    341         f += fstride*in_stride;
    342      }
    343   } else {
    344      int j;
    345      for (j=0;j<p;j++)
    346      {
    347         compute_bitrev_table( Fout , f, fstride*p, in_stride, factors,st);
    348         f += fstride*in_stride;
    349         Fout += m;
    350      }
    351   }
    352 }
    353 
    354 /*  facbuf is populated by p1,m1,p2,m2, ...
    355    where
    356    p[i] * m[i] = m[i-1]
    357    m0 = n                  */
    358 static
    359 int kf_factor(int n,opus_int16 * facbuf)
    360 {
    361    int p=4;
    362    int i;
    363    int stages=0;
    364    int nbak = n;
    365 
    366    /*factor out powers of 4, powers of 2, then any remaining primes */
    367    do {
    368        while (n % p) {
    369            switch (p) {
    370                case 4: p = 2; break;
    371                case 2: p = 3; break;
    372                default: p += 2; break;
    373            }
    374            if (p>32000 || (opus_int32)p*(opus_int32)p > n)
    375                p = n;          /* no more factors, skip to end */
    376        }
    377        n /= p;
    378 #ifdef RADIX_TWO_ONLY
    379        if (p!=2 && p != 4)
    380 #else
    381        if (p>5)
    382 #endif
    383        {
    384           return 0;
    385        }
    386        facbuf[2*stages] = p;
    387        if (p==2 && stages > 1)
    388        {
    389           facbuf[2*stages] = 4;
    390           facbuf[2] = 2;
    391        }
    392        stages++;
    393    } while (n > 1);
    394    n = nbak;
    395    /* Reverse the order to get the radix 4 at the end, so we can use the
    396       fast degenerate case. It turns out that reversing the order also
    397       improves the noise behaviour. */
    398    for (i=0;i<stages/2;i++)
    399    {
    400       int tmp;
    401       tmp = facbuf[2*i];
    402       facbuf[2*i] = facbuf[2*(stages-i-1)];
    403       facbuf[2*(stages-i-1)] = tmp;
    404    }
    405    for (i=0;i<stages;i++)
    406    {
    407        n /= facbuf[2*i];
    408        facbuf[2*i+1] = n;
    409    }
    410    return 1;
    411 }
    412 
    413 static void compute_twiddles(kiss_twiddle_cpx *twiddles, int nfft)
    414 {
    415   int i;
    416 #ifdef FIXED_POINT
    417   for (i=0;i<nfft;++i) {
    418      opus_val32 phase = -i;
    419 #ifdef ENABLE_QEXT
    420      twiddles[i].r = (int)MIN32(2147483647, floor(.5+2147483648*cos((2*M_PI/nfft)*phase)));
    421      twiddles[i].i = (int)MIN32(2147483647, floor(.5+2147483648*sin((2*M_PI/nfft)*phase)));
    422 #else
    423      kf_cexp2(twiddles+i, DIV32(SHL32(phase,17),nfft));
    424 #endif
    425   }
    426 #else
    427   for (i=0;i<nfft;++i) {
    428      const double pi=3.14159265358979323846264338327;
    429      double phase = ( -2*pi /nfft ) * i;
    430      kf_cexp(twiddles+i, phase );
    431   }
    432 #endif
    433 }
    434 
    435 int opus_fft_alloc_arch_c(kiss_fft_state *st) {
    436   (void)st;
    437   return 0;
    438 }
    439 
    440 /*
    441 *
    442 * Allocates all necessary storage space for the fft and ifft.
    443 * The return value is a contiguous block of memory.  As such,
    444 * It can be freed with free().
    445 * */
    446 kiss_fft_state *opus_fft_alloc_twiddles(int nfft,void * mem,size_t * lenmem,
    447                                        const kiss_fft_state *base, int arch)
    448 {
    449    kiss_fft_state *st=NULL;
    450    size_t memneeded = sizeof(struct kiss_fft_state); /* twiddle factors*/
    451 
    452    if ( lenmem==NULL ) {
    453        st = ( kiss_fft_state*)KISS_FFT_MALLOC( memneeded );
    454    }else{
    455        if (mem != NULL && *lenmem >= memneeded)
    456            st = (kiss_fft_state*)mem;
    457        *lenmem = memneeded;
    458    }
    459    if (st) {
    460        opus_int16 *bitrev;
    461        kiss_twiddle_cpx *twiddles;
    462 
    463        st->nfft=nfft;
    464 #ifdef FIXED_POINT
    465        st->scale_shift = celt_ilog2(st->nfft);
    466 # ifdef ENABLE_QEXT
    467        if (st->nfft == 1<<st->scale_shift)
    468           st->scale = QCONST32(1.0f, 30);
    469        else
    470           st->scale = (((opus_int64)1073741824<<st->scale_shift)+st->nfft/2)/st->nfft;
    471 # else
    472        if (st->nfft == 1<<st->scale_shift)
    473           st->scale = Q15ONE;
    474        else
    475           st->scale = (1073741824+st->nfft/2)/st->nfft>>(15-st->scale_shift);
    476 # endif
    477 #else
    478        st->scale = 1.f/nfft;
    479 #endif
    480        if (base != NULL)
    481        {
    482           st->twiddles = base->twiddles;
    483           st->shift = 0;
    484           while (st->shift < 32 && nfft<<st->shift != base->nfft)
    485              st->shift++;
    486           if (st->shift>=32)
    487              goto fail;
    488        } else {
    489           st->twiddles = twiddles = (kiss_twiddle_cpx*)KISS_FFT_MALLOC(sizeof(kiss_twiddle_cpx)*nfft);
    490           compute_twiddles(twiddles, nfft);
    491           st->shift = -1;
    492        }
    493        if (!kf_factor(nfft,st->factors))
    494        {
    495           goto fail;
    496        }
    497 
    498        /* bitrev */
    499        st->bitrev = bitrev = (opus_int16*)KISS_FFT_MALLOC(sizeof(opus_int16)*nfft);
    500        if (st->bitrev==NULL)
    501            goto fail;
    502        compute_bitrev_table(0, bitrev, 1,1, st->factors,st);
    503 
    504        /* Initialize architecture specific fft parameters */
    505        if (opus_fft_alloc_arch(st, arch))
    506            goto fail;
    507    }
    508    return st;
    509 fail:
    510    opus_fft_free(st, arch);
    511    return NULL;
    512 }
    513 
    514 kiss_fft_state *opus_fft_alloc(int nfft,void * mem,size_t * lenmem, int arch)
    515 {
    516   return opus_fft_alloc_twiddles(nfft, mem, lenmem, NULL, arch);
    517 }
    518 
    519 void opus_fft_free_arch_c(kiss_fft_state *st) {
    520   (void)st;
    521 }
    522 
    523 void opus_fft_free(const kiss_fft_state *cfg, int arch)
    524 {
    525   if (cfg)
    526   {
    527      opus_fft_free_arch((kiss_fft_state *)cfg, arch);
    528      opus_free((opus_int16*)cfg->bitrev);
    529      if (cfg->shift < 0)
    530         opus_free((kiss_twiddle_cpx*)cfg->twiddles);
    531      opus_free((kiss_fft_state*)cfg);
    532   }
    533 }
    534 
    535 #endif /* CUSTOM_MODES */
    536 
    537 #ifdef FIXED_POINT
    538 #ifndef OVERRIDE_fft_downshift
    539 static void fft_downshift(kiss_fft_cpx *x, int N, int *total, int step) {
    540   int shift;
    541   shift = IMIN(step, *total);
    542   *total -= shift;
    543   if (shift == 1) {
    544      int i;
    545      for (i=0;i<N;i++) {
    546         x[i].r = SHR32(x[i].r, 1);
    547         x[i].i = SHR32(x[i].i, 1);
    548      }
    549   } else if (shift>0) {
    550      int i;
    551      for (i=0;i<N;i++) {
    552         x[i].r = PSHR32(x[i].r, shift);
    553         x[i].i = PSHR32(x[i].i, shift);
    554      }
    555   }
    556 }
    557 #endif /* OVERRIDE_fft_downshift */
    558 #else
    559 #define fft_downshift(x, N, total, step)
    560 #endif
    561 
    562 void opus_fft_impl(const kiss_fft_state *st,kiss_fft_cpx *fout ARG_FIXED(int downshift))
    563 {
    564    int m2, m;
    565    int p;
    566    int L;
    567    int fstride[MAXFACTORS];
    568    int i;
    569    int shift;
    570 
    571    /* st->shift can be -1 */
    572    shift = st->shift>0 ? st->shift : 0;
    573 
    574    fstride[0] = 1;
    575    L=0;
    576    do {
    577       p = st->factors[2*L];
    578       m = st->factors[2*L+1];
    579       fstride[L+1] = fstride[L]*p;
    580       L++;
    581    } while(m!=1);
    582    m = st->factors[2*L-1];
    583    for (i=L-1;i>=0;i--)
    584    {
    585       if (i!=0)
    586          m2 = st->factors[2*i-1];
    587       else
    588          m2 = 1;
    589       switch (st->factors[2*i])
    590       {
    591       case 2:
    592          fft_downshift(fout, st->nfft, &downshift, 1);
    593          kf_bfly2(fout, m, fstride[i]);
    594          break;
    595       case 4:
    596          fft_downshift(fout, st->nfft, &downshift, 2);
    597          kf_bfly4(fout,fstride[i]<<shift,st,m, fstride[i], m2);
    598          break;
    599 #ifndef RADIX_TWO_ONLY
    600       case 3:
    601          fft_downshift(fout, st->nfft, &downshift, 2);
    602          kf_bfly3(fout,fstride[i]<<shift,st,m, fstride[i], m2);
    603          break;
    604       case 5:
    605          fft_downshift(fout, st->nfft, &downshift, 3);
    606          kf_bfly5(fout,fstride[i]<<shift,st,m, fstride[i], m2);
    607          break;
    608 #endif
    609       }
    610       m = m2;
    611    }
    612    fft_downshift(fout, st->nfft, &downshift, downshift);
    613 }
    614 
    615 void opus_fft_c(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)
    616 {
    617   int i;
    618   celt_coef scale;
    619 #ifdef FIXED_POINT
    620   /* Allows us to scale with MULT16_32_Q16(), which is faster than
    621      MULT16_32_Q15() on ARM. */
    622   int scale_shift = st->scale_shift-1;
    623 #endif
    624   scale = st->scale;
    625 
    626   celt_assert2 (fin != fout, "In-place FFT not supported");
    627   /* Bit-reverse the input */
    628   for (i=0;i<st->nfft;i++)
    629   {
    630      kiss_fft_cpx x = fin[i];
    631      fout[st->bitrev[i]].r = S_MUL2(x.r, scale);
    632      fout[st->bitrev[i]].i = S_MUL2(x.i, scale);
    633   }
    634   opus_fft_impl(st, fout ARG_FIXED(scale_shift));
    635 }
    636 
    637 
    638 void opus_ifft_c(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)
    639 {
    640   int i;
    641   celt_assert2 (fin != fout, "In-place FFT not supported");
    642   /* Bit-reverse the input */
    643   for (i=0;i<st->nfft;i++)
    644      fout[st->bitrev[i]] = fin[i];
    645   for (i=0;i<st->nfft;i++)
    646      fout[i].i = -fout[i].i;
    647   opus_fft_impl(st, fout ARG_FIXED(0));
    648   for (i=0;i<st->nfft;i++)
    649      fout[i].i = -fout[i].i;
    650 }