void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride) { if (fin == fout) { CHECKBUF(tmpbuf,ntmpbuf,st->nfft); kf_work(tmpbuf,fin,1,in_stride, st->factors,st); memcpy(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft); } else { kf_work( fout, fin, 1,in_stride, st->factors,st ); } }
void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride) { if (fin == fout) { kiss_fft_cpx *tmpbuf=(kiss_fft_cpx*)malloc( sizeof(kiss_fft_cpx) * st->nfft ); kf_work(tmpbuf,fin,1,in_stride, st->factors,st); memcpy(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft); free( tmpbuf ); } else { kf_work( fout, fin, 1,in_stride, st->factors,st ); } }
void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride) { if (fin == fout) { //NOTE: this is not really an in-place FFT algorithm. //It just performs an out-of-place FFT into a temp buffer kiss_fft_cpx tmpbuf[st->nfft]; kf_work(tmpbuf,fin,1,in_stride, st->factors,st); memcpy(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft); }else{ kf_work( fout, fin, 1,in_stride, st->factors,st ); } }
void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride) { if (fin == fout) { /* NOTE: this is not really an in-place FFT algorithm. It just performs an out-of-place FFT into a temp buffer */ kiss_fft_cpx * tmpbuf = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC( sizeof(kiss_fft_cpx)*st->nfft); kf_work(tmpbuf,fin,1,in_stride, st->factors,st); memcpy(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft); KISS_FFT_TMP_FREE(tmpbuf); }else{ kf_work( fout, fin, 1,in_stride, st->factors,st ); } }
static void kf_work( kiss_fft_cpx * Fout, const kiss_fft_cpx * f, size_t fstride, int in_stride, const celt_int16 * factors, const kiss_fft_state *st, int N, int m2 ) { const int p=*factors++; /* the radix */ const int m=*factors++; /* stage's fft length/p */ /*printf ("fft %d %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N, m2);*/ if (m!=1) kf_work( Fout , f, fstride*p, in_stride, factors,st, N*p, m); /* Compensate for longer twiddles table (when sharing) */ if (st->shift>0) fstride <<= st->shift; switch (p) { case 2: kf_bfly2(Fout,fstride,st,m, N, m2); break; case 4: kf_bfly4(Fout,fstride,st,m, N, m2); break; #ifndef RADIX_TWO_ONLY case 3: kf_bfly3(Fout,fstride,st,m, N, m2); break; case 5: kf_bfly5(Fout,fstride,st,m, N, m2); break; #endif } }
void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride) { if (fin == fout) { ms_fatal("In-place FFT not supported"); /*CHECKBUF(tmpbuf,ntmpbuf,st->nfft); kf_work(tmpbuf,fin,1,in_stride, st->factors,st); SPEEX_MOVE(fout,tmpbuf,st->nfft);*/ } else { kf_shuffle( fout, fin, 1,in_stride, st->factors,st); kf_work( fout, fin, 1,in_stride, st->factors,st, 1, in_stride, 1); } }
static void kiss_fft_stride(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride) { int i; celt_assert2 (fin != fout, "In-place FFT not supported"); /* Bit-reverse the input */ for (i=0;i<st->nfft;i++) { fout[st->bitrev[i]] = fin[i]; #ifndef FIXED_POINT fout[st->bitrev[i]].r *= st->scale; fout[st->bitrev[i]].i *= st->scale; #endif } kf_work( fout, fin, 1,in_stride, st->factors,st, 1, 1); }
static 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 ) { kiss_fft_cpx * Fout_beg=Fout; const int p=*factors++; /* the radix */ const int m=*factors++; /* stage's fft length/p */ const kiss_fft_cpx * Fout_end = Fout + p*m; if (m==1) { do { *Fout = *f; f += fstride*in_stride; } while(++Fout != Fout_end ); } else { do { kf_work( Fout , f, fstride*p, in_stride, factors,st); f += fstride*in_stride; } while( (Fout += m) != Fout_end ); } Fout=Fout_beg; switch (p) { case 2: kf_bfly2(Fout,fstride,st,m); break; case 3: kf_bfly3(Fout,fstride,st,m); break; case 4: kf_bfly4(Fout,fstride,st,m); break; case 5: kf_bfly5(Fout,fstride,st,m); break; default: kf_bfly_generic(Fout,fstride,st,m,p); break; } }
void kiss_fft(kiss_fft_cfg st,complex *fin, int ntfft, int sign) { int i; //NOTE: this is not really an in-place FFT algorithm. //It just performs an out-of-place FFT into a temp buffer if (sign==1) st->inverse = 1; else st->inverse = 0; /* todo this could be done in a better way */ if (previous_sign != sign) { for (i=0;i<ntfft;i++) { st->twiddles[i].i *= -1.0; } previous_sign = sign; } complex * tmpbuf = (complex*)malloc(sizeof(complex)*st->nfft); kf_work(tmpbuf,fin,1,1, st->factors,st); memcpy(fin,tmpbuf,sizeof(complex)*st->nfft); free(tmpbuf); }
static 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 ) { kiss_fft_cpx * Fout_beg=Fout; const int p=*factors++; /* the radix */ const int m=*factors++; /* stage's fft length/p */ const kiss_fft_cpx * Fout_end = Fout + p*m; if (m==1) { do{ *Fout = *f; f += fstride*in_stride; }while(++Fout != Fout_end ); }else{ do{ // recursive call: // DFT of size m*p performed by doing // p instances of smaller DFTs of size m, // each one takes a decimated version of the input kf_work( Fout , f, fstride*p, in_stride, factors,st); f += fstride*in_stride; }while( (Fout += m) != Fout_end ); } Fout=Fout_beg; // recombine the p smaller DFTs switch (p) { case 2: kf_bfly2(Fout,fstride,st,m); break; case 4: kf_bfly4(Fout,fstride,st,m); break; default: kf_bfly_generic(Fout,fstride,st,m,p); break; } }
static 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, int N, int s2, int m2 ) { int i; kiss_fft_cpx * Fout_beg=Fout; const int p=*factors++; /* the radix */ const int m=*factors++; /* stage's fft length/p */ #if 0 /*printf ("fft %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N);*/ if (m==1) { /* int j; for (j=0;j<p;j++) { Fout[j] = *f; f += fstride*in_stride; }*/ } else { int j; for (j=0;j<p;j++) { kf_work( Fout , f, fstride*p, in_stride, factors,st, N*p, fstride*in_stride, m); f += fstride*in_stride; Fout += m; } } Fout=Fout_beg; switch (p) { case 2: kf_bfly2(Fout,fstride,st,m); break; case 3: kf_bfly3(Fout,fstride,st,m); break; case 4: kf_bfly4(Fout,fstride,st,m); break; case 5: kf_bfly5(Fout,fstride,st,m); break; default: kf_bfly_generic(Fout,fstride,st,m,p); break; } #else /*printf ("fft %d %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N, m2);*/ if (m==1) { /*for (i=0;i<N;i++) { int j; Fout = Fout_beg+i*m2; const kiss_fft_cpx * f2 = f+i*s2; for (j=0;j<p;j++) { *Fout++ = *f2; f2 += fstride*in_stride; } }*/ }else{ kf_work( Fout , f, fstride*p, in_stride, factors,st, N*p, fstride*in_stride, m); } switch (p) { case 2: kf_bfly2(Fout,fstride,st,m, N, m2); break; case 3: for (i=0;i<N;i++){Fout=Fout_beg+i*m2; kf_bfly3(Fout,fstride,st,m);} break; case 4: kf_bfly4(Fout,fstride,st,m, N, m2); break; case 5: for (i=0;i<N;i++){Fout=Fout_beg+i*m2; kf_bfly5(Fout,fstride,st,m);} break; default: for (i=0;i<N;i++){Fout=Fout_beg+i*m2; kf_bfly_generic(Fout,fstride,st,m,p);} break; } #endif }
static 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 ) { kiss_fft_cpx * Fout_beg=Fout; const int p=*factors++; /* the radix */ const int m=*factors++; /* stage's fft length/p */ const kiss_fft_cpx * Fout_end = Fout + p*m; #ifdef _OPENMP // use openmp extensions at the // top-level (not recursive) if (fstride==1 && p<=5) { int k; // execute the p different work units in different threads # pragma omp parallel for for (k=0;k<p;++k) kf_work( Fout +k*m, f+ fstride*in_stride*k,fstride*p,in_stride,factors,st); // all threads have joined by this point switch (p) { case 2: kf_bfly2(Fout,fstride,st,m); break; case 3: kf_bfly3(Fout,fstride,st,m); break; case 4: kf_bfly4(Fout,fstride,st,m); break; case 5: kf_bfly5(Fout,fstride,st,m); break; default: kf_bfly_generic(Fout,fstride,st,m,p); break; } return; } #endif if (m==1) { do{ *Fout = *f; f += fstride*in_stride; }while(++Fout != Fout_end ); }else{ do{ // recursive call: // DFT of size m*p performed by doing // p instances of smaller DFTs of size m, // each one takes a decimated version of the input kf_work( Fout , f, fstride*p, in_stride, factors,st); f += fstride*in_stride; }while( (Fout += m) != Fout_end ); } Fout=Fout_beg; // recombine the p smaller DFTs switch (p) { case 2: kf_bfly2(Fout,fstride,st,m); break; case 3: kf_bfly3(Fout,fstride,st,m); break; case 4: kf_bfly4(Fout,fstride,st,m); break; case 5: kf_bfly5(Fout,fstride,st,m); break; default: kf_bfly_generic(Fout,fstride,st,m,p); break; } }