/*---------------------------------------------------------------------------- fft.c - fast Fourier transform and its inverse (both recursively) Copyright (C) 2004, Jerome R. Breitenbach. All rights reserved. The author gives permission to anyone to freely copy, distribute, and use this file, under the following conditions: - No changes are made. - No direct commercial advantage is obtained. - No liability is attributed to the author for any damages incurred. ----------------------------------------------------------------------------*/ /****************************************************************************** * This file defines a C function fft that, by calling another function * * fft_rec (also defined), calculates an FFT recursively. Usage: * * fft(N, x, X); * * Parameters: * * N: number of points in FFT (must equal 2^n for some integer n >= 1) * * x: pointer to N time-domain samples given in rectangular form (Re x, * * Im x) * * X: pointer to N frequency-domain samples calculated in rectangular form * * (Re X, Im X) * * Similarly, a function ifft with the same parameters is defined that * * calculates an inverse FFT (IFFT) recursively. Usage: * * ifft(N, x, X); * * Here, N and X are given, and x is calculated. * ******************************************************************************/ #include #include /* macros */ #define TWO_PI (6.2831853071795864769252867665590057683943L) /* function prototypes */ void fft(int N, double (*x)[2], double (*X)[2]); void fft_rec(int N, int offset, int delta, double (*x)[2], double (*X)[2], double (*XX)[2]); void ifft(int N, double (*x)[2], double (*X)[2]); /* FFT */ void fft(int N, double (*x)[2], double (*X)[2]) { /* Declare a pointer to scratch space. */ double (*XX)[2] = (double (*)[2])malloc(2 * N * sizeof(double)); /* Calculate FFT by a recursion. */ fft_rec(N, 0, 1, x, X, XX); /* Free memory. */ free(XX); } /* FFT recursion */ void fft_rec(int N, int offset, int delta, double (*x)[2], double (*X)[2], double (*XX)[2]) { int N2 = N/2; /* half the number of points in FFT */ int k; /* generic index */ double cs, sn; /* cosine and sine */ int k00, k01, k10, k11; /* indices for butterflies */ double tmp0, tmp1; /* temporary storage */ if(N != 2) /* Perform recursive step. */ { /* Calculate two (N/2)-point DFT's. */ fft_rec(N2, offset, 2*delta, x, XX, X); fft_rec(N2, offset+delta, 2*delta, x, XX, X); /* Combine the two (N/2)-point DFT's into one N-point DFT. */ for(k=0; k