FFT_fftw3.cxx
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "FFT_fftw3.hxx"
00024
00025 #include "Assert.hxx"
00026 #include "Audio.hxx"
00027 #include "Spectrum.hxx"
00028 #include "SpectrumConfig.hxx"
00029 #include "CLAM_Math.hxx"
00030 #include "ProcessingFactory.hxx"
00031 #include <fftw3.h>
00032
00033 namespace CLAM
00034 {
00035
00036 namespace Hidden
00037 {
00038 static const char * metadata[] = {
00039 "key", "FFT_fftw3",
00040 "category", "Analysis",
00041 "description", "FFT_fftw3",
00042 0
00043 };
00044 static FactoryRegistrator<ProcessingFactory, FFT_fftw3> reg = metadata;
00045 }
00046
00047 namespace Hidden
00048 {
00049 struct FFT_fftw3_Implementation
00050 {
00051 FFT_fftw3_Implementation(unsigned size)
00052 {
00053
00054 realInput = (double*) fftw_malloc(sizeof(double) * size);
00055 complexOutput = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * size);
00056 fftw_import_system_wisdom();
00057 plan = fftw_plan_dft_r2c_1d(size, realInput, complexOutput, FFTW_ESTIMATE);
00058 }
00059 ~FFT_fftw3_Implementation()
00060 {
00061 fftw_destroy_plan(plan);
00062 fftw_free(realInput);
00063 fftw_free(complexOutput);
00064 }
00065 double * realInput;
00066 fftw_complex * complexOutput;
00067 fftw_plan plan;
00068 };
00069 }
00070
00071
00072 bool FFT_fftw3::ConcreteConfigure(const ProcessingConfig& c)
00073 {
00074 int oldSize=mSize;
00075 FFT_base::ConcreteConfigure(c);
00076 CLAM_WARNING(isPowerOfTwo(mSize),
00077 "FFT_fftw3: Do(): Not a power of two");
00078 if (mSize<=0)
00079 {
00080 AddConfigErrorMessage("Invalid zero or negative input size");
00081 return false;
00082 }
00083 if (mSize == oldSize) return true;
00084 SetupMemory();
00085 return true;
00086 }
00087
00088 void FFT_fftw3::ReleaseMemory()
00089 {
00090 if (_fftw3) delete _fftw3;
00091 }
00092
00093 void FFT_fftw3::SetupMemory()
00094 {
00095 ReleaseMemory();
00096 _fftw3 = new Hidden::FFT_fftw3_Implementation(mSize);
00097 }
00098
00099 FFT_fftw3::FFT_fftw3(const FFTConfig &c)
00100 : _fftw3(0)
00101 {
00102 Configure(c);
00103 }
00104
00105 FFT_fftw3::~FFT_fftw3()
00106 {
00107 ReleaseMemory();
00108 }
00109
00110 bool FFT_fftw3::Do()
00111 {
00112 mOutput.GetData().SetSize( mInput.GetSize()/2+1);
00113 bool toReturn = Do(mInput.GetAudio(), mOutput.GetData());
00114 mInput.Consume();
00115 mOutput.Produce();
00116 return toReturn;
00117 }
00118
00119 bool FFT_fftw3::Do(const Audio& in, Spectrum &out)
00120 {
00121 CLAM_DEBUG_ASSERT(IsRunning(),
00122 "FFT_fftw3: Do(): Not in execution mode");
00123
00124 out.SetSpectralRange(in.GetSampleRate()/2);
00125 if (mState==sOther) CheckTypes(in,out);
00126 TData * inbuffer = in.GetBuffer().GetPtr();
00127 for (int i=0; i<mSize; i++)
00128 _fftw3->realInput[i] = inbuffer[i];
00129 fftw_execute(_fftw3->plan);
00130 if (mState!=sOther)
00131 ToComplex(out);
00132 else
00133 ToOther(out);
00134 if (mState==sComplexSync)
00135 out.SynchronizeTo(mComplexflags);
00136
00137 return true;
00138 }
00139
00140
00141 void FFT_fftw3::ToComplex(Spectrum &out)
00142 {
00143 Array<Complex>& outbuffer = out.GetComplexArray();
00144 outbuffer.Resize(mSize/2+1);
00145 outbuffer.SetSize(mSize/2+1);
00146 for (int i=0; i<mSize/2+1; i++)
00147 {
00148 outbuffer[i].SetReal(_fftw3->complexOutput[i][0]);
00149 outbuffer[i].SetImag(_fftw3->complexOutput[i][1]);
00150 }
00151 }
00152
00153 };
00154