Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members

FFTWrap.h

00001 // Copyright (C) 1999 Jean-Marc Valin
00002 
00003 #ifndef FFTWRAP_H
00004 #define FFTWRAP_H
00005 
00006 #ifdef WIN32 /*Work around bug in MSVC++ (for) variable scope*/
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 //typedef fftw_complex fft_complex;
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 /*ifdef NO_HASH_MAP*/
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    //typedef std::map<int, rfftw_plan> FFTPlanMap;
00053    // typedef std::map<int, rfftw_plan> RFFTPlanMap;
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 }//namespace FD
00169 
00170 
00171 #else /* ifdef HAVE_FFTW */
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 }//namespace FD
00272 
00273 #endif /* ifdef HAVE_FFTW */
00274 
00275 
00276 namespace FD {
00277 
00278 extern _FFTWrap FFTWrap;
00279 
00280 }//namespace FD
00281 
00282 #endif

Generated on Wed Oct 5 14:28:55 2005 for FlowDesigner by  doxygen 1.4.4