32 static size_t nscratchbuf=0;
33 if ( nscratchbuf < nbuf ) {
49 static size_t ntmpbuf=0;
50 if ( ntmpbuf < nbuf ) {
77 t = (*Fout2) * (*tw1);
79 *Fout2 = (*Fout) - (t);
97 tw3 = tw2 = tw1 = st->twiddles();
100 scratch[0] = Fout[m] * (*tw1);
101 scratch[1] = Fout[m2] * (*tw2);
102 scratch[2] = Fout[m3] * (*tw3);
104 scratch[5] = (*Fout) - scratch[1];
106 scratch[3] = scratch[0] + scratch[2];
107 scratch[4] = scratch[0] - scratch[2];
108 Fout[m2] = (*Fout) - scratch[3];
114 if ( st->inverse() ) {
115 Fout[m] =
kiss_fft_cpx( scratch[5].real() - scratch[4].imag() , scratch[5].imag() + scratch[4].real());
116 Fout[m3] =
kiss_fft_cpx( scratch[5].real() + scratch[4].imag() , scratch[5].imag() - scratch[4].real());
118 Fout[m] =
kiss_fft_cpx( scratch[5].real() + scratch[4].imag() , scratch[5].imag() - scratch[4].real());
119 Fout[m3] =
kiss_fft_cpx( scratch[5].real() - scratch[4].imag() , scratch[5].imag() + scratch[4].real());
127 const size_t fstride,
132 const size_t m2 = 2*m;
136 epi3 = st->twiddles()[fstride*m];
138 tw1=tw2=st->twiddles();
141 scratch[1] = Fout[m] * (*tw1);
142 scratch[2] = Fout[m2] * (*tw2);
144 scratch[3] = scratch[1]+scratch[2];
145 scratch[0] = scratch[1]-scratch[2];
149 Fout[m] =
kiss_fft_cpx( Fout->real() - (scratch[3].real()/2) , Fout->imag() - (scratch[3].imag()/2) );
150 scratch[0] *= epi3.imag();
153 Fout[m2] =
kiss_fft_cpx( Fout[m].real() + scratch[0].imag() , Fout[m].imag() - scratch[0].real());
154 Fout[m] =
kiss_fft_cpx( Fout[m].real() - scratch[0].imag() , Fout[m].imag() + scratch[0].real());
162 const size_t fstride,
171 ya = twiddles[fstride*m];
172 yb = twiddles[fstride*2*m];
181 for ( u=0; u<m; ++u ) {
184 scratch[1] = *Fout1 * tw[u*fstride];
185 scratch[2] = *Fout2 * tw[2*u*fstride];
186 scratch[3] = *Fout3 * tw[3*u*fstride];
187 scratch[4] = *Fout4 * tw[4*u*fstride];
189 scratch[7] = scratch[1]+scratch[4];
190 scratch[10] = scratch[1]-scratch[4];
191 scratch[8] = scratch[2]+scratch[3];
192 scratch[9] = scratch[2]-scratch[3];
194 *Fout0 =
kiss_fft_cpx( Fout0->real() + scratch[7].real() + scratch[8].real(),
195 Fout0->imag() + scratch[7].imag() + scratch[8].imag() );
197 scratch[5] =
kiss_fft_cpx( scratch[0].real() + scratch[7].real()*ya.real() + scratch[8].real()*yb.real() ,
198 scratch[0].imag() + scratch[7].imag()*ya.real() + scratch[8].imag()*yb.real() );
200 scratch[6] =
kiss_fft_cpx( (scratch[10].imag()*ya.imag()) + (scratch[9].imag()*yb.imag()) ,
201 -(scratch[10].real()*ya.imag()) - (scratch[9].real()*yb.imag()));
203 *Fout1 = scratch[5]-scratch[6];
204 *Fout4 = scratch[5]+scratch[6];
206 scratch[11] =
kiss_fft_cpx( scratch[0].real() + (scratch[7].real()*yb.real()) + (scratch[8].real()*ya.real()),
207 scratch[0].imag() + (scratch[7].imag()*yb.real()) + (scratch[8].imag()*ya.real()));
208 scratch[12] =
kiss_fft_cpx( -(scratch[10].imag()*yb.imag()) + (scratch[9].imag()*ya.imag()),
209 (scratch[10].real()*yb.imag()) - (scratch[9].real()*ya.imag()));
211 *Fout2 = scratch[11]+scratch[12];
212 *Fout3 = scratch[11]-scratch[12];
214 ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4;
221 const size_t fstride,
229 int Norig = st->nfft();
234 for ( u = 0; u < m; ++u ) {
236 for ( q1 = 0 ; q1 <
p; ++q1 ) {
237 scratchbuf[ q1 ] = Fout[ k ];
242 for ( q1 = 0 ; q1 <
p ; ++q1 ) {
244 Fout[ k ] = scratchbuf[ 0 ];
245 for ( q = 1; q <
p; ++q ) {
246 twidx += fstride * k;
247 if ( twidx >= Norig ) twidx -= Norig;
248 t = scratchbuf[ q ] * twiddles[ twidx ];
259 const size_t fstride,
265 const int p = *factors++;
266 const int m = *factors++;
272 f += fstride*in_stride;
273 }
while(++Fout != Fout_end );
280 kf_work( Fout , f, fstride*p, in_stride, factors,st);
281 f += fstride*in_stride;
282 }
while( (Fout += m) != Fout_end );
289 case 2 :
kf_bfly2(Fout,fstride,st,m);
break;
290 case 3 :
kf_bfly3(Fout,fstride,st,m);
break;
291 case 4 :
kf_bfly4(Fout,fstride,st,m);
break;
292 case 5 :
kf_bfly5(Fout,fstride,st,m);
break;
301 kf_work(tmpbuf,fin,1,in_stride, st->factors(),st);
303 for (
int i=0; i<st->nfft(); ++i ) fout[i]=tmpbuf[i];
305 kf_work( fout, fin, 1,in_stride, st->factors(),st );
325 ncfft = st->substate()->nfft();
326 for ( k = 0; k < ncfft; ++k ) {
327 st->tmpbuf()[k] =
kiss_fft_cpx( rin[k*fin_stride],iin[k*fin_stride] );
329 kiss_fft (st->substate(), st->tmpbuf(), tmpbuf);
330 for ( k = 0; k < ncfft; ++k ) {
331 rout[k*fout_stride] = tmpbuf[k].real();
332 iout[k*fout_stride] = tmpbuf[k].imag();
347 while ( (m%2) == 0 ) m/=2;
348 while ( (m%3) == 0 ) m/=3;
349 while ( (m%5) == 0 ) m/=5;
367 if ( st->substate()->inverse() ) {
368 std::cerr <<
"kiss fft usage error: improper alloc\n";
372 ncfft = st->substate()->nfft();
384 tdc =
kiss_fft_cpx( st->tmpbuf()[0].real() , st->tmpbuf()[0].imag() );
385 freqdata[0] =
kiss_fft_cpx( tdc.real() + tdc.imag() , 0 );
386 freqdata[ncfft] =
kiss_fft_cpx( tdc.real() - tdc.imag() , 0 );
391 for ( k=1; k <= ncfft/2 ; ++k ) {
392 fpk = st->tmpbuf()[k];
393 fpnk =
kiss_fft_cpx( st->tmpbuf()[ncfft-k].real(), -st->tmpbuf()[ncfft-k].imag());
397 tw = f2k * st->super_twiddles()[k-1];
399 freqdata[k] =
kiss_fft_cpx( (f1k.real() + tw.real())/2.0 , (f1k.imag() + tw.imag())/2.0 );
400 freqdata[ncfft-k] =
kiss_fft_cpx( (f1k.real() - tw.real())/2.0 , (tw.imag() - f1k.imag())/2.0);
408 if ( st->substate()->inverse() == 0 ) {
409 std::cerr <<
"kiss fft usage error: improper alloc\n";
413 ncfft = st->substate()->nfft();
415 st->tmpbuf()[0] =
kiss_fft_cpx( freqdata[0].real() + freqdata[ncfft].real() ,
416 freqdata[0].real() - freqdata[ncfft].real() );
418 for ( k = 1; k <= ncfft / 2; ++k ) {
421 fnkc =
kiss_fft_cpx( freqdata[ncfft - k].real() , -freqdata[ncfft - k].imag() );
425 fok = tmp * st->super_twiddles()[k-1];
426 st->tmpbuf()[k] = fek + fok;
427 st->tmpbuf()[ncfft - k] = fek - fok;
429 st->tmpbuf()[ncfft - k] =
kiss_fft_cpx( st->tmpbuf()[ncfft - k].real() ,
430 -st->tmpbuf()[ncfft - k].imag() );
443 if ( st->substate()->inverse() ) {
444 std::cerr <<
"kiss fft usage error: improper alloc\n";
448 ncfft = st->substate()->nfft();
454 for ( k = 0; k < ncfft/2; ++k ) {
457 for ( k = ncfft/2; k<ncfft; ++k ) {
462 kiss_fft( st->substate() , tmpbuf, st->tmpbuf() );
465 for ( k=0; k<ncfft ; ++k ) {
466 f1k = st->super_twiddles()[k];
467 f2k = st->tmpbuf()[k];
468 freqdata[k] = 2*(f1k.real()*f2k.real() - f1k.imag()*f2k.imag());
481 if ( !st->substate()->inverse() ) {
482 std::cerr <<
"kiss fft usage error: improper alloc\n";
486 ncfft = st->substate()->nfft();
490 for ( k=0; k<ncfft ; ++k ) {
491 f1k = st->super_twiddles()[k];
497 kiss_fft( st->substate() , tmpbuf, st->tmpbuf() );
503 for ( k = 0; k < ncfft/2; ++k ) {
504 timedata[2*k] = 2*st->tmpbuf()[k].real() - x0;
506 for ( k = ncfft/2; k<ncfft; ++k ) {
507 timedata[2*(ncfft-k)-1] = 2*st->tmpbuf()[k].real() - x0;
580 if ( st->ndims() & 1 ) {
584 for (
int i=0; i<st->dimprod(); ++i ) st->tmpbuf()[i]=fin[i];
585 bufin = st->tmpbuf();
588 bufout = st->tmpbuf();
591 for ( k=0; k < st->ndims(); ++k ) {
592 int curdim = st->dims()[k];
593 int stride = st->dimprod() / curdim;
595 for ( i=0 ; i<stride ; ++i ) {
600 if ( bufout == st->tmpbuf() ) {
602 bufin = st->tmpbuf();
604 bufout = st->tmpbuf();
616 int dimReal = st->dimReal();
617 int dimOther = st->dimOther();
618 int nrbins = dimReal/2+1;
625 for ( k1=0; k1<dimOther; ++k1 ) {
626 kiss_fftr( st->cfg_r(), timedata + k1*dimReal , tmp1 );
627 for ( k2=0; k2<nrbins; ++k2 ) {
628 tmp2[ k2*dimOther+k1 ] = tmp1[k2];
632 for ( k2=0; k2<nrbins; ++k2 ) {
633 kiss_fftnd(st->cfg_nd(), tmp2+k2*dimOther, tmp1);
634 for ( k1=0; k1<dimOther; ++k1 ) {
635 freqdata[ k1*(nrbins) + k2] = tmp1[k1];
642 int dimReal = st->dimReal();
643 int dimOther = st->dimOther();
644 int nrbins = dimReal/2+1;
648 for ( k2=0; k2<nrbins; ++k2 ) {
649 for ( k1=0; k1<dimOther; ++k1 ) {
650 tmp1[k1] = freqdata[ k1*(nrbins) + k2 ];
652 kiss_fftnd(st->cfg_nd(), tmp1, tmp2+k2*dimOther);
655 for ( k1=0; k1<dimOther; ++k1 ) {
656 for ( k2=0; k2<nrbins; ++k2 ) {
657 tmp1[k2] = tmp2[ k2*dimOther+k1 ];
659 kiss_fftri( st->cfg_r(),tmp1,timedata + k1*dimReal);
ocstream cerr(std::cerr)
Wrapper around std::cerr.
void kiss_fftr(kiss_fftr_cfg st, const kiss_fft_scalar *timedata, kiss_fft_cpx *freqdata)
real fft
class kiss_fftnd_state * kiss_fftnd_cfg
void kiss_idct(kiss_dct_cfg st, const kiss_fft_scalar *freqdata, kiss_fft_scalar *timedata)
idct-II (dct-iii)
int kiss_fft_next_fast_size(int n)
void kf_work(kiss_fft_cpx *Fout, const kiss_fft_cpx *f, const size_t fstride, int in_stride, int *factors, const kiss_fft_cfg st)
void kiss_fft_split(kiss_fftsplit_cfg st, const kiss_fft_scalar *rin, const kiss_fft_scalar *iin, kiss_fft_scalar *rout, kiss_fft_scalar *iout, int fin_stride, int fout_stride)
class kiss_fftsplit_state * kiss_fftsplit_cfg
void kf_bfly_generic(kiss_fft_cpx *Fout, const size_t fstride, const kiss_fft_cfg st, int m, int p)
void kf_bfly2(kiss_fft_cpx *Fout, const size_t fstride, const kiss_fft_cfg st, int m)
void kiss_fft(kiss_fft_cfg cfg, const kiss_fft_cpx *fin, kiss_fft_cpx *fout)
void kiss_dct(kiss_dct_cfg st, const kiss_fft_scalar *timedata, kiss_fft_scalar *freqdata)
dct-II
void kf_bfly4(kiss_fft_cpx *Fout, const size_t fstride, const kiss_fft_cfg st, const size_t m)
void kiss_fftri(kiss_fftr_cfg st, const kiss_fft_cpx *freqdata, kiss_fft_scalar *timedata)
class kiss_fftr_state * kiss_fftr_cfg
kiss_fft_cpx * get_scratch_buff(size_t nbuf)
void kiss_fftndr(kiss_fftndr_cfg st, const kiss_fft_scalar *timedata, kiss_fft_cpx *freqdata)
void kiss_fft_stride(kiss_fft_cfg st, const kiss_fft_cpx *fin, kiss_fft_cpx *fout, int in_stride)
kiss_fft_cpx * get_tmp_buff(size_t nbuf)
class kiss_dct_state * kiss_dct_cfg
void kiss_fft_cleanup(void)
void kiss_fftndri(kiss_fftndr_cfg st, const kiss_fft_cpx *freqdata, kiss_fft_scalar *timedata)
void kf_bfly3(kiss_fft_cpx *Fout, const size_t fstride, const kiss_fft_cfg st, size_t m)
BooleanOptionKey const exit("options:exit")
void kf_bfly5(kiss_fft_cpx *Fout, const size_t fstride, const kiss_fft_cfg st, int m)
std::complex< kiss_fft_scalar > kiss_fft_cpx
class kiss_fftndr_state * kiss_fftndr_cfg
class kiss_fft_state * kiss_fft_cfg
void kiss_fftnd(kiss_fftnd_cfg st, const kiss_fft_cpx *fin, kiss_fft_cpx *fout)
multidim fft