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 kiss_ifft_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]; ki_work( fout, fin, 1,in_stride, st->factors,st, 1, 1); }
void opus_ifft_c(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout) { 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]; for (i=0;i<st->nfft;i++) fout[i].i = -fout[i].i; opus_fft_impl(st, fout); for (i=0;i<st->nfft;i++) fout[i].i = -fout[i].i; }
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); }
void opus_fft_c(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout) { int i; opus_val16 scale; #ifdef FIXED_POINT /* Allows us to scale with MULT16_32_Q16(), which is faster than MULT16_32_Q15() on ARM. */ int scale_shift = st->scale_shift-1; #endif scale = st->scale; celt_assert2 (fin != fout, "In-place FFT not supported"); /* Bit-reverse the input */ for (i=0;i<st->nfft;i++) { kiss_fft_cpx x = fin[i]; fout[st->bitrev[i]].r = SHR32(MULT16_32_Q16(scale, x.r), scale_shift); fout[st->bitrev[i]].i = SHR32(MULT16_32_Q16(scale, x.i), scale_shift); } opus_fft_impl(st, fout); }