void RADIX_2_DIT_FFT(double *fftBuffer, long fftFrameSize, long sign) 
/*  
        FFT routine, (C)1996 S.M.Bernsee. Sign = -1 is FFT, 1 is iFFT (inverse) 
        Fills fftBuffer[0...2*fftFrameSize-1] with the Fourier transform of the 
        time domain data in fftBuffer[0...2*fftFrameSize-1]. The FFT array takes 
        and returns the cosine and sine parts in an interleaved manner, ie. 
        fftBuffer[0] = cosPart[0], fftBuffer[1] = sinPart[0], asf. fftFrameSize 
        must be a power of 2. It expects a complex input signal (see footnote 2), 
        ie. when working with 'common' audio signals our input signal has to be 
        passed as {in[0],0.,in[1],0.,in[2],0.,...} asf. In that case, the transform 
        of the frequencies of interest is in fftBuffer[0...fftFrameSize]. 
        2-radix DIT(Decimation In Time)-FFT algorithm. 
*/ 
{ 
        double wr, wi, arg, *p1, *p2, temp; 
        double tr, ti, ur, ui, *p1r, *p1i, *p2r, *p2i; 
        long i, bitm, j, le, le2, k; 
 
        // re-order x(n) or X[n] in bit reverse order. 
        // both x(n) and X[n] are complex value, a complex value occupies contineous 
        // two memory, the first is real part, and the second is imaginary part. 
        for (i = 2; i < 2*fftFrameSize-2; i += 2) { 
                for (bitm = 2, j = 0; bitm < 2*fftFrameSize; bitm <<= 1) { 
                        if (i & bitm) j++; 
                        j <<= 1; 
                } 
 
                // swap two point according bit reverse order 
                if (i < j) { 
                        p1 = fftBuffer+i; p2 = fftBuffer+j; 
                        temp = *p1; *(p1++) = *p2; 
                        *(p2++) = temp; temp = *p1; 
                        *p1 = *p2; *p2 = temp; 
                } 
        } 
 
        // After re-order in bit reverse rule, then the output will be in normal order. 
        for (k = 0, le = 2; k < (long)(log(fftFrameSize)/log(2.)+.5); k++) { 
                le <<= 1; 
                le2 = le>>1; 
                ur = 1.0;                                // cos0 
                ui = 0.0;                                // sin0 
                arg = M_PI / (le2>>1);        // 2*PI/(2^r) 
                wr = cos(arg);                        // wr = cos(arg) 
                wi = sign*sin(arg);                // wi = sin(sign*arg), if forward FFT, then sign = -1, otherwise sign = 1 
                for (j = 0; j < le2; j += 2) { 
                        p1r = fftBuffer+j; p1i = p1r+1;                // the first point of one butterfly calculation: P1 
                        p2r = p1r+le2; p2i = p2r+1;                        // the second point of one butterfly calculation: P2 
                        for (i = j; i < 2*fftFrameSize; i += le) { 
                                tr = *p2r * ur - *p2i * ui;                // real part of: P2 * WN^r 
                                ti = *p2r * ui + *p2i * ur;                // imag part of: P2 * WN^r 
                                *p2r = *p1r - tr; *p2i = *p1i - ti; 
                                *p1r += tr; *p1i += ti; 
                                p1r += le; p1i += le; 
                                p2r += le; p2i += le; 
                        } 
                        tr = ur*wr - ui*wi;                // cos(A+arg) = cosAcos(arg) - sinAsin(arg) 
                        ui = ur*wi + ui*wr;                // sin(A+arg) = sinAcos(arg) + cosAsin(arg) 
                        ur = tr; 
                } 
        } 
}
 |