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 opus_fft(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout) { int m2, m; int p; int L; int fstride[MAXFACTORS]; int i; int shift; /* st->shift can be -1 */ shift = st->shift>0 ? st->shift : 0; 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 } fstride[0] = 1; L=0; do { p = st->factors[2*L]; m = st->factors[2*L+1]; fstride[L+1] = fstride[L]*p; L++; } while(m!=1); m = st->factors[2*L-1]; for (i=L-1;i>=0;i--) { if (i!=0) m2 = st->factors[2*i-1]; else m2 = 1; switch (st->factors[2*i]) { case 2: kf_bfly2(fout,fstride[i]<<shift,st,m, fstride[i], m2); break; case 4: kf_bfly4(fout,fstride[i]<<shift,st,m, fstride[i], m2); break; #ifndef RADIX_TWO_ONLY case 3: kf_bfly3(fout,fstride[i]<<shift,st,m, fstride[i], m2); break; case 5: kf_bfly5(fout,fstride[i]<<shift,st,m, fstride[i], m2); break; #endif } m = m2; } }
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 opus_fft_impl(const kiss_fft_state *st,kiss_fft_cpx *fout) { int m2, m; int p; int L; int fstride[MAXFACTORS]; int i; int shift; /* st->shift can be -1 */ shift = st->shift>0 ? st->shift : 0; fstride[0] = 1; L=0; do { p = st->factors[2*L]; m = st->factors[2*L+1]; fstride[L+1] = fstride[L]*p; L++; } while(m!=1); m = st->factors[2*L-1]; for (i=L-1;i>=0;i--) { if (i!=0) m2 = st->factors[2*i-1]; else m2 = 1; switch (st->factors[2*i]) { case 2: kf_bfly2(fout, m, fstride[i]); break; case 4: kf_bfly4(fout,fstride[i]<<shift,st,m, fstride[i], m2); break; #ifndef RADIX_TWO_ONLY case 3: kf_bfly3(fout,fstride[i]<<shift,st,m, fstride[i], m2); break; case 5: kf_bfly5(fout,fstride[i]<<shift,st,m, fstride[i], m2); break; #endif } m = m2; } }
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; } }