1885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/*Copyright (c) 2003-2004, Mark Borgerding
2885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  Lots of modifications by Jean-Marc Valin
3885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  Copyright (c) 2005-2007, Xiph.Org Foundation
4885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  Copyright (c) 2008,      Xiph.Org Foundation, CSIRO
5885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
6885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  All rights reserved.
7885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
8885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  Redistribution and use in source and binary forms, with or without
9885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   modification, are permitted provided that the following conditions are met:
10885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
11885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    * Redistributions of source code must retain the above copyright notice,
12885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       this list of conditions and the following disclaimer.
13885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    * Redistributions in binary form must reproduce the above copyright notice,
14885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       this list of conditions and the following disclaimer in the
15885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       documentation and/or other materials provided with the distribution.
16885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
17885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  POSSIBILITY OF SUCH DAMAGE.*/
28885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
29885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* This code is originally from Mark Borgerding's KISS-FFT but has been
30885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   heavily modified to better suit Opus */
31885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
32885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifndef SKIP_CONFIG_H
33885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#  ifdef HAVE_CONFIG_H
34885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#    include "config.h"
35885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#  endif
36885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
37885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
38885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "_kiss_fft_guts.h"
39885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "arch.h"
40885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "os_support.h"
41885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "mathops.h"
42885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "stack_alloc.h"
43885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
44885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* The guts header contains all the multiplication and addition macros that are defined for
45885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   complex numbers.  It also delares the kf_ internal functions.
46885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org*/
47885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
48885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void kf_bfly2(
49885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     kiss_fft_cpx * Fout,
50885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     const size_t fstride,
51885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     const kiss_fft_state *st,
52885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     int m,
53885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     int N,
54885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     int mm
55885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    )
56885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
57885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   kiss_fft_cpx * Fout2;
58885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   const kiss_twiddle_cpx * tw1;
59885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int i,j;
60885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   kiss_fft_cpx * Fout_beg = Fout;
61885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=0;i<N;i++)
62885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
63885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      Fout = Fout_beg + i*mm;
64885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      Fout2 = Fout + m;
65885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      tw1 = st->twiddles;
66885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      for(j=0;j<m;j++)
67885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
68885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         kiss_fft_cpx t;
69885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Fout->r = SHR32(Fout->r, 1);Fout->i = SHR32(Fout->i, 1);
70885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Fout2->r = SHR32(Fout2->r, 1);Fout2->i = SHR32(Fout2->i, 1);
71885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_MUL (t,  *Fout2 , *tw1);
72885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         tw1 += fstride;
73885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_SUB( *Fout2 ,  *Fout , t );
74885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_ADDTO( *Fout ,  t );
75885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         ++Fout2;
76885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         ++Fout;
77885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
78885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
79885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
80885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
81885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void ki_bfly2(
82885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     kiss_fft_cpx * Fout,
83885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     const size_t fstride,
84885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     const kiss_fft_state *st,
85885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     int m,
86885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     int N,
87885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     int mm
88885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    )
89885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
90885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   kiss_fft_cpx * Fout2;
91885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   const kiss_twiddle_cpx * tw1;
92885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   kiss_fft_cpx t;
93885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int i,j;
94885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   kiss_fft_cpx * Fout_beg = Fout;
95885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=0;i<N;i++)
96885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
97885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      Fout = Fout_beg + i*mm;
98885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      Fout2 = Fout + m;
99885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      tw1 = st->twiddles;
100885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      for(j=0;j<m;j++)
101885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
102885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_MULC (t,  *Fout2 , *tw1);
103885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         tw1 += fstride;
104885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_SUB( *Fout2 ,  *Fout , t );
105885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_ADDTO( *Fout ,  t );
106885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         ++Fout2;
107885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         ++Fout;
108885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
109885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
110885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
111885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
112885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void kf_bfly4(
113885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     kiss_fft_cpx * Fout,
114885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     const size_t fstride,
115885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     const kiss_fft_state *st,
116885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     int m,
117885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     int N,
118885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     int mm
119885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    )
120885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
121885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   const kiss_twiddle_cpx *tw1,*tw2,*tw3;
122885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   kiss_fft_cpx scratch[6];
123885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   const size_t m2=2*m;
124885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   const size_t m3=3*m;
125885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int i, j;
126885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
127885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   kiss_fft_cpx * Fout_beg = Fout;
128885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=0;i<N;i++)
129885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
130885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      Fout = Fout_beg + i*mm;
131885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      tw3 = tw2 = tw1 = st->twiddles;
132885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      for (j=0;j<m;j++)
133885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
134885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_MUL4(scratch[0],Fout[m] , *tw1 );
135885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_MUL4(scratch[1],Fout[m2] , *tw2 );
136885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_MUL4(scratch[2],Fout[m3] , *tw3 );
137885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
138885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Fout->r = PSHR32(Fout->r, 2);
139885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Fout->i = PSHR32(Fout->i, 2);
140885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_SUB( scratch[5] , *Fout, scratch[1] );
141885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_ADDTO(*Fout, scratch[1]);
142885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_ADD( scratch[3] , scratch[0] , scratch[2] );
143885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_SUB( scratch[4] , scratch[0] , scratch[2] );
144885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_SUB( Fout[m2], *Fout, scratch[3] );
145885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         tw1 += fstride;
146885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         tw2 += fstride*2;
147885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         tw3 += fstride*3;
148885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_ADDTO( *Fout , scratch[3] );
149885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
150885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Fout[m].r = scratch[5].r + scratch[4].i;
151885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Fout[m].i = scratch[5].i - scratch[4].r;
152885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Fout[m3].r = scratch[5].r - scratch[4].i;
153885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Fout[m3].i = scratch[5].i + scratch[4].r;
154885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         ++Fout;
155885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
156885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
157885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
158885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
159885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void ki_bfly4(
160885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     kiss_fft_cpx * Fout,
161885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     const size_t fstride,
162885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     const kiss_fft_state *st,
163885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     int m,
164885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     int N,
165885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     int mm
166885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    )
167885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
168885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   const kiss_twiddle_cpx *tw1,*tw2,*tw3;
169885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   kiss_fft_cpx scratch[6];
170885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   const size_t m2=2*m;
171885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   const size_t m3=3*m;
172885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int i, j;
173885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
174885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   kiss_fft_cpx * Fout_beg = Fout;
175885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=0;i<N;i++)
176885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
177885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      Fout = Fout_beg + i*mm;
178885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      tw3 = tw2 = tw1 = st->twiddles;
179885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      for (j=0;j<m;j++)
180885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
181885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_MULC(scratch[0],Fout[m] , *tw1 );
182885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_MULC(scratch[1],Fout[m2] , *tw2 );
183885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_MULC(scratch[2],Fout[m3] , *tw3 );
184885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
185885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_SUB( scratch[5] , *Fout, scratch[1] );
186885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_ADDTO(*Fout, scratch[1]);
187885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_ADD( scratch[3] , scratch[0] , scratch[2] );
188885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_SUB( scratch[4] , scratch[0] , scratch[2] );
189885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_SUB( Fout[m2], *Fout, scratch[3] );
190885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         tw1 += fstride;
191885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         tw2 += fstride*2;
192885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         tw3 += fstride*3;
193885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_ADDTO( *Fout , scratch[3] );
194885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
195885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Fout[m].r = scratch[5].r - scratch[4].i;
196885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Fout[m].i = scratch[5].i + scratch[4].r;
197885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Fout[m3].r = scratch[5].r + scratch[4].i;
198885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Fout[m3].i = scratch[5].i - scratch[4].r;
199885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         ++Fout;
200885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
201885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
202885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
203885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
204885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifndef RADIX_TWO_ONLY
205885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
206885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void kf_bfly3(
207885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     kiss_fft_cpx * Fout,
208885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     const size_t fstride,
209885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     const kiss_fft_state *st,
210885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     int m,
211885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     int N,
212885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     int mm
213885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    )
214885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
215885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int i;
216885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   size_t k;
217885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   const size_t m2 = 2*m;
218885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   const kiss_twiddle_cpx *tw1,*tw2;
219885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   kiss_fft_cpx scratch[5];
220885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   kiss_twiddle_cpx epi3;
221885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
222885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   kiss_fft_cpx * Fout_beg = Fout;
223885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   epi3 = st->twiddles[fstride*m];
224885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=0;i<N;i++)
225885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
226885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      Fout = Fout_beg + i*mm;
227885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      tw1=tw2=st->twiddles;
228885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      k=m;
229885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      do {
230885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3);
231885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
232885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_MUL(scratch[1],Fout[m] , *tw1);
233885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_MUL(scratch[2],Fout[m2] , *tw2);
234885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
235885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_ADD(scratch[3],scratch[1],scratch[2]);
236885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_SUB(scratch[0],scratch[1],scratch[2]);
237885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         tw1 += fstride;
238885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         tw2 += fstride*2;
239885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
240885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Fout[m].r = Fout->r - HALF_OF(scratch[3].r);
241885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Fout[m].i = Fout->i - HALF_OF(scratch[3].i);
242885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
243885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_MULBYSCALAR( scratch[0] , epi3.i );
244885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
245885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_ADDTO(*Fout,scratch[3]);
246885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
247885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Fout[m2].r = Fout[m].r + scratch[0].i;
248885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Fout[m2].i = Fout[m].i - scratch[0].r;
249885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
250885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Fout[m].r -= scratch[0].i;
251885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Fout[m].i += scratch[0].r;
252885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
253885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         ++Fout;
254885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      } while(--k);
255885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
256885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
257885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
258885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void ki_bfly3(
259885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     kiss_fft_cpx * Fout,
260885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     const size_t fstride,
261885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     const kiss_fft_state *st,
262885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     int m,
263885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     int N,
264885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     int mm
265885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    )
266885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
267885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int i, k;
268885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   const size_t m2 = 2*m;
269885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   const kiss_twiddle_cpx *tw1,*tw2;
270885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   kiss_fft_cpx scratch[5];
271885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   kiss_twiddle_cpx epi3;
272885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
273885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   kiss_fft_cpx * Fout_beg = Fout;
274885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   epi3 = st->twiddles[fstride*m];
275885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=0;i<N;i++)
276885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
277885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      Fout = Fout_beg + i*mm;
278885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      tw1=tw2=st->twiddles;
279885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      k=m;
280885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      do{
281885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
282885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_MULC(scratch[1],Fout[m] , *tw1);
283885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_MULC(scratch[2],Fout[m2] , *tw2);
284885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
285885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_ADD(scratch[3],scratch[1],scratch[2]);
286885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_SUB(scratch[0],scratch[1],scratch[2]);
287885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         tw1 += fstride;
288885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         tw2 += fstride*2;
289885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
290885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Fout[m].r = Fout->r - HALF_OF(scratch[3].r);
291885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Fout[m].i = Fout->i - HALF_OF(scratch[3].i);
292885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
293885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_MULBYSCALAR( scratch[0] , -epi3.i );
294885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
295885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_ADDTO(*Fout,scratch[3]);
296885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
297885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Fout[m2].r = Fout[m].r + scratch[0].i;
298885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Fout[m2].i = Fout[m].i - scratch[0].r;
299885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
300885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Fout[m].r -= scratch[0].i;
301885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Fout[m].i += scratch[0].r;
302885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
303885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         ++Fout;
304885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }while(--k);
305885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
306885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
307885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
308885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void kf_bfly5(
309885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     kiss_fft_cpx * Fout,
310885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     const size_t fstride,
311885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     const kiss_fft_state *st,
312885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     int m,
313885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     int N,
314885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     int mm
315885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    )
316885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
317885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4;
318885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int i, u;
319885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   kiss_fft_cpx scratch[13];
320885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   const kiss_twiddle_cpx * twiddles = st->twiddles;
321885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   const kiss_twiddle_cpx *tw;
322885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   kiss_twiddle_cpx ya,yb;
323885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   kiss_fft_cpx * Fout_beg = Fout;
324885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
325885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   ya = twiddles[fstride*m];
326885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   yb = twiddles[fstride*2*m];
327885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   tw=st->twiddles;
328885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
329885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=0;i<N;i++)
330885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
331885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      Fout = Fout_beg + i*mm;
332885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      Fout0=Fout;
333885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      Fout1=Fout0+m;
334885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      Fout2=Fout0+2*m;
335885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      Fout3=Fout0+3*m;
336885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      Fout4=Fout0+4*m;
337885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
338885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      for ( u=0; u<m; ++u ) {
339885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_FIXDIV( *Fout0,5); C_FIXDIV( *Fout1,5); C_FIXDIV( *Fout2,5); C_FIXDIV( *Fout3,5); C_FIXDIV( *Fout4,5);
340885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         scratch[0] = *Fout0;
341885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
342885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_MUL(scratch[1] ,*Fout1, tw[u*fstride]);
343885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_MUL(scratch[2] ,*Fout2, tw[2*u*fstride]);
344885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_MUL(scratch[3] ,*Fout3, tw[3*u*fstride]);
345885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_MUL(scratch[4] ,*Fout4, tw[4*u*fstride]);
346885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
347885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_ADD( scratch[7],scratch[1],scratch[4]);
348885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_SUB( scratch[10],scratch[1],scratch[4]);
349885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_ADD( scratch[8],scratch[2],scratch[3]);
350885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_SUB( scratch[9],scratch[2],scratch[3]);
351885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
352885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Fout0->r += scratch[7].r + scratch[8].r;
353885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Fout0->i += scratch[7].i + scratch[8].i;
354885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
355885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r);
356885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r);
357885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
358885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         scratch[6].r =  S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i);
359885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i);
360885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
361885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_SUB(*Fout1,scratch[5],scratch[6]);
362885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_ADD(*Fout4,scratch[5],scratch[6]);
363885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
364885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r);
365885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r);
366885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i);
367885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i);
368885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
369885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_ADD(*Fout2,scratch[11],scratch[12]);
370885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_SUB(*Fout3,scratch[11],scratch[12]);
371885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
372885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4;
373885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
374885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
375885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
376885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
377885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void ki_bfly5(
378885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     kiss_fft_cpx * Fout,
379885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     const size_t fstride,
380885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     const kiss_fft_state *st,
381885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     int m,
382885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     int N,
383885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     int mm
384885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                    )
385885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
386885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4;
387885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int i, u;
388885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   kiss_fft_cpx scratch[13];
389885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   const kiss_twiddle_cpx * twiddles = st->twiddles;
390885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   const kiss_twiddle_cpx *tw;
391885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   kiss_twiddle_cpx ya,yb;
392885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   kiss_fft_cpx * Fout_beg = Fout;
393885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
394885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   ya = twiddles[fstride*m];
395885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   yb = twiddles[fstride*2*m];
396885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   tw=st->twiddles;
397885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
398885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=0;i<N;i++)
399885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
400885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      Fout = Fout_beg + i*mm;
401885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      Fout0=Fout;
402885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      Fout1=Fout0+m;
403885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      Fout2=Fout0+2*m;
404885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      Fout3=Fout0+3*m;
405885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      Fout4=Fout0+4*m;
406885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
407885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      for ( u=0; u<m; ++u ) {
408885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         scratch[0] = *Fout0;
409885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
410885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_MULC(scratch[1] ,*Fout1, tw[u*fstride]);
411885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_MULC(scratch[2] ,*Fout2, tw[2*u*fstride]);
412885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_MULC(scratch[3] ,*Fout3, tw[3*u*fstride]);
413885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_MULC(scratch[4] ,*Fout4, tw[4*u*fstride]);
414885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
415885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_ADD( scratch[7],scratch[1],scratch[4]);
416885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_SUB( scratch[10],scratch[1],scratch[4]);
417885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_ADD( scratch[8],scratch[2],scratch[3]);
418885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_SUB( scratch[9],scratch[2],scratch[3]);
419885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
420885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Fout0->r += scratch[7].r + scratch[8].r;
421885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Fout0->i += scratch[7].i + scratch[8].i;
422885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
423885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r);
424885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r);
425885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
426885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         scratch[6].r = -S_MUL(scratch[10].i,ya.i) - S_MUL(scratch[9].i,yb.i);
427885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         scratch[6].i =  S_MUL(scratch[10].r,ya.i) + S_MUL(scratch[9].r,yb.i);
428885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
429885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_SUB(*Fout1,scratch[5],scratch[6]);
430885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_ADD(*Fout4,scratch[5],scratch[6]);
431885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
432885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r);
433885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r);
434885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         scratch[12].r =  S_MUL(scratch[10].i,yb.i) - S_MUL(scratch[9].i,ya.i);
435885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         scratch[12].i = -S_MUL(scratch[10].r,yb.i) + S_MUL(scratch[9].r,ya.i);
436885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
437885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_ADD(*Fout2,scratch[11],scratch[12]);
438885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         C_SUB(*Fout3,scratch[11],scratch[12]);
439885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
440885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4;
441885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
442885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
443885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
444885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
445885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
446885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
447885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
448885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef CUSTOM_MODES
449885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
450885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic
451885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid compute_bitrev_table(
452885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         int Fout,
453885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         opus_int16 *f,
454885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         const size_t fstride,
455885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         int in_stride,
456885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         opus_int16 * factors,
457885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         const kiss_fft_state *st
458885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            )
459885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
460885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   const int p=*factors++; /* the radix  */
461885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   const int m=*factors++; /* stage's fft length/p */
462885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
463885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    /*printf ("fft %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N);*/
464885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (m==1)
465885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
466885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int j;
467885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      for (j=0;j<p;j++)
468885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
469885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         *f = Fout+j;
470885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         f += fstride*in_stride;
471885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
472885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   } else {
473885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int j;
474885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      for (j=0;j<p;j++)
475885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
476885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         compute_bitrev_table( Fout , f, fstride*p, in_stride, factors,st);
477885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         f += fstride*in_stride;
478885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Fout += m;
479885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
480885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
481885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
482885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
483885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/*  facbuf is populated by p1,m1,p2,m2, ...
484885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    where
485885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    p[i] * m[i] = m[i-1]
486885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    m0 = n                  */
487885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic
488885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgint kf_factor(int n,opus_int16 * facbuf)
489885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
490885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int p=4;
491885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
492885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    /*factor out powers of 4, powers of 2, then any remaining primes */
493885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    do {
494885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        while (n % p) {
495885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            switch (p) {
496885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                case 4: p = 2; break;
497885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                case 2: p = 3; break;
498885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                default: p += 2; break;
499885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
500885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if (p>32000 || (opus_int32)p*(opus_int32)p > n)
501885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                p = n;          /* no more factors, skip to end */
502885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }
503885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        n /= p;
504885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef RADIX_TWO_ONLY
505885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        if (p!=2 && p != 4)
506885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#else
507885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        if (p>5)
508885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
509885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        {
510885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org           return 0;
511885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }
512885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        *facbuf++ = p;
513885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        *facbuf++ = n;
514885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    } while (n > 1);
515885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    return 1;
516885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
517885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
518885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void compute_twiddles(kiss_twiddle_cpx *twiddles, int nfft)
519885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
520885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int i;
521885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT
522885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=0;i<nfft;++i) {
523885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      opus_val32 phase = -i;
524885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      kf_cexp2(twiddles+i, DIV32(SHL32(phase,17),nfft));
525885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
526885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#else
527885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=0;i<nfft;++i) {
528885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      const double pi=3.14159265358979323846264338327;
529885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      double phase = ( -2*pi /nfft ) * i;
530885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      kf_cexp(twiddles+i, phase );
531885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
532885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
533885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
534885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
535885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/*
536885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org *
537885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org * Allocates all necessary storage space for the fft and ifft.
538885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org * The return value is a contiguous block of memory.  As such,
539885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org * It can be freed with free().
540885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org * */
541885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgkiss_fft_state *opus_fft_alloc_twiddles(int nfft,void * mem,size_t * lenmem,  const kiss_fft_state *base)
542885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
543885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    kiss_fft_state *st=NULL;
544885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    size_t memneeded = sizeof(struct kiss_fft_state); /* twiddle factors*/
545885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
546885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if ( lenmem==NULL ) {
547885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        st = ( kiss_fft_state*)KISS_FFT_MALLOC( memneeded );
548885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }else{
549885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        if (mem != NULL && *lenmem >= memneeded)
550885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            st = (kiss_fft_state*)mem;
551885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        *lenmem = memneeded;
552885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
553885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if (st) {
554885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        opus_int16 *bitrev;
555885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        kiss_twiddle_cpx *twiddles;
556885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
557885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        st->nfft=nfft;
558885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifndef FIXED_POINT
559885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        st->scale = 1.f/nfft;
560885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
561885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        if (base != NULL)
562885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        {
563885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org           st->twiddles = base->twiddles;
564885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org           st->shift = 0;
565885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org           while (nfft<<st->shift != base->nfft && st->shift < 32)
566885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org              st->shift++;
567885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org           if (st->shift>=32)
568885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org              goto fail;
569885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        } else {
570885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org           st->twiddles = twiddles = (kiss_twiddle_cpx*)KISS_FFT_MALLOC(sizeof(kiss_twiddle_cpx)*nfft);
571885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org           compute_twiddles(twiddles, nfft);
572885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org           st->shift = -1;
573885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }
574885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        if (!kf_factor(nfft,st->factors))
575885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        {
576885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org           goto fail;
577885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }
578885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
579885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        /* bitrev */
580885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        st->bitrev = bitrev = (opus_int16*)KISS_FFT_MALLOC(sizeof(opus_int16)*nfft);
581885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        if (st->bitrev==NULL)
582885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            goto fail;
583885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        compute_bitrev_table(0, bitrev, 1,1, st->factors,st);
584885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
585885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    return st;
586885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgfail:
587885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    opus_fft_free(st);
588885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    return NULL;
589885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
590885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
591885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgkiss_fft_state *opus_fft_alloc(int nfft,void * mem,size_t * lenmem )
592885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
593885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   return opus_fft_alloc_twiddles(nfft, mem, lenmem, NULL);
594885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
595885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
596885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid opus_fft_free(const kiss_fft_state *cfg)
597885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
598885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (cfg)
599885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
600885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      opus_free((opus_int16*)cfg->bitrev);
601885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (cfg->shift < 0)
602885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         opus_free((kiss_twiddle_cpx*)cfg->twiddles);
603885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      opus_free((kiss_fft_state*)cfg);
604885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
605885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
606885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
607885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif /* CUSTOM_MODES */
608885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
609885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid opus_fft(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)
610885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
611885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int m2, m;
612885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int p;
613885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int L;
614885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int fstride[MAXFACTORS];
615885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int i;
616885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    int shift;
617885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
618885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    /* st->shift can be -1 */
619885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    shift = st->shift>0 ? st->shift : 0;
620885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
621885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    celt_assert2 (fin != fout, "In-place FFT not supported");
622885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    /* Bit-reverse the input */
623885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    for (i=0;i<st->nfft;i++)
624885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    {
625885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       fout[st->bitrev[i]] = fin[i];
626885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifndef FIXED_POINT
627885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       fout[st->bitrev[i]].r *= st->scale;
628885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       fout[st->bitrev[i]].i *= st->scale;
629885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
630885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
631885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
632885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    fstride[0] = 1;
633885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    L=0;
634885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    do {
635885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       p = st->factors[2*L];
636885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       m = st->factors[2*L+1];
637885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       fstride[L+1] = fstride[L]*p;
638885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       L++;
639885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    } while(m!=1);
640885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    m = st->factors[2*L-1];
641885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    for (i=L-1;i>=0;i--)
642885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    {
643885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       if (i!=0)
644885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          m2 = st->factors[2*i-1];
645885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       else
646885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          m2 = 1;
647885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       switch (st->factors[2*i])
648885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       {
649885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       case 2:
650885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          kf_bfly2(fout,fstride[i]<<shift,st,m, fstride[i], m2);
651885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          break;
652885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       case 4:
653885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          kf_bfly4(fout,fstride[i]<<shift,st,m, fstride[i], m2);
654885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          break;
655885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org #ifndef RADIX_TWO_ONLY
656885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       case 3:
657885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          kf_bfly3(fout,fstride[i]<<shift,st,m, fstride[i], m2);
658885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          break;
659885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       case 5:
660885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          kf_bfly5(fout,fstride[i]<<shift,st,m, fstride[i], m2);
661885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          break;
662885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org #endif
663885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       }
664885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       m = m2;
665885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    }
666885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
667885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
668885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid opus_ifft(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)
669885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
670885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int m2, m;
671885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int p;
672885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int L;
673885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int fstride[MAXFACTORS];
674885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int i;
675885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int shift;
676885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
677885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* st->shift can be -1 */
678885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   shift = st->shift>0 ? st->shift : 0;
679885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   celt_assert2 (fin != fout, "In-place FFT not supported");
680885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* Bit-reverse the input */
681885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=0;i<st->nfft;i++)
682885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      fout[st->bitrev[i]] = fin[i];
683885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
684885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   fstride[0] = 1;
685885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   L=0;
686885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   do {
687885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      p = st->factors[2*L];
688885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      m = st->factors[2*L+1];
689885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      fstride[L+1] = fstride[L]*p;
690885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      L++;
691885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   } while(m!=1);
692885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   m = st->factors[2*L-1];
693885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=L-1;i>=0;i--)
694885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
695885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (i!=0)
696885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         m2 = st->factors[2*i-1];
697885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      else
698885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         m2 = 1;
699885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      switch (st->factors[2*i])
700885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
701885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      case 2:
702885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         ki_bfly2(fout,fstride[i]<<shift,st,m, fstride[i], m2);
703885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         break;
704885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      case 4:
705885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         ki_bfly4(fout,fstride[i]<<shift,st,m, fstride[i], m2);
706885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         break;
707885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifndef RADIX_TWO_ONLY
708885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      case 3:
709885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         ki_bfly3(fout,fstride[i]<<shift,st,m, fstride[i], m2);
710885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         break;
711885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      case 5:
712885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         ki_bfly5(fout,fstride[i]<<shift,st,m, fstride[i], m2);
713885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         break;
714885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
715885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
716885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      m = m2;
717885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
718885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
719885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
720