static void fft16(FFTComplex *z) { FFTSample t1, t2, t3, t4, t5, t6; fft8(z); fft4(z+8); fft4(z+12); TRANSFORM_ZERO(z[0],z[4],z[8],z[12]); TRANSFORM(z[2],z[6],z[10],z[14],sqrthalf,sqrthalf); TRANSFORM(z[1],z[5],z[9],z[13],ff_cos_16[1],ff_cos_16[3]); TRANSFORM(z[3],z[7],z[11],z[15],ff_cos_16[3],ff_cos_16[1]); }
static void fft16(Complex *z) { float t1, t2, t3, t4, t5, t6; fft8(z); fft4(z + 8); fft4(z + 12); const float * const cosTable = getCosineTable(4); TRANSFORM_ZERO(z[0], z[4], z[8], z[12]); TRANSFORM(z[2], z[6], z[10], z[14], sqrthalf, sqrthalf); TRANSFORM(z[1], z[5], z[9], z[13], cosTable[1],cosTable[3]); TRANSFORM(z[3], z[7], z[11], z[15], cosTable[3], cosTable[1]); }
void fft16(FFTComplex *z) { fft8(z); fft4(z+8); fft4(z+12); TRANSFORM_ZERO(z,4); z+=2; TRANSFORM_EQUAL(z,4); z-=1; TRANSFORM(z,4,cPI1_8,cPI3_8); z+=2; TRANSFORM(z,4,cPI3_8,cPI1_8); }
void FFT::fft16(Complex *z) { float t1, t2, t3, t4, t5, t6; fft8(z); fft4(z + 8); fft4(z + 12); assert(_cosTables[0]); const float * const cosTable = _cosTables[0]->getTable(); TRANSFORM_ZERO(z[0], z[4], z[8], z[12]); TRANSFORM(z[2], z[6], z[10], z[14], sqrthalf, sqrthalf); TRANSFORM(z[1], z[5], z[9], z[13], cosTable[1],cosTable[3]); TRANSFORM(z[3], z[7], z[11], z[15], cosTable[3], cosTable[1]); }
void FFT::fft8(Complex *z) { float t1, t2, t3, t4, t5, t6, t7, t8; fft4(z); BF(t1, z[5].re, z[4].re, -z[5].re); BF(t2, z[5].im, z[4].im, -z[5].im); BF(t3, z[7].re, z[6].re, -z[7].re); BF(t4, z[7].im, z[6].im, -z[7].im); BF(t8, t1, t3, t1); BF(t7, t2, t2, t4); BF(z[4].re, z[0].re, z[0].re, t1); BF(z[4].im, z[0].im, z[0].im, t2); BF(z[6].re, z[2].re, z[2].re, t7); BF(z[6].im, z[2].im, z[2].im, t8); TRANSFORM(z[1], z[3], z[5], z[7], sqrthalf, sqrthalf); }
static inline void fft8(FFTComplex *z) { fft4(z); FFTSample t1,t2,t3,t4,t7,t8; BF(t1, z[5].re, z[4].re, -z[5].re); BF(t2, z[5].im, z[4].im, -z[5].im); BF(t3, z[7].re, z[6].re, -z[7].re); BF(t4, z[7].im, z[6].im, -z[7].im); BF(t8, t1, t3, t1); BF(t7, t2, t2, t4); BF(z[4].re, z[0].re, z[0].re, t1); BF(z[4].im, z[0].im, z[0].im, t2); BF(z[6].re, z[2].re, z[2].re, t7); BF(z[6].im, z[2].im, z[2].im, t8); z++; TRANSFORM_EQUAL(z,2); }
void FFT::fft(int n, int logn, Complex *z) { switch (logn) { case 2: fft4(z); break; case 3: fft8(z); break; case 4: fft16(z); break; default: fft((n / 2), logn - 1, z); fft((n / 4), logn - 2, z + (n / 4) * 2); fft((n / 4), logn - 2, z + (n / 4) * 3); assert(_cosTables[logn - 4]); if (n > 1024) pass_big(z, _cosTables[logn - 4]->getTable(), (n / 4) / 2); else pass(z, _cosTables[logn - 4]->getTable(), (n / 4) / 2); } }
static void fft4_dispatch(FFTComplex *z) { fft4(z); }