00001
00002
00003
00004
00005
00006
00007 #include "wvfft.h"
00008 #include <rfftw.h>
00009
00010
00011
00012 WvRealToComplexFFTEncoder::WvRealToComplexFFTEncoder(size_t _n,
00013 WvRealToComplexFFTEncoder::WindowFunction _wnd) :
00014 n(_n), wnd(_wnd)
00015 {
00016 plan = rfftw_create_plan(n, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE);
00017 }
00018
00019
00020 WvRealToComplexFFTEncoder::~WvRealToComplexFFTEncoder()
00021 {
00022 rfftw_destroy_plan(plan);
00023 }
00024
00025
00026 bool WvRealToComplexFFTEncoder::_typedencode(IBuffer &inbuf,
00027 OBuffer &outbuf, bool flush)
00028 {
00029 size_t len;
00030 while ((len = inbuf.optgettable()) != 0)
00031 {
00032 if (len < n)
00033 {
00034 len = inbuf.used();
00035 if (len < n)
00036 return ! flush;
00037 }
00038 size_t avail = outbuf.free();
00039 if (len > avail)
00040 len = avail;
00041 size_t howmany = len / n;
00042 if (howmany == 0)
00043 return ! flush;
00044 if (wnd != WND_NONE || ! flush)
00045 howmany = 1;
00046
00047 size_t total = howmany * n;
00048 double *dataout = outbuf.alloc(total);
00049 double *datain = const_cast<double*>(inbuf.get(total));
00050 rfftw(plan, howmany, datain, 1, 1, dataout, 1, 1);
00051
00052 if (wnd == WND_BOXCAR)
00053 inbuf.unget((total + 1) / 2);
00054
00055
00056 if (! flush) break;
00057 }
00058 return true;
00059 }
00060
00061
00062 bool WvRealToComplexFFTEncoder::_reset()
00063 {
00064 return true;
00065 }
00066
00067
00068
00069
00070 WvComplexToRealFFTEncoder::WvComplexToRealFFTEncoder(size_t _n) :
00071 n(_n), tmpbuf(n)
00072 {
00073 plan = rfftw_create_plan(_n, FFTW_COMPLEX_TO_REAL, FFTW_ESTIMATE);
00074 }
00075
00076
00077 WvComplexToRealFFTEncoder::~WvComplexToRealFFTEncoder()
00078 {
00079 rfftw_destroy_plan(plan);
00080 }
00081
00082
00083 bool WvComplexToRealFFTEncoder::_typedencode(IBuffer &inbuf,
00084 OBuffer &outbuf, bool flush)
00085 {
00086 size_t len;
00087 while ((len = inbuf.used()) != 0)
00088 {
00089 if (len < n)
00090 return ! flush;
00091 if (outbuf.free() < n)
00092 return ! flush;
00093 double *dataout = outbuf.alloc(n);
00094 tmpbuf.zap();
00095 tmpbuf.merge(inbuf, n);
00096 double *datain = tmpbuf.ptr();
00097 rfftw_one(plan, datain, dataout);
00098
00099
00100 if (! flush) break;
00101 }
00102 return true;
00103 }
00104
00105
00106 bool WvComplexToRealFFTEncoder::_reset()
00107 {
00108 return true;
00109 }
00110
00111
00112
00113
00114 WvPowerSpectrumEncoder::WvPowerSpectrumEncoder(size_t _n) :
00115 n(_n), half(_n / 2 + 1), mid((_n + 1) / 2)
00116 {
00117 }
00118
00119
00120 bool WvPowerSpectrumEncoder::_typedencode(IBuffer &inbuf, OBuffer &outbuf,
00121 bool flush)
00122 {
00123 size_t len;
00124 while ((len = inbuf.used()) != 0)
00125 {
00126 if (len < n)
00127 return ! flush;
00128 if (outbuf.free() < half)
00129 return ! flush;
00130 const double *datain = inbuf.get(n);
00131 double *dataout = outbuf.alloc(half);
00132
00133 dataout[0] = datain[0] * datain[0];
00134 for (size_t i = 1; i < mid; ++i)
00135 {
00136 dataout[i] = datain[i] * datain[i] +
00137 datain[n - i] * datain[n - 1];
00138 }
00139 if ((n & 1) == 0)
00140 dataout[half - 1] = datain[half - 1] * datain[half - 1];
00141
00142
00143 if (! flush) break;
00144 }
00145 return true;
00146 }
00147
00148
00149 bool WvPowerSpectrumEncoder::_reset()
00150 {
00151 return true;
00152 }