LCOV - code coverage report
Current view: top level - media/libopus/celt - kiss_fft.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 168 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 7 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : /* The guts header contains all the multiplication and addition macros that are defined for
      45             :    complex numbers.  It also delares the kf_ internal functions.
      46             : */
      47             : 
      48           0 : static void kf_bfly2(
      49             :                      kiss_fft_cpx * Fout,
      50             :                      int m,
      51             :                      int N
      52             :                     )
      53             : {
      54             :    kiss_fft_cpx * Fout2;
      55             :    int i;
      56             :    (void)m;
      57             : #ifdef CUSTOM_MODES
      58             :    if (m==1)
      59             :    {
      60             :       celt_assert(m==1);
      61             :       for (i=0;i<N;i++)
      62             :       {
      63             :          kiss_fft_cpx t;
      64             :          Fout2 = Fout + 1;
      65             :          t = *Fout2;
      66             :          C_SUB( *Fout2 ,  *Fout , t );
      67             :          C_ADDTO( *Fout ,  t );
      68             :          Fout += 2;
      69             :       }
      70             :    } else
      71             : #endif
      72             :    {
      73             :       opus_val16 tw;
      74           0 :       tw = QCONST16(0.7071067812f, 15);
      75             :       /* We know that m==4 here because the radix-2 is just after a radix-4 */
      76           0 :       celt_assert(m==4);
      77           0 :       for (i=0;i<N;i++)
      78             :       {
      79             :          kiss_fft_cpx t;
      80           0 :          Fout2 = Fout + 4;
      81           0 :          t = Fout2[0];
      82           0 :          C_SUB( Fout2[0] ,  Fout[0] , t );
      83           0 :          C_ADDTO( Fout[0] ,  t );
      84             : 
      85           0 :          t.r = S_MUL(ADD32_ovflw(Fout2[1].r, Fout2[1].i), tw);
      86           0 :          t.i = S_MUL(SUB32_ovflw(Fout2[1].i, Fout2[1].r), tw);
      87           0 :          C_SUB( Fout2[1] ,  Fout[1] , t );
      88           0 :          C_ADDTO( Fout[1] ,  t );
      89             : 
      90           0 :          t.r = Fout2[2].i;
      91           0 :          t.i = -Fout2[2].r;
      92           0 :          C_SUB( Fout2[2] ,  Fout[2] , t );
      93           0 :          C_ADDTO( Fout[2] ,  t );
      94             : 
      95           0 :          t.r = S_MUL(SUB32_ovflw(Fout2[3].i, Fout2[3].r), tw);
      96           0 :          t.i = S_MUL(NEG32_ovflw(ADD32_ovflw(Fout2[3].i, Fout2[3].r)), tw);
      97           0 :          C_SUB( Fout2[3] ,  Fout[3] , t );
      98           0 :          C_ADDTO( Fout[3] ,  t );
      99           0 :          Fout += 8;
     100             :       }
     101             :    }
     102           0 : }
     103             : 
     104           0 : static void kf_bfly4(
     105             :                      kiss_fft_cpx * Fout,
     106             :                      const size_t fstride,
     107             :                      const kiss_fft_state *st,
     108             :                      int m,
     109             :                      int N,
     110             :                      int mm
     111             :                     )
     112             : {
     113             :    int i;
     114             : 
     115           0 :    if (m==1)
     116             :    {
     117             :       /* Degenerate case where all the twiddles are 1. */
     118           0 :       for (i=0;i<N;i++)
     119             :       {
     120             :          kiss_fft_cpx scratch0, scratch1;
     121             : 
     122           0 :          C_SUB( scratch0 , *Fout, Fout[2] );
     123           0 :          C_ADDTO(*Fout, Fout[2]);
     124           0 :          C_ADD( scratch1 , Fout[1] , Fout[3] );
     125           0 :          C_SUB( Fout[2], *Fout, scratch1 );
     126           0 :          C_ADDTO( *Fout , scratch1 );
     127           0 :          C_SUB( scratch1 , Fout[1] , Fout[3] );
     128             : 
     129           0 :          Fout[1].r = ADD32_ovflw(scratch0.r, scratch1.i);
     130           0 :          Fout[1].i = SUB32_ovflw(scratch0.i, scratch1.r);
     131           0 :          Fout[3].r = SUB32_ovflw(scratch0.r, scratch1.i);
     132           0 :          Fout[3].i = ADD32_ovflw(scratch0.i, scratch1.r);
     133           0 :          Fout+=4;
     134             :       }
     135             :    } else {
     136             :       int j;
     137             :       kiss_fft_cpx scratch[6];
     138             :       const kiss_twiddle_cpx *tw1,*tw2,*tw3;
     139           0 :       const int m2=2*m;
     140           0 :       const int m3=3*m;
     141           0 :       kiss_fft_cpx * Fout_beg = Fout;
     142           0 :       for (i=0;i<N;i++)
     143             :       {
     144           0 :          Fout = Fout_beg + i*mm;
     145           0 :          tw3 = tw2 = tw1 = st->twiddles;
     146             :          /* m is guaranteed to be a multiple of 4. */
     147           0 :          for (j=0;j<m;j++)
     148             :          {
     149           0 :             C_MUL(scratch[0],Fout[m] , *tw1 );
     150           0 :             C_MUL(scratch[1],Fout[m2] , *tw2 );
     151           0 :             C_MUL(scratch[2],Fout[m3] , *tw3 );
     152             : 
     153           0 :             C_SUB( scratch[5] , *Fout, scratch[1] );
     154           0 :             C_ADDTO(*Fout, scratch[1]);
     155           0 :             C_ADD( scratch[3] , scratch[0] , scratch[2] );
     156           0 :             C_SUB( scratch[4] , scratch[0] , scratch[2] );
     157           0 :             C_SUB( Fout[m2], *Fout, scratch[3] );
     158           0 :             tw1 += fstride;
     159           0 :             tw2 += fstride*2;
     160           0 :             tw3 += fstride*3;
     161           0 :             C_ADDTO( *Fout , scratch[3] );
     162             : 
     163           0 :             Fout[m].r = ADD32_ovflw(scratch[5].r, scratch[4].i);
     164           0 :             Fout[m].i = SUB32_ovflw(scratch[5].i, scratch[4].r);
     165           0 :             Fout[m3].r = SUB32_ovflw(scratch[5].r, scratch[4].i);
     166           0 :             Fout[m3].i = ADD32_ovflw(scratch[5].i, scratch[4].r);
     167           0 :             ++Fout;
     168             :          }
     169             :       }
     170             :    }
     171           0 : }
     172             : 
     173             : 
     174             : #ifndef RADIX_TWO_ONLY
     175             : 
     176           0 : static void kf_bfly3(
     177             :                      kiss_fft_cpx * Fout,
     178             :                      const size_t fstride,
     179             :                      const kiss_fft_state *st,
     180             :                      int m,
     181             :                      int N,
     182             :                      int mm
     183             :                     )
     184             : {
     185             :    int i;
     186             :    size_t k;
     187           0 :    const size_t m2 = 2*m;
     188             :    const kiss_twiddle_cpx *tw1,*tw2;
     189             :    kiss_fft_cpx scratch[5];
     190             :    kiss_twiddle_cpx epi3;
     191             : 
     192           0 :    kiss_fft_cpx * Fout_beg = Fout;
     193             : #ifdef FIXED_POINT
     194             :    /*epi3.r = -16384;*/ /* Unused */
     195             :    epi3.i = -28378;
     196             : #else
     197           0 :    epi3 = st->twiddles[fstride*m];
     198             : #endif
     199           0 :    for (i=0;i<N;i++)
     200             :    {
     201           0 :       Fout = Fout_beg + i*mm;
     202           0 :       tw1=tw2=st->twiddles;
     203             :       /* For non-custom modes, m is guaranteed to be a multiple of 4. */
     204           0 :       k=m;
     205             :       do {
     206             : 
     207           0 :          C_MUL(scratch[1],Fout[m] , *tw1);
     208           0 :          C_MUL(scratch[2],Fout[m2] , *tw2);
     209             : 
     210           0 :          C_ADD(scratch[3],scratch[1],scratch[2]);
     211           0 :          C_SUB(scratch[0],scratch[1],scratch[2]);
     212           0 :          tw1 += fstride;
     213           0 :          tw2 += fstride*2;
     214             : 
     215           0 :          Fout[m].r = SUB32_ovflw(Fout->r, HALF_OF(scratch[3].r));
     216           0 :          Fout[m].i = SUB32_ovflw(Fout->i, HALF_OF(scratch[3].i));
     217             : 
     218           0 :          C_MULBYSCALAR( scratch[0] , epi3.i );
     219             : 
     220           0 :          C_ADDTO(*Fout,scratch[3]);
     221             : 
     222           0 :          Fout[m2].r = ADD32_ovflw(Fout[m].r, scratch[0].i);
     223           0 :          Fout[m2].i = SUB32_ovflw(Fout[m].i, scratch[0].r);
     224             : 
     225           0 :          Fout[m].r = SUB32_ovflw(Fout[m].r, scratch[0].i);
     226           0 :          Fout[m].i = ADD32_ovflw(Fout[m].i, scratch[0].r);
     227             : 
     228           0 :          ++Fout;
     229           0 :       } while(--k);
     230             :    }
     231           0 : }
     232             : 
     233             : 
     234             : #ifndef OVERRIDE_kf_bfly5
     235           0 : static void kf_bfly5(
     236             :                      kiss_fft_cpx * Fout,
     237             :                      const size_t fstride,
     238             :                      const kiss_fft_state *st,
     239             :                      int m,
     240             :                      int N,
     241             :                      int mm
     242             :                     )
     243             : {
     244             :    kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4;
     245             :    int i, u;
     246             :    kiss_fft_cpx scratch[13];
     247             :    const kiss_twiddle_cpx *tw;
     248             :    kiss_twiddle_cpx ya,yb;
     249           0 :    kiss_fft_cpx * Fout_beg = Fout;
     250             : 
     251             : #ifdef FIXED_POINT
     252             :    ya.r = 10126;
     253             :    ya.i = -31164;
     254             :    yb.r = -26510;
     255             :    yb.i = -19261;
     256             : #else
     257           0 :    ya = st->twiddles[fstride*m];
     258           0 :    yb = st->twiddles[fstride*2*m];
     259             : #endif
     260           0 :    tw=st->twiddles;
     261             : 
     262           0 :    for (i=0;i<N;i++)
     263             :    {
     264           0 :       Fout = Fout_beg + i*mm;
     265           0 :       Fout0=Fout;
     266           0 :       Fout1=Fout0+m;
     267           0 :       Fout2=Fout0+2*m;
     268           0 :       Fout3=Fout0+3*m;
     269           0 :       Fout4=Fout0+4*m;
     270             : 
     271             :       /* For non-custom modes, m is guaranteed to be a multiple of 4. */
     272           0 :       for ( u=0; u<m; ++u ) {
     273           0 :          scratch[0] = *Fout0;
     274             : 
     275           0 :          C_MUL(scratch[1] ,*Fout1, tw[u*fstride]);
     276           0 :          C_MUL(scratch[2] ,*Fout2, tw[2*u*fstride]);
     277           0 :          C_MUL(scratch[3] ,*Fout3, tw[3*u*fstride]);
     278           0 :          C_MUL(scratch[4] ,*Fout4, tw[4*u*fstride]);
     279             : 
     280           0 :          C_ADD( scratch[7],scratch[1],scratch[4]);
     281           0 :          C_SUB( scratch[10],scratch[1],scratch[4]);
     282           0 :          C_ADD( scratch[8],scratch[2],scratch[3]);
     283           0 :          C_SUB( scratch[9],scratch[2],scratch[3]);
     284             : 
     285           0 :          Fout0->r = ADD32_ovflw(Fout0->r, ADD32_ovflw(scratch[7].r, scratch[8].r));
     286           0 :          Fout0->i = ADD32_ovflw(Fout0->i, ADD32_ovflw(scratch[7].i, scratch[8].i));
     287             : 
     288           0 :          scratch[5].r = ADD32_ovflw(scratch[0].r, ADD32_ovflw(S_MUL(scratch[7].r,ya.r), S_MUL(scratch[8].r,yb.r)));
     289           0 :          scratch[5].i = ADD32_ovflw(scratch[0].i, ADD32_ovflw(S_MUL(scratch[7].i,ya.r), S_MUL(scratch[8].i,yb.r)));
     290             : 
     291           0 :          scratch[6].r =  ADD32_ovflw(S_MUL(scratch[10].i,ya.i), S_MUL(scratch[9].i,yb.i));
     292           0 :          scratch[6].i = NEG32_ovflw(ADD32_ovflw(S_MUL(scratch[10].r,ya.i), S_MUL(scratch[9].r,yb.i)));
     293             : 
     294           0 :          C_SUB(*Fout1,scratch[5],scratch[6]);
     295           0 :          C_ADD(*Fout4,scratch[5],scratch[6]);
     296             : 
     297           0 :          scratch[11].r = ADD32_ovflw(scratch[0].r, ADD32_ovflw(S_MUL(scratch[7].r,yb.r), S_MUL(scratch[8].r,ya.r)));
     298           0 :          scratch[11].i = ADD32_ovflw(scratch[0].i, ADD32_ovflw(S_MUL(scratch[7].i,yb.r), S_MUL(scratch[8].i,ya.r)));
     299           0 :          scratch[12].r = SUB32_ovflw(S_MUL(scratch[9].i,ya.i), S_MUL(scratch[10].i,yb.i));
     300           0 :          scratch[12].i = SUB32_ovflw(S_MUL(scratch[10].r,yb.i), S_MUL(scratch[9].r,ya.i));
     301             : 
     302           0 :          C_ADD(*Fout2,scratch[11],scratch[12]);
     303           0 :          C_SUB(*Fout3,scratch[11],scratch[12]);
     304             : 
     305           0 :          ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4;
     306             :       }
     307             :    }
     308           0 : }
     309             : #endif /* OVERRIDE_kf_bfly5 */
     310             : 
     311             : 
     312             : #endif
     313             : 
     314             : 
     315             : #ifdef CUSTOM_MODES
     316             : 
     317             : static
     318             : void compute_bitrev_table(
     319             :          int Fout,
     320             :          opus_int16 *f,
     321             :          const size_t fstride,
     322             :          int in_stride,
     323             :          opus_int16 * factors,
     324             :          const kiss_fft_state *st
     325             :             )
     326             : {
     327             :    const int p=*factors++; /* the radix  */
     328             :    const int m=*factors++; /* stage's fft length/p */
     329             : 
     330             :     /*printf ("fft %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N);*/
     331             :    if (m==1)
     332             :    {
     333             :       int j;
     334             :       for (j=0;j<p;j++)
     335             :       {
     336             :          *f = Fout+j;
     337             :          f += fstride*in_stride;
     338             :       }
     339             :    } else {
     340             :       int j;
     341             :       for (j=0;j<p;j++)
     342             :       {
     343             :          compute_bitrev_table( Fout , f, fstride*p, in_stride, factors,st);
     344             :          f += fstride*in_stride;
     345             :          Fout += m;
     346             :       }
     347             :    }
     348             : }
     349             : 
     350             : /*  facbuf is populated by p1,m1,p2,m2, ...
     351             :     where
     352             :     p[i] * m[i] = m[i-1]
     353             :     m0 = n                  */
     354             : static
     355             : int kf_factor(int n,opus_int16 * facbuf)
     356             : {
     357             :     int p=4;
     358             :     int i;
     359             :     int stages=0;
     360             :     int nbak = n;
     361             : 
     362             :     /*factor out powers of 4, powers of 2, then any remaining primes */
     363             :     do {
     364             :         while (n % p) {
     365             :             switch (p) {
     366             :                 case 4: p = 2; break;
     367             :                 case 2: p = 3; break;
     368             :                 default: p += 2; break;
     369             :             }
     370             :             if (p>32000 || (opus_int32)p*(opus_int32)p > n)
     371             :                 p = n;          /* no more factors, skip to end */
     372             :         }
     373             :         n /= p;
     374             : #ifdef RADIX_TWO_ONLY
     375             :         if (p!=2 && p != 4)
     376             : #else
     377             :         if (p>5)
     378             : #endif
     379             :         {
     380             :            return 0;
     381             :         }
     382             :         facbuf[2*stages] = p;
     383             :         if (p==2 && stages > 1)
     384             :         {
     385             :            facbuf[2*stages] = 4;
     386             :            facbuf[2] = 2;
     387             :         }
     388             :         stages++;
     389             :     } while (n > 1);
     390             :     n = nbak;
     391             :     /* Reverse the order to get the radix 4 at the end, so we can use the
     392             :        fast degenerate case. It turns out that reversing the order also
     393             :        improves the noise behaviour. */
     394             :     for (i=0;i<stages/2;i++)
     395             :     {
     396             :        int tmp;
     397             :        tmp = facbuf[2*i];
     398             :        facbuf[2*i] = facbuf[2*(stages-i-1)];
     399             :        facbuf[2*(stages-i-1)] = tmp;
     400             :     }
     401             :     for (i=0;i<stages;i++)
     402             :     {
     403             :         n /= facbuf[2*i];
     404             :         facbuf[2*i+1] = n;
     405             :     }
     406             :     return 1;
     407             : }
     408             : 
     409             : static void compute_twiddles(kiss_twiddle_cpx *twiddles, int nfft)
     410             : {
     411             :    int i;
     412             : #ifdef FIXED_POINT
     413             :    for (i=0;i<nfft;++i) {
     414             :       opus_val32 phase = -i;
     415             :       kf_cexp2(twiddles+i, DIV32(SHL32(phase,17),nfft));
     416             :    }
     417             : #else
     418             :    for (i=0;i<nfft;++i) {
     419             :       const double pi=3.14159265358979323846264338327;
     420             :       double phase = ( -2*pi /nfft ) * i;
     421             :       kf_cexp(twiddles+i, phase );
     422             :    }
     423             : #endif
     424             : }
     425             : 
     426             : int opus_fft_alloc_arch_c(kiss_fft_state *st) {
     427             :    (void)st;
     428             :    return 0;
     429             : }
     430             : 
     431             : /*
     432             :  *
     433             :  * Allocates all necessary storage space for the fft and ifft.
     434             :  * The return value is a contiguous block of memory.  As such,
     435             :  * It can be freed with free().
     436             :  * */
     437             : kiss_fft_state *opus_fft_alloc_twiddles(int nfft,void * mem,size_t * lenmem,
     438             :                                         const kiss_fft_state *base, int arch)
     439             : {
     440             :     kiss_fft_state *st=NULL;
     441             :     size_t memneeded = sizeof(struct kiss_fft_state); /* twiddle factors*/
     442             : 
     443             :     if ( lenmem==NULL ) {
     444             :         st = ( kiss_fft_state*)KISS_FFT_MALLOC( memneeded );
     445             :     }else{
     446             :         if (mem != NULL && *lenmem >= memneeded)
     447             :             st = (kiss_fft_state*)mem;
     448             :         *lenmem = memneeded;
     449             :     }
     450             :     if (st) {
     451             :         opus_int16 *bitrev;
     452             :         kiss_twiddle_cpx *twiddles;
     453             : 
     454             :         st->nfft=nfft;
     455             : #ifdef FIXED_POINT
     456             :         st->scale_shift = celt_ilog2(st->nfft);
     457             :         if (st->nfft == 1<<st->scale_shift)
     458             :            st->scale = Q15ONE;
     459             :         else
     460             :            st->scale = (1073741824+st->nfft/2)/st->nfft>>(15-st->scale_shift);
     461             : #else
     462             :         st->scale = 1.f/nfft;
     463             : #endif
     464             :         if (base != NULL)
     465             :         {
     466             :            st->twiddles = base->twiddles;
     467             :            st->shift = 0;
     468             :            while (st->shift < 32 && nfft<<st->shift != base->nfft)
     469             :               st->shift++;
     470             :            if (st->shift>=32)
     471             :               goto fail;
     472             :         } else {
     473             :            st->twiddles = twiddles = (kiss_twiddle_cpx*)KISS_FFT_MALLOC(sizeof(kiss_twiddle_cpx)*nfft);
     474             :            compute_twiddles(twiddles, nfft);
     475             :            st->shift = -1;
     476             :         }
     477             :         if (!kf_factor(nfft,st->factors))
     478             :         {
     479             :            goto fail;
     480             :         }
     481             : 
     482             :         /* bitrev */
     483             :         st->bitrev = bitrev = (opus_int16*)KISS_FFT_MALLOC(sizeof(opus_int16)*nfft);
     484             :         if (st->bitrev==NULL)
     485             :             goto fail;
     486             :         compute_bitrev_table(0, bitrev, 1,1, st->factors,st);
     487             : 
     488             :         /* Initialize architecture specific fft parameters */
     489             :         if (opus_fft_alloc_arch(st, arch))
     490             :             goto fail;
     491             :     }
     492             :     return st;
     493             : fail:
     494             :     opus_fft_free(st, arch);
     495             :     return NULL;
     496             : }
     497             : 
     498             : kiss_fft_state *opus_fft_alloc(int nfft,void * mem,size_t * lenmem, int arch)
     499             : {
     500             :    return opus_fft_alloc_twiddles(nfft, mem, lenmem, NULL, arch);
     501             : }
     502             : 
     503             : void opus_fft_free_arch_c(kiss_fft_state *st) {
     504             :    (void)st;
     505             : }
     506             : 
     507             : void opus_fft_free(const kiss_fft_state *cfg, int arch)
     508             : {
     509             :    if (cfg)
     510             :    {
     511             :       opus_fft_free_arch((kiss_fft_state *)cfg, arch);
     512             :       opus_free((opus_int16*)cfg->bitrev);
     513             :       if (cfg->shift < 0)
     514             :          opus_free((kiss_twiddle_cpx*)cfg->twiddles);
     515             :       opus_free((kiss_fft_state*)cfg);
     516             :    }
     517             : }
     518             : 
     519             : #endif /* CUSTOM_MODES */
     520             : 
     521           0 : void opus_fft_impl(const kiss_fft_state *st,kiss_fft_cpx *fout)
     522             : {
     523             :     int m2, m;
     524             :     int p;
     525             :     int L;
     526             :     int fstride[MAXFACTORS];
     527             :     int i;
     528             :     int shift;
     529             : 
     530             :     /* st->shift can be -1 */
     531           0 :     shift = st->shift>0 ? st->shift : 0;
     532             : 
     533           0 :     fstride[0] = 1;
     534           0 :     L=0;
     535             :     do {
     536           0 :        p = st->factors[2*L];
     537           0 :        m = st->factors[2*L+1];
     538           0 :        fstride[L+1] = fstride[L]*p;
     539           0 :        L++;
     540           0 :     } while(m!=1);
     541           0 :     m = st->factors[2*L-1];
     542           0 :     for (i=L-1;i>=0;i--)
     543             :     {
     544           0 :        if (i!=0)
     545           0 :           m2 = st->factors[2*i-1];
     546             :        else
     547           0 :           m2 = 1;
     548           0 :        switch (st->factors[2*i])
     549             :        {
     550             :        case 2:
     551           0 :           kf_bfly2(fout, m, fstride[i]);
     552           0 :           break;
     553             :        case 4:
     554           0 :           kf_bfly4(fout,fstride[i]<<shift,st,m, fstride[i], m2);
     555           0 :           break;
     556             :  #ifndef RADIX_TWO_ONLY
     557             :        case 3:
     558           0 :           kf_bfly3(fout,fstride[i]<<shift,st,m, fstride[i], m2);
     559           0 :           break;
     560             :        case 5:
     561           0 :           kf_bfly5(fout,fstride[i]<<shift,st,m, fstride[i], m2);
     562           0 :           break;
     563             :  #endif
     564             :        }
     565           0 :        m = m2;
     566             :     }
     567           0 : }
     568             : 
     569           0 : void opus_fft_c(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)
     570             : {
     571             :    int i;
     572             :    opus_val16 scale;
     573             : #ifdef FIXED_POINT
     574             :    /* Allows us to scale with MULT16_32_Q16(), which is faster than
     575             :       MULT16_32_Q15() on ARM. */
     576             :    int scale_shift = st->scale_shift-1;
     577             : #endif
     578           0 :    scale = st->scale;
     579             : 
     580           0 :    celt_assert2 (fin != fout, "In-place FFT not supported");
     581             :    /* Bit-reverse the input */
     582           0 :    for (i=0;i<st->nfft;i++)
     583             :    {
     584           0 :       kiss_fft_cpx x = fin[i];
     585           0 :       fout[st->bitrev[i]].r = SHR32(MULT16_32_Q16(scale, x.r), scale_shift);
     586           0 :       fout[st->bitrev[i]].i = SHR32(MULT16_32_Q16(scale, x.i), scale_shift);
     587             :    }
     588           0 :    opus_fft_impl(st, fout);
     589           0 : }
     590             : 
     591             : 
     592           0 : void opus_ifft_c(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)
     593             : {
     594             :    int i;
     595           0 :    celt_assert2 (fin != fout, "In-place FFT not supported");
     596             :    /* Bit-reverse the input */
     597           0 :    for (i=0;i<st->nfft;i++)
     598           0 :       fout[st->bitrev[i]] = fin[i];
     599           0 :    for (i=0;i<st->nfft;i++)
     600           0 :       fout[i].i = -fout[i].i;
     601           0 :    opus_fft_impl(st, fout);
     602           0 :    for (i=0;i<st->nfft;i++)
     603           0 :       fout[i].i = -fout[i].i;
     604           0 : }

Generated by: LCOV version 1.13