IFFT_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 #include "IFFT_fftw3.hxx"
00023 #include "SpecTypeFlags.hxx"
00024
00025 #include "Audio.hxx"
00026 #include "Spectrum.hxx"
00027 #include "ProcessingFactory.hxx"
00028
00029 #include <fftw3.h>
00030
00031
00032 namespace CLAM {
00033
00034 namespace Hidden
00035 {
00036 static const char * metadata[] = {
00037 "key", "IFFT_fftw3",
00038 "category", "Synthesis",
00039 "description", "IFFT_fftw3",
00040 0
00041 };
00042 static FactoryRegistrator<ProcessingFactory, IFFT_fftw3> reg = metadata;
00043 }
00044
00045 struct IFFT_fftw3::Implementation
00046 {
00047 Implementation(unsigned size)
00048 {
00049
00050 _complexInput = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * size);
00051 _realOutput = (double*) fftw_malloc(sizeof(double) * size);
00052 fftw_import_system_wisdom();
00053 _plan = fftw_plan_dft_c2r_1d(size, _complexInput, _realOutput, FFTW_ESTIMATE);
00054 }
00055 ~Implementation()
00056 {
00057 fftw_destroy_plan(_plan);
00058 fftw_free(_realOutput);
00059 fftw_free(_complexInput);
00060 }
00061 fftw_plan _plan;
00062 fftw_complex * _complexInput;
00063 double * _realOutput;
00064 };
00065
00066 IFFT_fftw3::IFFT_fftw3(const IFFTConfig &c)
00067 : _fftw3(0)
00068 {
00069 Configure(c);
00070 };
00071
00072 bool IFFT_fftw3::ConcreteConfigure(const ProcessingConfig& c)
00073 {
00074 CopyAsConcreteConfig(mConfig, c);
00075 mSize = CLAM_DEFAULT_IFFT_SIZE;
00076 if (mConfig.HasAudioSize()) {
00077 CLAM_ASSERT (mConfig.GetAudioSize()>=0,"Wrong (negative) Size in IFFT Configuration.");
00078 mSize = mConfig.GetAudioSize();
00079 }
00080 mOutput.SetSize( mSize );
00081 mOutput.SetHop( mSize );
00082
00083 mState=sOther;
00084 SetupMemory();
00085 return true;
00086 }
00087
00088 IFFT_fftw3::~IFFT_fftw3()
00089 {
00090 ReleaseMemory();
00091 }
00092
00093 void IFFT_fftw3::ReleaseMemory()
00094 {
00095 if (_fftw3) delete _fftw3;
00096 }
00097 void IFFT_fftw3::SetupMemory()
00098 {
00099 ReleaseMemory();
00100 _fftw3 = new Implementation(mSize);
00101 }
00102
00103 void IFFT_fftw3::CheckTypes(const Spectrum& in, const Audio &out) const
00104 {
00105 CLAM_ASSERT(out.HasBuffer(),"IFFT Do: Float attribute required for Audio object.");
00106 CLAM_BEGIN_CHECK
00107
00108 if (out.GetSize()!=mSize) {
00109 std::stringstream ss;
00110 ss << "IFFT_fftw3::Do: Wrong size in IFFT Audio output\n"
00111 << " Expected: " << mSize*2+1 << ", used " << out.GetSize();
00112 CLAM_ASSERT(0,ss.str().c_str());
00113 }
00114 if (in.GetSize() < mSize/2+1 ) {
00115 std::stringstream ss;
00116 ss << "IFFT_fftw3::Do: not enough memory in input Spectrum.\n"
00117 << " Expected: " << mSize/2+1 << ", used " << in.GetSize();
00118 CLAM_ASSERT(0,ss.str().c_str());
00119
00120 }
00121 CLAM_END_CHECK
00122 }
00123
00124
00125
00126
00127
00128
00129
00130
00131 bool IFFT_fftw3::Do()
00132 {
00133 bool toReturn = Do(mInput.GetData(),mOutput.GetAudio());
00134 mInput.Consume();
00135 mOutput.Produce();
00136 return toReturn;
00137 };
00138
00139
00140 bool IFFT_fftw3::SetPrototypes(const Spectrum& in, const Audio &out)
00141 {
00142 CheckTypes(in,out);
00143
00144 SpecTypeFlags flags;
00145 in.GetType(flags);
00146
00147 if (flags.bComplex)
00148 mState=sComplex;
00149 else
00150 {
00151 CLAM_ASSERT(flags.bPolar || flags.bMagPhase || flags.bMagPhaseBPF,"IFFT_fftw3: SetPrototypes(): No Spectrum Attributes!");
00152 mState=sOther;
00153 }
00154
00155
00156 return true;
00157 }
00158
00159 bool IFFT_fftw3::UnsetPrototypes()
00160 {
00161 mState=sOther;
00162 return true;
00163 }
00164
00165
00166 bool IFFT_fftw3::Do( const Spectrum& in, Audio &out) const
00167 {
00168 CLAM_ASSERT(IsRunning() ,"IFFT_fftw3: Do(): Not in execution mode");
00169 CLAM_ASSERT(out.GetSize() == mSize,
00170 "Not proper IFFT output size");
00171
00172 if (mState==sComplex)
00173 ComplexToRIFFTW(in);
00174 else
00175 {
00176 CheckTypes(in,out);
00177 OtherToRIFFTW(in);
00178 }
00179 fftw_execute(_fftw3->_plan);
00180 TData * outbuffer = out.GetBuffer().GetPtr();
00181 for (int i=0; i<mSize; i++)
00182 outbuffer[i] = _fftw3->_realOutput[i];
00183
00184 out.SetSampleRate(TData(in.GetSpectralRange()*2));
00185 return true;
00186 }
00187
00188 bool IFFT_fftw3::SetPrototypes()
00189 {
00190
00191
00192 CLAM_ASSERT(false,"IFFT_fftw3::SetPrototypes: Not implemented.");
00193 return false;
00194 }
00195
00196 inline void IFFT_fftw3::ComplexToRIFFTW(const Spectrum &in) const
00197 {
00198 CLAM_ASSERT(in.HasComplexArray(), "Input spectrum has no complex array");
00199 const Array<Complex> & inbuffer = in.GetComplexArray();
00200 CLAM_ASSERT(inbuffer.Size() == mSize/2+1, "IFFT_fftw3::ComplexToRIFFTW: sizes doesn't match.");
00201 for (int i=0; i< inbuffer.Size(); i++)
00202 {
00203 _fftw3->_complexInput[i][0] = inbuffer[i].Real()/mSize;
00204 _fftw3->_complexInput[i][1] = inbuffer[i].Imag()/mSize;
00205 }
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 }
00218
00219
00220 inline void IFFT_fftw3::OtherToRIFFTW(const Spectrum &in) const
00221 {
00222 if (in.HasComplexArray())
00223 {
00224 ComplexToRIFFTW(in);
00225 return;
00226 }
00227 SpecTypeFlags flags;
00228 Spectrum spec = in;
00229 spec.GetType(flags);
00230 flags.bComplex=1;
00231 spec.SetTypeSynchronize(flags);
00232 ComplexToRIFFTW(spec);
00233 }
00234 }
00235