diff --git a/src/Experimental.h b/src/Experimental.h index 3a2f81e22..1a3bcd192 100644 --- a/src/Experimental.h +++ b/src/Experimental.h @@ -107,10 +107,6 @@ // Paul Licameli (PRL) 29 Nov 2014 // #define EXPERIMENTAL_IMPROVED_SEEKING -// Philip Van Baren 01 July 2009 -// Replace RealFFT() and PowerSpectrum function to use (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 diff --git a/src/FFT.cpp b/src/FFT.cpp index 62408eed4..9ab73bc28 100644 --- a/src/FFT.cpp +++ b/src/FFT.cpp @@ -46,6 +46,7 @@ #include #include +#include "RealFFTf.h" #include "Experimental.h" static int **gFFTBitTable = NULL; @@ -110,10 +111,6 @@ void InitFFT() } } -#ifdef EXPERIMENTAL_USE_REALFFTF -#include "RealFFTf.h" -#endif - void DeinitFFT() { if (gFFTBitTable) { @@ -122,10 +119,8 @@ void DeinitFFT() } delete[] gFFTBitTable; } -#ifdef EXPERIMENTAL_USE_REALFFTF // Deallocate any unused RealFFTf tables CleanupFFT(); -#endif } inline int FastReverseBits(int i, int NumBits) @@ -238,22 +233,11 @@ void FFT(int NumSamples, /* * Real Fast Fourier Transform * - * This function was based on the code in Numerical Recipes in C. - * In Num. Rec., the inner loop is based on a single 1-based array - * of interleaved real and imaginary numbers. Because we have two - * separate zero-based arrays, our indices are quite different. - * Here is the correspondence between Num. Rec. indices and our indices: - * - * i1 <-> real[i] - * i2 <-> imag[i] - * i3 <-> real[n/2-i] - * i4 <-> imag[n/2-i] + * This is merely a wrapper of RealFFTf() from RealFFTf.h. */ 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]; @@ -280,62 +264,8 @@ void RealFFT(int NumSamples, float *RealIn, float *RealOut, float *ImagOut) } delete [] pFFT; ReleaseFFT(hFFT); - -#else - - int Half = NumSamples / 2; - int i; - - float theta = M_PI / Half; - - float *tmpReal = new float[Half]; - float *tmpImag = new float[Half]; - - for (i = 0; i < Half; i++) { - tmpReal[i] = RealIn[2 * i]; - tmpImag[i] = RealIn[2 * i + 1]; - } - - FFT(Half, 0, tmpReal, tmpImag, RealOut, ImagOut); - - float wtemp = float (sin(0.5 * theta)); - - float wpr = -2.0 * wtemp * wtemp; - float wpi = -1.0 * float (sin(theta)); - float wr = 1.0 + wpr; - float wi = wpi; - - int i3; - - float h1r, h1i, h2r, h2i; - - for (i = 1; i < Half / 2; i++) { - - i3 = Half - 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]); - - RealOut[i] = h1r + wr * h2r - wi * h2i; - ImagOut[i] = h1i + wr * h2i + wi * h2r; - RealOut[i3] = h1r - wr * h2r + wi * h2i; - ImagOut[i3] = -h1i + wr * h2i + wi * h2r; - - wr = (wtemp = wr) * wpr - wi * wpi + wr; - wi = wi * wpr + wtemp * wpi + wi; - } - - RealOut[0] = (h1r = RealOut[0]) + ImagOut[0]; - ImagOut[0] = h1r - ImagOut[0]; - - delete[]tmpReal; - delete[]tmpImag; -#endif //EXPERIMENTAL_USE_REALFFTF } -#ifdef EXPERIMENTAL_USE_REALFFTF /* * InverseRealFFT * @@ -344,10 +274,11 @@ void RealFFT(int NumSamples, float *RealIn, float *RealOut, float *ImagOut) * and as a result the output is purely real. * Only the first half of RealIn and ImagIn are used due to this * symmetry assumption. + * + * This is merely a wrapper of InverseRealFFTf() from RealFFTf.h. */ 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]; @@ -373,15 +304,13 @@ void InverseRealFFT(int NumSamples, float *RealIn, float *ImagIn, float *RealOut delete [] pFFT; ReleaseFFT(hFFT); } -#endif // EXPERIMENTAL_USE_REALFFTF /* * 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. + * This function uses RealFFTf() from RealFFTf.h to perform the real + * FFT computation, and then squares 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. @@ -389,8 +318,6 @@ void InverseRealFFT(int NumSamples, float *RealIn, float *ImagIn, float *RealOut 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]; @@ -411,73 +338,6 @@ void PowerSpectrum(int NumSamples, float *In, float *Out) Out[i] = pFFT[1]*pFFT[1]; delete [] pFFT; ReleaseFFT(hFFT); - -#else // EXPERIMENTAL_USE_REALFFTF - - int Half = NumSamples / 2; - int i; - - float theta = M_PI / Half; - - float *tmpReal = new float[Half]; - float *tmpImag = new float[Half]; - float *RealOut = new float[Half]; - float *ImagOut = new float[Half]; - - for (i = 0; i < Half; i++) { - tmpReal[i] = In[2 * i]; - tmpImag[i] = In[2 * i + 1]; - } - - FFT(Half, 0, tmpReal, tmpImag, RealOut, ImagOut); - - float wtemp = float (sin(0.5 * theta)); - - float wpr = -2.0 * wtemp * wtemp; - float wpi = -1.0 * float (sin(theta)); - float wr = 1.0 + wpr; - float wi = wpi; - - int i3; - - float h1r, h1i, h2r, h2i, rt, it; - - for (i = 1; i < Half / 2; i++) { - - i3 = Half - 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[Half / 2]; - it = ImagOut[Half / 2]; - Out[Half / 2] = rt * rt + it * it; - - delete[]tmpReal; - delete[]tmpImag; - delete[]RealOut; - delete[]ImagOut; -#endif // EXPERIMENTAL_USE_REALFFTF } /* diff --git a/src/FFT.h b/src/FFT.h index 10dad8053..6bce57abe 100644 --- a/src/FFT.h +++ b/src/FFT.h @@ -77,13 +77,9 @@ void RealFFT(int NumSamples, * 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. diff --git a/src/FreqWindow.cpp b/src/FreqWindow.cpp index 02a894eec..91322d94c 100644 --- a/src/FreqWindow.cpp +++ b/src/FreqWindow.cpp @@ -1255,11 +1255,7 @@ bool SpectrumAnalyst::Calculate(Algorithm alg, int windowFunc, case EnhancedAutocorrelation: // Take FFT -#ifdef EXPERIMENTAL_USE_REALFFTF RealFFT(mWindowSize, in, out, out2); -#else - FFT(mWindowSize, false, in, NULL, out, out2); -#endif // Compute power for (int i = 0; i < mWindowSize; i++) in[i] = (out[i] * out[i]) + (out2[i] * out2[i]); @@ -1277,11 +1273,7 @@ bool SpectrumAnalyst::Calculate(Algorithm alg, int windowFunc, 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 (int i = 0; i < half; i++) @@ -1289,12 +1281,7 @@ bool SpectrumAnalyst::Calculate(Algorithm alg, int windowFunc, break; case Cepstrum: -#ifdef EXPERIMENTAL_USE_REALFFTF RealFFT(mWindowSize, in, out, out2); -#else - FFT(mWindowSize, false, in, NULL, out, out2); -#endif - // Compute log power // Set a sane lower limit assuming maximum time amplitude of 1.0 { @@ -1309,11 +1296,7 @@ bool SpectrumAnalyst::Calculate(Algorithm alg, int windowFunc, 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 (int i = 0; i < half; i++) diff --git a/src/Spectrum.cpp b/src/Spectrum.cpp index 5f043a8e6..d113cd5ee 100644 --- a/src/Spectrum.cpp +++ b/src/Spectrum.cpp @@ -52,11 +52,7 @@ bool ComputeSpectrum(const float * data, int width, 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]); @@ -68,12 +64,7 @@ bool ComputeSpectrum(const float * data, int width, in[i] = powf(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 PowerSpectrum(windowSize, in, out); diff --git a/src/WaveClip.cpp b/src/WaveClip.cpp index 40e38ccf8..14282d946 100644 --- a/src/WaveClip.cpp +++ b/src/WaveClip.cpp @@ -34,6 +34,7 @@ #include "Resample.h" #include "Project.h" #include "WaveTrack.h" +#include "FFT.h" #include "prefs/SpectrogramSettings.h" @@ -259,8 +260,6 @@ protected: }; -#ifdef EXPERIMENTAL_USE_REALFFTF -#include "FFT.h" static void ComputeSpectrumUsingRealFFTf (float *buffer, HFFT hFFT, const float *window, int len, float *out) { @@ -288,7 +287,6 @@ static void ComputeSpectrumUsingRealFFTf out[i] = 10.0*log10f(power); } } -#endif // EXPERIMENTAL_USE_REALFFTF WaveClip::WaveClip(DirManager *projDirManager, sampleFormat format, int rate) { @@ -852,7 +850,6 @@ bool SpecCache::CalculateOneSpectrum if (copy) useBuffer = scratch; -#ifdef EXPERIMENTAL_USE_REALFFTF if (autocorrelation) { float *const results = &freq[half * xx]; // This function does not mutate useBuffer @@ -956,12 +953,6 @@ bool SpecCache::CalculateOneSpectrum results[ii] += gainFactors[ii]; } } -#else // EXPERIMENTAL_USE_REALFFTF - // This function does not mutate scratch - ComputeSpectrum(scratch, windowSize, windowSize, - rate, results, - autocorrelation, settings.windowType); -#endif // EXPERIMENTAL_USE_REALFFTF } return result; } @@ -972,9 +963,7 @@ void SpecCache::Populate sampleCount numSamples, double offset, double rate, double pixelsPerSecond) { -#ifdef EXPERIMENTAL_USE_REALFFTF settings.CacheWindows(); -#endif const int &frequencyGain = settings.frequencyGain; const int &windowSize = settings.windowSize; diff --git a/src/WaveClip.h b/src/WaveClip.h index a208a4d14..757ec059d 100644 --- a/src/WaveClip.h +++ b/src/WaveClip.h @@ -20,9 +20,7 @@ #include "xml/XMLTagHandler.h" #include "Experimental.h" -#ifdef EXPERIMENTAL_USE_REALFFTF #include "RealFFTf.h" -#endif #include #include diff --git a/src/effects/Equalization.cpp b/src/effects/Equalization.cpp index cc85cceef..c1ce5f7a8 100644 --- a/src/effects/Equalization.cpp +++ b/src/effects/Equalization.cpp @@ -1296,11 +1296,7 @@ bool EffectEqualization::CalcFilter() //transfer to time domain to do the padding and windowing float *outr = new float[mWindowSize]; float *outi = new float[mWindowSize]; -#ifdef EXPERIMENTAL_USE_REALFFTF InverseRealFFT(mWindowSize, mFilterFuncR, NULL, outr); // To time domain -#else - FFT(mWindowSize,true,mFilterFuncR,NULL,outr,outi); //To time domain -#endif for(i=0;i<=(mM-1)/2;i++) { //Windowing - could give a choice, fixed for now - MJS @@ -2944,11 +2940,7 @@ void EqualizationPanel::Recalc() mOuti = new float[mEffect->mWindowSize]; mEffect->CalcFilter(); //to calculate the actual response -#ifdef EXPERIMENTAL_USE_REALFFTF InverseRealFFT(mEffect->mWindowSize, mEffect->mFilterFuncR, mEffect->mFilterFuncI, mOutr); -#else - FFT(mWindowSize,true,mFilterFuncR,mFilterFuncI,mOutr,mOuti); //work out FIR response - note mOuti will be all zeros -#endif // EXPERIMENTAL_USE_REALFFTF } void EqualizationPanel::OnSize(wxSizeEvent & WXUNUSED(event)) diff --git a/src/prefs/SpectrogramSettings.cpp b/src/prefs/SpectrogramSettings.cpp index 8f80a290b..090e3893e 100644 --- a/src/prefs/SpectrogramSettings.cpp +++ b/src/prefs/SpectrogramSettings.cpp @@ -348,7 +348,6 @@ SpectrogramSettings::~SpectrogramSettings() void SpectrogramSettings::DestroyWindows() { -#ifdef EXPERIMENTAL_USE_REALFFTF if (hFFT != NULL) { EndFFT(hFFT); hFFT = NULL; @@ -365,7 +364,6 @@ void SpectrogramSettings::DestroyWindows() delete[] tWindow; tWindow = NULL; } -#endif } @@ -428,7 +426,6 @@ namespace void SpectrogramSettings::CacheWindows() const { -#ifdef EXPERIMENTAL_USE_REALFFTF if (hFFT == NULL || window == NULL) { double scale; @@ -444,7 +441,6 @@ void SpectrogramSettings::CacheWindows() const RecreateWindow(dWindow, DWINDOW, fftLen, padding, windowType, windowSize, scale); } } -#endif // EXPERIMENTAL_USE_REALFFTF } void SpectrogramSettings::ConvertToEnumeratedWindowSizes() diff --git a/src/prefs/SpectrogramSettings.h b/src/prefs/SpectrogramSettings.h index b51e8a505..7fcaade12 100644 --- a/src/prefs/SpectrogramSettings.h +++ b/src/prefs/SpectrogramSettings.h @@ -137,7 +137,6 @@ public: // Following fields are derived from preferences. -#ifdef EXPERIMENTAL_USE_REALFFTF // Variables used for computing the spectrum mutable FFTParam *hFFT{}; mutable float *window{}; @@ -145,7 +144,5 @@ public: // Two other windows for computing reassigned spectrogram mutable float *tWindow{}; // Window times time parameter mutable float *dWindow{}; // Derivative of window - -#endif }; #endif