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         if (mSize<=0) 
00077         {
00078                 AddConfigErrorMessage("Invalid zero or negative input size");
00079                 return false;
00080         }
00081         if (mSize == oldSize) return true;
00082         SetupMemory();
00083         return true;
00084 }
00085 
00086 void FFT_fftw3::ReleaseMemory()
00087 {
00088         if (_fftw3) delete _fftw3;
00089 }
00090 
00091 void FFT_fftw3::SetupMemory()
00092 {
00093         ReleaseMemory();
00094         _fftw3 = new Hidden::FFT_fftw3_Implementation(mSize);
00095 }
00096 
00097 FFT_fftw3::FFT_fftw3(const FFTConfig &c)
00098         : _fftw3(0)
00099 { 
00100         Configure(c);
00101 }
00102 
00103 FFT_fftw3::~FFT_fftw3()
00104 {
00105         ReleaseMemory();
00106 }
00107 
00108 bool FFT_fftw3::Do() 
00109 {
00110         mOutput.GetData().SetSize( mInput.GetSize()/2+1);
00111         bool toReturn = Do(mInput.GetAudio(), mOutput.GetData());
00112         mInput.Consume();
00113         mOutput.Produce();
00114         return toReturn;
00115 }
00116 
00117 bool FFT_fftw3::Do(const Audio& in, Spectrum &out)
00118 {
00119         CLAM_DEBUG_ASSERT(IsRunning(),
00120                 "FFT_fftw3: Do(): Not in execution mode");
00121         CLAM_BEGIN_DEBUG_CHECK
00122                 CLAM_WARNING(isPowerOfTwo(mSize),
00123                         "FFT_fftw3: Do(): Not a power of two");
00124         CLAM_END_DEBUG_CHECK
00125 
00126         out.SetSpectralRange(in.GetSampleRate()/2);
00127         if (mState==sOther) CheckTypes(in,out);
00128         TData * inbuffer = in.GetBuffer().GetPtr();
00129         for (int i=0; i<mSize; i++)
00130                 _fftw3->realInput[i] = inbuffer[i];
00131         fftw_execute(_fftw3->plan);
00132         if (mState!=sOther)
00133                 ToComplex(out);
00134         else
00135                 ToOther(out);
00136         if (mState==sComplexSync)
00137                 out.SynchronizeTo(mComplexflags);
00138 
00139         return true;
00140 }
00141 
00142 
00143 void FFT_fftw3::ToComplex(Spectrum &out)
00144 {
00145         Array<Complex>& outbuffer = out.GetComplexArray();
00146         outbuffer.Resize(mSize/2+1); // TODO: Any sense?
00147         outbuffer.SetSize(mSize/2+1); // TODO: Any sense?
00148         for (int i=0; i<mSize/2+1; i++)
00149         {
00150                 outbuffer[i].SetReal(_fftw3->complexOutput[i][0]);
00151                 outbuffer[i].SetImag(_fftw3->complexOutput[i][1]);
00152         }
00153 }
00154 
00155 }; // CLAM
00156 

Generated on Tue Aug 12 22:33:42 2008 for CLAM by  doxygen 1.5.5