25 const kiss_fft_cfg st,
34 C_FIXDIV(*Fout,2); C_FIXDIV(*Fout2,2);
36 C_MUL (t, *Fout2 , *tw1);
38 C_SUB( *Fout2 , *Fout , t );
48 const kiss_fft_cfg st,
59 tw3 = tw2 = tw1 = st->twiddles;
62 C_FIXDIV(*Fout,4); C_FIXDIV(Fout[m],4); C_FIXDIV(Fout[m2],4); C_FIXDIV(Fout[m3],4);
64 C_MUL(scratch[0],Fout[m] , *tw1 );
65 C_MUL(scratch[1],Fout[m2] , *tw2 );
66 C_MUL(scratch[2],Fout[m3] , *tw3 );
68 C_SUB( scratch[5] , *Fout, scratch[1] );
69 C_ADDTO(*Fout, scratch[1]);
70 C_ADD( scratch[3] , scratch[0] , scratch[2] );
71 C_SUB( scratch[4] , scratch[0] , scratch[2] );
72 C_SUB( Fout[m2], *Fout, scratch[3] );
76 C_ADDTO( *Fout , scratch[3] );
79 Fout[m].r = scratch[5].r - scratch[4].i;
80 Fout[m].i = scratch[5].i + scratch[4].r;
81 Fout[m3].r = scratch[5].r + scratch[4].i;
82 Fout[m3].i = scratch[5].i - scratch[4].r;
84 Fout[m].r = scratch[5].r + scratch[4].i;
85 Fout[m].i = scratch[5].i - scratch[4].r;
86 Fout[m3].r = scratch[5].r - scratch[4].i;
87 Fout[m3].i = scratch[5].i + scratch[4].r;
96 const kiss_fft_cfg st,
101 const size_t m2 = 2*m;
105 epi3 = st->twiddles[fstride*m];
107 tw1=tw2=st->twiddles;
110 C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3);
112 C_MUL(scratch[1],Fout[m] , *tw1);
113 C_MUL(scratch[2],Fout[m2] , *tw2);
115 C_ADD(scratch[3],scratch[1],scratch[2]);
116 C_SUB(scratch[0],scratch[1],scratch[2]);
120 Fout[m].r = Fout->r - HALF_OF(scratch[3].r);
121 Fout[m].i = Fout->i - HALF_OF(scratch[3].i);
123 C_MULBYSCALAR( scratch[0] , epi3.i );
125 C_ADDTO(*Fout,scratch[3]);
127 Fout[m2].r = Fout[m].r + scratch[0].i;
128 Fout[m2].i = Fout[m].i - scratch[0].r;
130 Fout[m].r -= scratch[0].i;
131 Fout[m].i += scratch[0].r;
139 const size_t fstride,
140 const kiss_fft_cfg st,
150 ya = twiddles[fstride*m];
151 yb = twiddles[fstride*2*m];
160 for ( u=0; u<m; ++u ) {
161 C_FIXDIV( *Fout0,5); C_FIXDIV( *Fout1,5); C_FIXDIV( *Fout2,5); C_FIXDIV( *Fout3,5); C_FIXDIV( *Fout4,5);
164 C_MUL(scratch[1] ,*Fout1, tw[u*fstride]);
165 C_MUL(scratch[2] ,*Fout2, tw[2*u*fstride]);
166 C_MUL(scratch[3] ,*Fout3, tw[3*u*fstride]);
167 C_MUL(scratch[4] ,*Fout4, tw[4*u*fstride]);
169 C_ADD( scratch[7],scratch[1],scratch[4]);
170 C_SUB( scratch[10],scratch[1],scratch[4]);
171 C_ADD( scratch[8],scratch[2],scratch[3]);
172 C_SUB( scratch[9],scratch[2],scratch[3]);
174 Fout0->r += scratch[7].r + scratch[8].r;
175 Fout0->i += scratch[7].i + scratch[8].i;
177 scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r);
178 scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r);
180 scratch[6].r = S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i);
181 scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i);
183 C_SUB(*Fout1,scratch[5],scratch[6]);
184 C_ADD(*Fout4,scratch[5],scratch[6]);
186 scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r);
187 scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r);
188 scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i);
189 scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i);
191 C_ADD(*Fout2,scratch[11],scratch[12]);
192 C_SUB(*Fout3,scratch[11],scratch[12]);
194 ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4;
199static void kf_bfly_generic(
201 const size_t fstride,
202 const kiss_fft_cfg st,
210 int Norig = st->nfft;
214 for ( u=0; u<m; ++u ) {
216 for ( q1=0 ; q1<p ; ++q1 ) {
217 scratch[q1] = Fout[ k ];
218 C_FIXDIV(scratch[q1],p);
223 for ( q1=0 ; q1<p ; ++q1 ) {
225 Fout[ k ] = scratch[0];
227 twidx += (int)fstride * k;
228 if (twidx>=Norig) twidx-=Norig;
229 C_MUL(t,scratch[q] , twiddles[twidx] );
230 C_ADDTO( Fout[ k ] ,t);
235 KISS_FFT_TMP_FREE(scratch);
242 const size_t fstride,
245 const kiss_fft_cfg st
249 const int p=*factors++;
250 const int m=*factors++;
256 if (fstride==1 && p<=5 && m!=1)
261# pragma omp parallel for
263 kf_work( Fout +k*m, f+ fstride*in_stride*k,fstride*p,in_stride,factors,st);
267 case 2: kf_bfly2(Fout,fstride,st,m);
break;
268 case 3: kf_bfly3(Fout,fstride,st,m);
break;
269 case 4: kf_bfly4(Fout,fstride,st,m);
break;
270 case 5: kf_bfly5(Fout,fstride,st,m);
break;
271 default: kf_bfly_generic(Fout,fstride,st,m,p);
break;
280 f += fstride*in_stride;
281 }
while(++Fout != Fout_end );
288 kf_work( Fout , f, fstride*p, in_stride, factors,st);
289 f += fstride*in_stride;
290 }
while( (Fout += m) != Fout_end );
297 case 2: kf_bfly2(Fout,fstride,st,m);
break;
298 case 3: kf_bfly3(Fout,fstride,st,m);
break;
299 case 4: kf_bfly4(Fout,fstride,st,m);
break;
300 case 5: kf_bfly5(Fout,fstride,st,m);
break;
301 default: kf_bfly_generic(Fout,fstride,st,m,p);
break;
310void kf_factor(
int n,
int * facbuf)
314 floor_sqrt = floor( sqrt((
double)n) );
320 case 4: p = 2;
break;
321 case 2: p = 3;
break;
322 default: p += 2;
break;
342 kiss_fft_cfg st=NULL;
346 if ( lenmem==NULL ) {
347 st = ( kiss_fft_cfg)KISS_FFT_MALLOC( memneeded );
349 if (mem != NULL && *lenmem >= memneeded)
350 st = (kiss_fft_cfg)mem;
356 st->inverse = inverse_fft;
358 for (i=0;i<nfft;++i) {
359 const double pi=3.141592653589793238462643383279502884197169399375105820974944;
360 double phase = -2*pi*i / nfft;
363 kf_cexp(st->twiddles+i, phase );
366 kf_factor(nfft,st->factors);
378 kf_work(tmpbuf,fin,1,in_stride, st->factors,st);
380 KISS_FFT_TMP_FREE(tmpbuf);
382 kf_work( fout, fin, 1,in_stride, st->factors,st );
401 while ( (m%2) == 0 ) m/=2;
402 while ( (m%3) == 0 ) m/=3;
403 while ( (m%5) == 0 ) m/=5;
KISS FFT internals, taken from: https://github.com/mborgerding/kissfft.
int kiss_fft_next_fast_size(int n)
Returns the smallest integer k, such that k>=n and k has only "fast" factors (2,3,...
void kiss_fft_cleanup(void)
Cleans up some memory that gets managed internally.
void kiss_fft(kiss_fft_cfg cfg, const kiss_fft_cpx *fin, kiss_fft_cpx *fout)
kiss_fft(cfg,in_out_buf)
kiss_fft_cfg kiss_fft_alloc(int nfft, int inverse_fft, void *mem, size_t *lenmem)
kiss_fft_alloc
void kiss_fft_stride(kiss_fft_cfg st, const kiss_fft_cpx *fin, kiss_fft_cpx *fout, int in_stride)
A more generic version of the above function.
Complex data type used by kissFFT.
Internal KissFFT structure.