Update of /cvsroot/audacity/audacity-src/src In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv21641
Modified Files: Experimental.h FFT.cpp FFT.h FreqWindow.cpp Spectrum.cpp Log Message: Add EXPERIMENTAL_USE_REALFFTF setting which replaces FFT calls with RealFFT and InverseRealFFT calls and also remaps the RealFFT and PowerSpectrum functions to use the faster RealFFTf function Index: Experimental.h =================================================================== RCS file: /cvsroot/audacity/audacity-src/src/Experimental.h,v retrieving revision 1.56 retrieving revision 1.57 diff -u -d -r1.56 -r1.57 --- Experimental.h 24 Jun 2009 20:37:27 -0000 1.56 +++ Experimental.h 3 Jul 2009 12:37:21 -0000 1.57 @@ -73,6 +73,10 @@ // Allow keyboard seeking before initial playback position //#define EXPERIMENTAL_SEEK_BEHIND_CURSOR +// Philip Van Baren 01 July 2009 +// Replace RealFFT() and PowerSpectrum function to used (faster) RealFFTf function +//#define EXPERIMENTAL_USE_REALFFTF + // RBD, 1 Sep 2008 // Enables MIDI Output of NoteTrack (MIDI) data during playback // USE_MIDI must be defined in order for EXPERIMENTAL_MIDI_OUT to work Index: Spectrum.cpp =================================================================== RCS file: /cvsroot/audacity/audacity-src/src/Spectrum.cpp,v retrieving revision 1.14 retrieving revision 1.15 diff -u -d -r1.14 -r1.15 --- Spectrum.cpp 24 Jan 2007 01:13:33 -0000 1.14 +++ Spectrum.cpp 3 Jul 2009 12:37:22 -0000 1.15 @@ -65,8 +65,11 @@ if (autocorrelation) { // Take FFT +#ifdef EXPERIMENTAL_USE_REALFFTF + RealFFT(windowSize, in, out, out2); +#else FFT(windowSize, false, in, NULL, out, out2); - +#endif // Compute power for (i = 0; i < windowSize; i++) in[i] = (out[i] * out[i]) + (out2[i] * out2[i]); @@ -78,7 +81,11 @@ in[i] = pow(in[i], 1.0f / 3.0f); // Take FFT +#ifdef EXPERIMENTAL_USE_REALFFTF + RealFFT(windowSize, in, out, out2); +#else FFT(windowSize, false, in, NULL, out, out2); +#endif } else Index: FreqWindow.cpp =================================================================== RCS file: /cvsroot/audacity/audacity-src/src/FreqWindow.cpp,v retrieving revision 1.73 retrieving revision 1.74 diff -u -d -r1.73 -r1.74 --- FreqWindow.cpp 16 May 2009 11:13:12 -0000 1.73 +++ FreqWindow.cpp 3 Jul 2009 12:37:22 -0000 1.74 @@ -1026,8 +1026,11 @@ case 3: // Autocorrelation, Cuberoot AC or Enhanced AC // Take FFT +#ifdef EXPERIMENTAL_USE_REALFFTF + RealFFT(mWindowSize, in, out, out2); +#else FFT(mWindowSize, false, in, NULL, out, out2); - +#endif // Compute power for (i = 0; i < mWindowSize; i++) in[i] = (out[i] * out[i]) + (out2[i] * out2[i]); @@ -1044,7 +1047,11 @@ in[i] = pow(in[i], 1.0f / 3.0f); } // Take FFT +#ifdef EXPERIMENTAL_USE_REALFFTF + RealFFT(mWindowSize, in, out, out2); +#else FFT(mWindowSize, false, in, NULL, out, out2); +#endif // Take real part of result for (i = 0; i < half; i++) @@ -1052,7 +1059,11 @@ break; case 4: // Cepstrum +#ifdef EXPERIMENTAL_USE_REALFFTF + RealFFT(mWindowSize, in, out, out2); +#else FFT(mWindowSize, false, in, NULL, out, out2); +#endif // Compute log power float power; @@ -1062,10 +1073,14 @@ if(power <= 0.) in[i] = -100000.; else - in[i] = log((out[i] * out[i]) + (out2[i] * out2[i])); + in[i] = log(power); } // Take IFFT +#ifdef EXPERIMENTAL_USE_REALFFTF + InverseRealFFT(mWindowSize, in, NULL, out); +#else FFT(mWindowSize, true, in, NULL, out, out2); +#endif // Take real part of result for (i = 0; i < half; i++) Index: FFT.cpp =================================================================== RCS file: /cvsroot/audacity/audacity-src/src/FFT.cpp,v retrieving revision 1.12 retrieving revision 1.13 diff -u -d -r1.12 -r1.13 --- FFT.cpp 26 Jun 2009 00:05:18 -0000 1.12 +++ FFT.cpp 3 Jul 2009 12:37:22 -0000 1.13 @@ -108,6 +108,10 @@ } } +#ifdef EXPERIMENTAL_USE_REALFFTF +#include "realfftf.h" +#endif + void DeinitFFT() { if (gFFTBitTable) { @@ -116,6 +120,10 @@ } delete[] gFFTBitTable; } +#ifdef EXPERIMENTAL_USE_REALFFTF + // Deallocate any unused RealFFTf tables + CleanupFFT(); +#endif } inline int FastReverseBits(int i, int NumBits) @@ -242,6 +250,37 @@ void RealFFT(int NumSamples, float *RealIn, float *RealOut, float *ImagOut) { +#ifdef EXPERIMENTAL_USE_REALFFTF + // Remap to RealFFTf() function + int i; + HFFT hFFT = GetFFT(NumSamples); + float *pFFT = new float[NumSamples]; + // Copy the data into the processing buffer + for(i=0; i<NumSamples; i++) + pFFT[i] = RealIn[i]; + + // Perform the FFT + RealFFTf(pFFT, hFFT); + + // Copy the data into the real and imaginary outputs + for(i=1;i<(NumSamples/2);i++) { + RealOut[i]=pFFT[hFFT->BitReversed[i] ]; + ImagOut[i]=pFFT[hFFT->BitReversed[i]+1]; + } + // Handle the (real-only) DC and Fs/2 bins + RealOut[0] = pFFT[0]; + RealOut[i] = pFFT[1]; + ImagOut[0] = ImagOut[i] = 0; + // Fill in the upper half using symmetry properties + for(i++ ; i<NumSamples; i++) { + RealOut[i] = RealOut[NumSamples-i]; + ImagOut[i] = -ImagOut[NumSamples-i]; + } + delete [] pFFT; + ReleaseFFT(hFFT); + +#else + int Half = NumSamples / 2; int i; @@ -291,7 +330,48 @@ delete[]tmpReal; delete[]tmpImag; +#endif EXPERIMENTAL_USE_REALFFTF +} + +#ifdef EXPERIMENTAL_USE_REALFFTF +/* + * InverseRealFFT + * + * This function computes the inverse of RealFFT, above. + * The RealIn and ImagIn is assumed to be conjugate-symmetric + * and as a result the output is purely real. + * Only the first half of RealIn and ImagIn are used due to this + * symmetry assumption. + */ +void InverseRealFFT(int NumSamples, float *RealIn, float *ImagIn, float *RealOut) +{ + // Remap to RealFFTf() function + int i; + HFFT hFFT = GetFFT(NumSamples); + float *pFFT = new float[NumSamples]; + // Copy the data into the processing buffer + for(i=0; i<(NumSamples/2); i++) + pFFT[2*i ] = RealIn[i]; + if(ImagIn == NULL) { + for(i=0; i<(NumSamples/2); i++) + pFFT[2*i+1] = 0; + } else { + for(i=0; i<(NumSamples/2); i++) + pFFT[2*i+1] = ImagIn[i]; + } + // Put the fs/2 component in the imaginary part of the DC bin + pFFT[1] = RealIn[i]; + + // Perform the FFT + InverseRealFFTf(pFFT, hFFT); + + // Copy the data to the (purely real) output buffer + ReorderToTime(hFFT, pFFT, RealOut); + + delete [] pFFT; + ReleaseFFT(hFFT); } +#endif // EXPERIMENTAL_USE_REALFFTF /* * PowerSpectrum @@ -307,6 +387,31 @@ void PowerSpectrum(int NumSamples, float *In, float *Out) { +#ifdef EXPERIMENTAL_USE_REALFFTF + // Remap to RealFFTf() function + int i; + HFFT hFFT = GetFFT(NumSamples); + float *pFFT = new float[NumSamples]; + // Copy the data into the processing buffer + for(i=0; i<NumSamples; i++) + pFFT[i] = In[i]; + + // Perform the FFT + RealFFTf(pFFT, hFFT); + + // Copy the data into the real and imaginary outputs + for(i=1;i<NumSamples/2;i++) { + Out[i]= (pFFT[hFFT->BitReversed[i] ]*pFFT[hFFT->BitReversed[i] ]) + + (pFFT[hFFT->BitReversed[i]+1]*pFFT[hFFT->BitReversed[i]+1]); + } + // Handle the (real-only) DC and Fs/2 bins + Out[0] = pFFT[0]*pFFT[0]; + Out[i] = pFFT[1]*pFFT[1]; + delete [] pFFT; + ReleaseFFT(hFFT); + +#else // EXPERIMENTAL_USE_REALFFTF + int Half = NumSamples / 2; int i; @@ -370,6 +475,7 @@ delete[]tmpImag; delete[]RealOut; delete[]ImagOut; +#endif // EXPERIMENTAL_USE_REALFFTF } /* Index: FFT.h =================================================================== RCS file: /cvsroot/audacity/audacity-src/src/FFT.h,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- FFT.h 3 Dec 2007 03:46:20 -0000 1.6 +++ FFT.h 3 Jul 2009 12:37:22 -0000 1.7 @@ -57,15 +57,27 @@ /* * Computes an FFT when the input data is real but you still - * want complex data as output. The output arrays are half - * the length of the input, and NumSamples must be a power of - * two. + * want complex data as output. The output arrays are the + * same length as the input, but will be conjugate-symmetric + * NumSamples must be a power of two. */ void RealFFT(int NumSamples, float *RealIn, float *RealOut, float *ImagOut); /* + * Computes an Inverse FFT when the input data is conjugate symmetric + * so the output is purely real. NumSamples must be a power of + * two. + * Requires: EXPERIMENTAL_USE_REALFFTF + */ +#include "Experimental.h" +#ifdef EXPERIMENTAL_USE_REALFFTF +void InverseRealFFT(int NumSamples, + float *RealIn, float *ImagIn, float *RealOut); +#endif + +/* * Computes a FFT of complex input and returns complex output. * Currently this is the only function here that supports the * inverse transform as well. @@ -111,9 +123,3 @@ // // Local Variables: // c-basic-offset: 3 -// indent-tabs-mode: nil -// End: -// -// vim: et sts=3 sw=3 -// arch-tag: 91e23340-889b-4c2d-89b0-0173315a0b32 - ------------------------------------------------------------------------------ _______________________________________________ Audacity-cvs mailing list Audacity-cvs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/audacity-cvs