/// <summary> /// Compute a 1D fast Fourier transform of a dataset of complex numbers (as pairs of float's). /// </summary> /// <param name="data"></param> /// <param name="length"></param> /// <param name="direction"></param> public static void FFT(float[] data, int length, FourierDirection direction) { //Debug.Assert(data != null); //Debug.Assert(data.Length >= length * 2); //Debug.Assert(Fourier.IsPowerOf2(length) == true); Fourier.SyncLookupTableLength(length); int ln = Fourier.Log2(length); // reorder array Fourier.ReorderArray(data); // successive doubling int N = 1; int signIndex = (direction == FourierDirection.Forward) ? 0 : 1; for (int level = 1; level <= ln; level++) { int M = N; N <<= 1; float[] uRLookup = _uRLookupF[level, signIndex]; float[] uILookup = _uILookupF[level, signIndex]; for (int j = 0; j < M; j++) { float uR = uRLookup[j]; float uI = uILookup[j]; for (int evenT = j; evenT < length; evenT += N) { int even = evenT << 1; int odd = (evenT + M) << 1; float r = data[odd]; float i = data[odd + 1]; float odduR = r * uR - i * uI; float odduI = r * uI + i * uR; r = data[even]; i = data[even + 1]; data[even] = r + odduR; data[even + 1] = i + odduI; data[odd] = r - odduR; data[odd + 1] = i - odduI; } } } }
static private void ReorderArray(double[] data) { //Debug.Assert(data != null); int length = data.Length / 2; //Debug.Assert(Fourier.IsPowerOf2(length) == true); //Debug.Assert(length >= cMinLength); //Debug.Assert(length <= cMaxLength); int[] reversedBits = Fourier.GetReversedBits(Fourier.Log2(length)); for (int i = 0; i < length; i++) { int swap = reversedBits[i]; if (swap > i) { Fourier.Swap(ref data[i << 1], ref data[swap << 1]); Fourier.Swap(ref data[i << 1 + 1], ref data[swap << 1 + 1]); } } }