00001
00020 #include <assert.h>
00021
00022 namespace aureservoir
00023 {
00024
00026
00027
00028 void rfft(const DEVector<double>::Type &x,
00029 CDEVector<double>::Type &X, int fftsize)
00030 {
00031
00032 DEVector<double>::Type xpad(fftsize);
00033 std::fill_n(xpad.data(), fftsize, 0);
00034 xpad(_(1,x.length())) = x;
00035
00036
00037 fftw_plan p1;
00038 X.resize(fftsize/2+1);
00039 p1 = fftw_plan_dft_r2c_1d(fftsize, &xpad(1),
00040 reinterpret_cast<fftw_complex*>( &X(1) ),
00041 FFTW_ESTIMATE);
00042 fftw_execute(p1);
00043 fftw_destroy_plan(p1);
00044 }
00045
00046 void rfft(const DEVector<float>::Type &x,
00047 CDEVector<float>::Type &X, int fftsize)
00048 {
00049
00050 DEVector<float>::Type xpad(fftsize);
00051 std::fill_n(xpad.data(), fftsize, 0);
00052 xpad(_(1,x.length())) = x;
00053
00054
00055 fftwf_plan p1;
00056 X.resize(fftsize/2+1);
00057 p1 = fftwf_plan_dft_r2c_1d(fftsize, &xpad(1),
00058 reinterpret_cast<fftwf_complex*>( &X(1) ),
00059 FFTW_ESTIMATE);
00060 fftwf_execute(p1);
00061 fftwf_destroy_plan(p1);
00062 }
00063
00064 void irfft(CDEVector<double>::Type &X, DEVector<double>::Type &x)
00065 {
00066 int fftsize = 2*(X.length()-1);
00067
00068
00069 x.resize(fftsize);
00070 fftw_plan p1 = fftw_plan_dft_c2r_1d(fftsize,
00071 reinterpret_cast<fftw_complex*>( &X(1) ),
00072 &x(1), FFTW_ESTIMATE);
00073 fftw_execute(p1);
00074 fftw_destroy_plan(p1);
00075 }
00076
00077 void irfft(CDEVector<float>::Type &X, DEVector<float>::Type &x)
00078 {
00079 int fftsize = 2*(X.length()-1);
00080
00081
00082 x.resize(fftsize);
00083 fftwf_plan p1 = fftwf_plan_dft_c2r_1d(fftsize,
00084 reinterpret_cast<fftwf_complex*>( &X(1) ),
00085 &x(1), FFTW_ESTIMATE);
00086 fftwf_execute(p1);
00087 fftwf_destroy_plan(p1);
00088 }
00089
00091
00092
00093
00094 template <typename T>
00095 int CalcDelay<T>::gcc(const typename CDEVector<T>::Type &X,
00096 const typename CDEVector<T>::Type &Y, int maxdelay, int filter)
00097 {
00098 assert( X.length() == Y.length() );
00099
00100 typename CDEVector<T>::Type tmp( X.length() );
00101
00102 int fftsize = 2*(X.length()-1);
00103
00104
00105 for(int i=1; i<=X.length(); ++i)
00106 tmp(i) = conj( X(i) ) * Y(i);
00107
00108
00109 if( filter == 1 )
00110 {
00111 for(int i=1; i<=X.length(); ++i)
00112 if( std::abs(tmp(i)) != 0) tmp(i) = tmp(i) / std::abs(tmp(i));
00113 }
00114
00115
00116 typename DEVector<T>::Type crosscorr;
00117 irfft(tmp,crosscorr);
00118
00119
00120 for(int i=1; i<=fftsize; ++i)
00121 crosscorr(i) = std::abs( crosscorr(i) );
00122 int mdelay = (fftsize < maxdelay+1) ? fftsize : maxdelay+1;
00123
00124 int delay = (int) ( std::max_element( crosscorr.data(),
00125 crosscorr.data()+mdelay )
00126 - crosscorr.data() );
00127
00128
00129
00130
00131 return delay;
00132 }
00133
00135
00136
00137
00138 template <typename T>
00139 void DelayLine<T>::initBuffer(const typename DEVector<T>::Type &initbuf)
00140 {
00141 delay_ = initbuf.length();
00142 buffer_ = initbuf;
00143 readpt_ = 1;
00144 }
00145
00146 template <typename T>
00147 T DelayLine<T>::tic(T sample)
00148 {
00149
00150 if( delay_ == 0 )
00151 return sample;
00152
00153 T outsample = buffer_( readpt_ );
00154 buffer_( readpt_ ) = sample;
00155 readpt_ = (readpt_ % delay_) + 1;
00156
00157 return outsample;
00158 }
00159
00161
00162 }