00001
00002
00003 #ifndef FFTWRAP_H
00004 #define FFTWRAP_H
00005
00006 #ifdef WIN32
00007 #define for if(0);else for
00008 #endif
00009
00010 #ifndef STUPID_COMPLEX_KLUDGE
00011 #include <complex>
00012 #endif
00013
00014 #include "misc.h"
00015 #ifdef HAVE_FLOAT_H
00016 #include <float.h>
00017 #endif
00018
00019 #if (__GNUC__ == 3 && __GNUC_MINOR__ >= 1 && HAVE_EXT_HASH_MAP)
00020 using namespace __gnu_cxx;
00021 #endif
00022
00023 #ifdef HAVE_FFTW
00024
00025 #include <fftw.h>
00026 #include <rfftw.h>
00027
00028
00029
00030 #define NO_HASH_MAP
00031
00032 #ifdef NO_HASH_MAP
00033 #include <map>
00034 #else
00035 #ifdef HAVE_HASH_MAP
00036 #include <hash_map>
00037 #elif defined (HAVE_EXT_HASH_MAP)
00038 #include <ext/hash_map>
00039 #endif
00040
00041 #endif
00042
00043 namespace FD {
00044
00045 class _FFTWrap {
00046 #ifdef NO_HASH_MAP
00047 typedef std::map<int, rfftw_plan> FFTPlanMap;
00048 typedef std::map<int, rfftw_plan> RFFTPlanMap;
00049 #else
00050 typedef std::hash_map<int, rfftw_plan, hash<int> > FFTPlanMap;
00051 typedef std::hash_map<int, rfftw_plan, hash<int> > RFFTPlanMap;
00052
00053
00054 #endif
00055
00056 FFTPlanMap FFTPlans[2];
00057 RFFTPlanMap RFFTPlans[2];
00058 public:
00059
00060 ~_FFTWrap()
00061 {
00062 for (int i=0;i<2;i++)
00063 for (RFFTPlanMap::iterator plan_pair = RFFTPlans[i].begin(); plan_pair != RFFTPlans[i].end(); plan_pair++)
00064 rfftw_destroy_plan(plan_pair->second);
00065 for (int i=0;i<2;i++)
00066 for (FFTPlanMap::iterator plan_pair = FFTPlans[i].begin(); plan_pair != FFTPlans[i].end(); plan_pair++)
00067 fftw_destroy_plan(plan_pair->second);
00068 }
00069
00070 #ifndef STUPID_COMPLEX_KLUDGE
00071 void fft (const std::complex<float> *fin, std::complex<float> *fout, int size)
00072 {
00073 FFTW_COMPLEX in[size];
00074 FFTW_COMPLEX out[size];
00075 for (int i=0;i<size;i++)
00076 {
00077 in[i].re = fin[i].real();
00078 in[i].im = fin[i].imag();
00079 }
00080 FFTPlanMap::iterator plan_pair = FFTPlans[0].find(size);
00081 fftw_plan *plan;
00082 if (plan_pair == FFTPlans[0].end())
00083 {
00084 FFTPlans[0][size] = fftw_create_plan (size, FFTW_FORWARD, FFTW_ESTIMATE);
00085 plan = &FFTPlans[0][size];
00086 } else {
00087 plan = &plan_pair->second;
00088 }
00089
00090 fftw_one (*plan, const_cast <FFTW_COMPLEX *> (in), out);
00091
00092 for (int i=0;i<size;i++)
00093 fout[i] = std::complex<float> (out[i].re, out[i].im);
00094 }
00095
00096 void ifft (const std::complex<float> *fin, std::complex<float> *fout, int size)
00097 {
00098 FFTW_COMPLEX in[size];
00099 FFTW_COMPLEX out[size];
00100 for (int i=0;i<size;i++)
00101 {
00102 in[i].re = fin[i].real();
00103 in[i].im = fin[i].imag();
00104 }
00105 FFTPlanMap::iterator plan_pair = FFTPlans[1].find(size);
00106 fftw_plan *plan;
00107 if (plan_pair == FFTPlans[1].end())
00108 {
00109 FFTPlans[1][size] = fftw_create_plan (size, FFTW_BACKWARD, FFTW_ESTIMATE);
00110 plan = &FFTPlans[1][size];
00111 } else {
00112 plan = &plan_pair->second;
00113 }
00114
00115 fftw_one (*plan, const_cast <FFTW_COMPLEX *> (in), out);
00116
00117 for (int i=0;i<size;i++)
00118 fout[i] = std::complex<float> (out[i].re, out[i].im);
00119 }
00120 #endif
00121
00122 void rfft (const float *fin, float *fout, int size)
00123 {
00124 FFTW_REAL in[size];
00125 FFTW_REAL out[size];
00126 for (int i=0;i<size;i++)
00127 in[i]=fin[i];
00128 RFFTPlanMap::iterator plan_pair = RFFTPlans[0].find(size);
00129 rfftw_plan *plan;
00130 if (plan_pair == RFFTPlans[0].end())
00131 {
00132 RFFTPlans[0][size] = rfftw_create_plan (size, FFTW_FORWARD, FFTW_ESTIMATE);
00133 plan = &RFFTPlans[0][size];
00134 } else {
00135 plan = &plan_pair->second;
00136 }
00137
00138 rfftw_one (*plan, const_cast <FFTW_REAL *> (in), out);
00139 for (int i=0;i<size;i++)
00140 fout[i]=out[i];
00141 }
00142
00143 void irfft (const float *fin, float *fout, int size)
00144 {
00145 FFTW_REAL in[size];
00146 FFTW_REAL out[size];
00147 for (int i=0;i<size;i++)
00148 in[i]=fin[i];
00149 RFFTPlanMap::iterator plan_pair = RFFTPlans[1].find(size);
00150 rfftw_plan *plan;
00151 if (plan_pair == RFFTPlans[1].end())
00152 {
00153 RFFTPlans[1][size] = rfftw_create_plan (size, FFTW_BACKWARD, FFTW_ESTIMATE);
00154 plan = &RFFTPlans[1][size];
00155 } else {
00156 plan = &plan_pair->second;
00157 }
00158
00159 rfftw_one (*plan, const_cast <FFTW_REAL *> (in), out);
00160 for (int i=0;i<size;i++)
00161 fout[i]=out[i];
00162
00163 }
00164
00165
00166 };
00167
00168 }
00169
00170
00171 #else
00172
00173 #ifndef WIN32
00174 #warning FFTW is not present. FlowDesigner will use a (very, very) slow DFT implementation.
00175 #endif
00176
00177 #include <iostream>
00178 #include <math.h>
00179
00180 namespace FD {
00181
00182 class _FFTWrap {
00183 public:
00184 #ifndef STUPID_COMPLEX_KLUDGE
00185 void fft (const std::complex<float> *fin, std::complex<float> *fout, int size)
00186 {
00187 float fact = 2*M_PI/size;
00188 for (int i=0;i<size;i++)
00189 {
00190 fout[i] = std::complex<float> (0,0);
00191 for (int j=0;j<size;j++)
00192 {
00193 std::complex<float> c(cos(fact*j*i),-sin(fact*j*i));
00194 fout[i] += c*fin[j];
00195 }
00196 }
00197 }
00198
00199 void ifft (const std::complex<float> *fin, std::complex<float> *fout, int size)
00200 {
00201 float fact = 2*M_PI/size;
00202 for (int i=0;i<size;i++)
00203 {
00204 fout[i] = std::complex<float> (0,0);
00205 for (int j=0;j<size;j++)
00206 {
00207 std::complex<float> c(cos(fact*j*i),sin(fact*j*i));
00208 fout[i] += c*fin[j];
00209 }
00210 }
00211 }
00212 #endif
00213
00214 void rfft (const float *fin, float *fout, int size)
00215 {
00216 float fact = 2*M_PI/size;
00217 for (int i=0;i<size;i++)
00218 fout[i] = 0;
00219 for (int i=1;i<(size+1)>>1;i++)
00220 {
00221 for (int j=0;j<size;j++)
00222 {
00223 fout[i] += fin[j]*cos(fact*j*i);
00224 fout[size-i] -= fin[j]*sin(fact*j*i);
00225 }
00226 }
00227 for (int j=0;j<size;j++)
00228 {
00229 fout[0] += fin[j];
00230 }
00231 if (size&1)
00232 for (int j=0;j<size;j++)
00233 {
00234 if (j&1)
00235 fout[size>>1] -= fin[j];
00236 else
00237 fout[size>>1] += fin[j];
00238 }
00239 }
00240
00241 void irfft (const float *fin, float *fout, int size)
00242 {
00243 float fact = 2*M_PI/size;
00244 for (int i=0;i<size;i++)
00245 fout[i] = 0;
00246 for (int i=1;i<(size+1)>>1;i++)
00247 {
00248 for (int j=0;j<size;j++)
00249 {
00250 fout[i] += fin[j]*cos(fact*j*i);
00251 fout[size-i] += fin[j]*sin(fact*j*i);
00252 }
00253 }
00254 for (int j=0;j<size;j++)
00255 {
00256 fout[0] += fin[j];
00257 }
00258 if (size&1)
00259 for (int j=0;j<size;j++)
00260 {
00261 if (j&1)
00262 fout[size>>1] -= fin[j];
00263 else
00264 fout[size>>1] += fin[j];
00265 }
00266 }
00267
00268
00269 };
00270
00271 }
00272
00273 #endif
00274
00275
00276 namespace FD {
00277
00278 extern _FFTWrap FFTWrap;
00279
00280 }
00281
00282 #endif