CLAM-Development  1.4.0
FFT_fftw3.cxx
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG)
3  * UNIVERSITAT POMPEU FABRA
4  *
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  */
21 
22 
23 #include "FFT_fftw3.hxx"
24 
25 #include "Assert.hxx"
26 #include "Audio.hxx"
27 #include "Spectrum.hxx"
28 #include "SpectrumConfig.hxx"
29 #include "CLAM_Math.hxx"
30 #include "ProcessingFactory.hxx"
31 #include <fftw3.h>
32 
33 namespace CLAM
34 {
35 
36 namespace Hidden
37 {
38  static const char * metadata[] = {
39  "key", "FFT_fftw3",
40  "category", "Analysis",
41  "description", "FFT_fftw3",
42  0
43  };
44  static FactoryRegistrator<ProcessingFactory, FFT_fftw3> reg = metadata;
45 }
46 
47 namespace Hidden
48 {
49  struct FFT_fftw3_Implementation
50  {
51  FFT_fftw3_Implementation(unsigned size)
52  {
53  // Special malloc which aligns to SIMD segment boundaries
54  realInput = (double*) fftw_malloc(sizeof(double) * size);
55  complexOutput = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * size);
56  fftw_import_system_wisdom();
57  plan = fftw_plan_dft_r2c_1d(size, realInput, complexOutput, FFTW_ESTIMATE);
58  }
59  ~FFT_fftw3_Implementation()
60  {
61  fftw_destroy_plan(plan);
62  fftw_free(realInput);
63  fftw_free(complexOutput);
64  }
65  double * realInput;
66  fftw_complex * complexOutput;
67  fftw_plan plan;
68  };
69 }
70 
71 
73 {
74  int oldSize=mSize;
77  "FFT_fftw3: Do(): Not a power of two");
78  if (mSize<=0)
79  {
80  AddConfigErrorMessage("Invalid zero or negative input size");
81  return false;
82  }
83  if (mSize == oldSize) return true;
84  SetupMemory();
85  return true;
86 }
87 
88 void FFT_fftw3::ReleaseMemory()
89 {
90  if (_fftw3) delete _fftw3;
91 }
92 
93 void FFT_fftw3::SetupMemory()
94 {
95  ReleaseMemory();
96  _fftw3 = new Hidden::FFT_fftw3_Implementation(mSize);
97 }
98 
100  : _fftw3(0)
101 {
102  Configure(c);
103 }
104 
106 {
107  ReleaseMemory();
108 }
109 
111 {
113  bool toReturn = Do(mInput.GetAudio(), mOutput.GetData());
114  mInput.Consume();
115  mOutput.Produce();
116  return toReturn;
117 }
118 
119 bool FFT_fftw3::Do(const Audio& in, Spectrum &out)
120 {
122  "FFT_fftw3: Do(): Not in execution mode");
123 
124  out.SetSpectralRange(in.GetSampleRate()/2);
125  if (mState==sOther) CheckTypes(in,out);
126  TData * inbuffer = in.GetBuffer().GetPtr();
127  for (int i=0; i<mSize; i++)
128  _fftw3->realInput[i] = inbuffer[i];
129  fftw_execute(_fftw3->plan);
130  if (mState!=sOther)
131  ToComplex(out);
132  else
133  ToOther(out);
134  if (mState==sComplexSync)
136 
137  return true;
138 }
139 
140 
141 void FFT_fftw3::ToComplex(Spectrum &out)
142 {
143  Array<Complex>& outbuffer = out.GetComplexArray();
144  outbuffer.Resize(mSize/2+1); // TODO: Any sense?
145  outbuffer.SetSize(mSize/2+1); // TODO: Any sense?
146  for (int i=0; i<mSize/2+1; i++)
147  {
148  outbuffer[i].SetReal(_fftw3->complexOutput[i][0]);
149  outbuffer[i].SetImag(_fftw3->complexOutput[i][1]);
150  }
151 }
152 
153 }; // CLAM
154