FFT_fftw3.cxx

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG)
00003  *                         UNIVERSITAT POMPEU FABRA
00004  *
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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                         // Special malloc which aligns to SIMD segment boundaries
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); // TODO: Any sense?
00145         outbuffer.SetSize(mSize/2+1); // TODO: Any sense?
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 }; // CLAM
00154 
Generated by  doxygen 1.6.3