#include "fft.h" #include #include /* Everything here comes from Audacity 1.3.13 (orignally in C++ and with more genericity and functionnality) Original Author : Dominic Mazzoni Licenced under GPL 2.0 (see LICENCE) */ #define MaxFastBits 16 int **gFFTBitTable = NULL; void FFT(int NumSamples, int InverseTransform, float *RealIn, float *ImagIn, float *RealOut, float *ImagOut) { int NumBits; /* Number of bits needed to store indices */ int i, j, k, n; int BlockSize, BlockEnd; double angle_numerator = 2.0 * M_PI; double tr, ti; /* temp real, temp imaginary */ /* if (!IsPowerOfTwo(NumSamples)) { fprintf(stderr, "%d is not a power of two\n", NumSamples); exit(1); } */ if (!gFFTBitTable) InitFFT(); if (!InverseTransform) angle_numerator = -angle_numerator; NumBits = NumberOfBitsNeeded(NumSamples); /* ** Do simultaneous data copy and bit-reversal ordering into outputs... */ for (i = 0; i < NumSamples; i++) { j = FastReverseBits(i, NumBits); RealOut[j] = RealIn[i]; ImagOut[j] = (ImagIn == NULL) ? 0.0 : ImagIn[i]; } /* ** Do the FFT itself... */ BlockEnd = 1; for (BlockSize = 2; BlockSize <= NumSamples; BlockSize <<= 1) { double delta_angle = angle_numerator / (double) BlockSize; double sm2 = sin(-2 * delta_angle); double sm1 = sin(-delta_angle); double cm2 = cos(-2 * delta_angle); double cm1 = cos(-delta_angle); double w = 2 * cm1; double ar0, ar1, ar2, ai0, ai1, ai2; for (i = 0; i < NumSamples; i += BlockSize) { ar2 = cm2; ar1 = cm1; ai2 = sm2; ai1 = sm1; for (j = i, n = 0; n < BlockEnd; j++, n++) { ar0 = w * ar1 - ar2; ar2 = ar1; ar1 = ar0; ai0 = w * ai1 - ai2; ai2 = ai1; ai1 = ai0; k = j + BlockEnd; tr = ar0 * RealOut[k] - ai0 * ImagOut[k]; ti = ar0 * ImagOut[k] + ai0 * RealOut[k]; RealOut[k] = RealOut[j] - tr; ImagOut[k] = ImagOut[j] - ti; RealOut[j] += tr; ImagOut[j] += ti; } } BlockEnd = BlockSize; } /* ** Need to normalize if inverse transform... */ if (InverseTransform) { float denom = (float) NumSamples; for (i = 0; i < NumSamples; i++) { RealOut[i] /= denom; ImagOut[i] /= denom; } } } void InitFFT() { gFFTBitTable = malloc(MaxFastBits*sizeof(int)); int len = 2; int b, i; for (b=1; b<=MaxFastBits; b++) { gFFTBitTable[b-1]=malloc(len*sizeof(int)); for (i=0; i>= 1; } return rev; } /* * PowerSpectrum * * This function computes the same as RealFFT, above, but * adds the squares of the real and imaginary part of each * coefficient, extracting the power and throwing away the * phase. * * For speed, it does not call RealFFT, but duplicates some * of its code. */ void PowerSpectrum(float *In, float *Out) { int i; float theta = M_PI / 128; float tmpReal[128]; float tmpImag[128]; float RealOut[128]; float ImagOut[128]; for (i = 0; i < 128; i++) { tmpReal[i] = In[2 * i]; tmpImag[i] = In[2 * i + 1]; //FIXME : WTFFFF ? tmpImag[i]=0; } FFT(128, 0, tmpReal, tmpImag, RealOut, ImagOut); float wtemp = sin(0.5 * theta); float wpr = -2.0 * wtemp * wtemp; float wpi = -1.0 * sin(theta); float wr = 1.0 + wpr; float wi = wpi; int i3; float h1r, h1i, h2r, h2i, rt, it; for (i = 1; i < 128 / 2; i++) { i3 = 128 - i; h1r = 0.5 * (RealOut[i] + RealOut[i3]); h1i = 0.5 * (ImagOut[i] - ImagOut[i3]); h2r = 0.5 * (ImagOut[i] + ImagOut[i3]); h2i = -0.5 * (RealOut[i] - RealOut[i3]); rt = h1r + wr * h2r - wi * h2i; it = h1i + wr * h2i + wi * h2r; Out[i] = rt * rt + it * it; rt = h1r - wr * h2r + wi * h2i; it = -h1i + wr * h2i + wi * h2r; Out[i3] = rt * rt + it * it; wr = (wtemp = wr) * wpr - wi * wpi + wr; wi = wi * wpr + wtemp * wpi + wi; } rt = (h1r = RealOut[0]) + ImagOut[0]; it = h1r - ImagOut[0]; Out[0] = rt * rt + it * it; rt = RealOut[128 / 2]; it = ImagOut[128 / 2]; Out[128 / 2] = rt * rt + it * it; }