// Copyright (C) 1999 Jean-Marc Valin #ifndef FFTWRAP_H #define FFTWRAP_H #ifdef WIN32 /*Work around bug in MSVC++ (for) variable scope*/ #define for if(0);else for #endif #ifndef STUPID_COMPLEX_KLUDGE #include #endif #include "misc.h" #ifdef HAVE_FLOAT_H #include #endif #if (__GNUC__ == 3 && __GNUC_MINOR__ >= 1 && HAVE_EXT_HASH_MAP) using namespace __gnu_cxx; #endif #ifdef HAVE_FFTW #include #include //typedef fftw_complex fft_complex; #define NO_HASH_MAP #ifdef NO_HASH_MAP #include #else #ifdef HAVE_HASH_MAP #include #elif defined (HAVE_EXT_HASH_MAP) #include #endif #endif /*ifdef NO_HASH_MAP*/ namespace FD { class _FFTWrap { #ifdef NO_HASH_MAP typedef std::map FFTPlanMap; typedef std::map RFFTPlanMap; #else typedef std::hash_map > FFTPlanMap; typedef std::hash_map > RFFTPlanMap; //typedef std::map FFTPlanMap; // typedef std::map RFFTPlanMap; #endif FFTPlanMap FFTPlans[2]; RFFTPlanMap RFFTPlans[2]; public: ~_FFTWrap() { for (int i=0;i<2;i++) for (RFFTPlanMap::iterator plan_pair = RFFTPlans[i].begin(); plan_pair != RFFTPlans[i].end(); plan_pair++) rfftw_destroy_plan(plan_pair->second); for (int i=0;i<2;i++) for (FFTPlanMap::iterator plan_pair = FFTPlans[i].begin(); plan_pair != FFTPlans[i].end(); plan_pair++) fftw_destroy_plan(plan_pair->second); } #ifndef STUPID_COMPLEX_KLUDGE void fft (const std::complex *fin, std::complex *fout, int size) { FFTW_COMPLEX in[size]; FFTW_COMPLEX out[size]; for (int i=0;isecond; } fftw_one (*plan, const_cast (in), out); for (int i=0;i (out[i].re, out[i].im); } void ifft (const std::complex *fin, std::complex *fout, int size) { FFTW_COMPLEX in[size]; FFTW_COMPLEX out[size]; for (int i=0;isecond; } fftw_one (*plan, const_cast (in), out); for (int i=0;i (out[i].re, out[i].im); } #endif void rfft (const float *fin, float *fout, int size) { FFTW_REAL in[size]; FFTW_REAL out[size]; for (int i=0;isecond; } rfftw_one (*plan, const_cast (in), out); for (int i=0;isecond; } rfftw_one (*plan, const_cast (in), out); for (int i=0;i #include namespace FD { class _FFTWrap { public: #ifndef STUPID_COMPLEX_KLUDGE void fft (const std::complex *fin, std::complex *fout, int size) { float fact = 2*M_PI/size; for (int i=0;i (0,0); for (int j=0;j c(cos(fact*j*i),-sin(fact*j*i)); fout[i] += c*fin[j]; } } } void ifft (const std::complex *fin, std::complex *fout, int size) { float fact = 2*M_PI/size; for (int i=0;i (0,0); for (int j=0;j c(cos(fact*j*i),sin(fact*j*i)); fout[i] += c*fin[j]; } } } #endif void rfft (const float *fin, float *fout, int size) { float fact = 2*M_PI/size; for (int i=0;i>1;i++) { for (int j=0;j>1] -= fin[j]; else fout[size>>1] += fin[j]; } } void irfft (const float *fin, float *fout, int size) { float fact = 2*M_PI/size; for (int i=0;i>1;i++) { for (int j=0;j>1] -= fin[j]; else fout[size>>1] += fin[j]; } } }; }//namespace FD #endif /* ifdef HAVE_FFTW */ namespace FD { extern _FFTWrap FFTWrap; }//namespace FD #endif