Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

wvfft.cc

Go to the documentation of this file.
00001 /* 00002 * Worldvisions Weaver Software: 00003 * Copyright (C) 1997-2002 Net Integration Technologies, Inc. 00004 * 00005 * An FFT abstraction. 00006 */ 00007 #include "wvfft.h" 00008 #include <rfftw.h> 00009 00010 /***** WvRealToComplexFFTEncoder *****/ 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; // not enough space 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 // if not flushing, process at most one block at a time 00056 if (! flush) break; 00057 } 00058 return true; 00059 } 00060 00061 00062 bool WvRealToComplexFFTEncoder::_reset() 00063 { 00064 return true; 00065 } 00066 00067 00068 /***** WvComplexToRealFFTEncoder *****/ 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 // if not flushing, process at most one block at a time 00100 if (! flush) break; 00101 } 00102 return true; 00103 } 00104 00105 00106 bool WvComplexToRealFFTEncoder::_reset() 00107 { 00108 return true; 00109 } 00110 00111 00112 /***** WvPowerSpectrumEncoder *****/ 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 // compute power spectrum 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 // if not flushing, process at most one block at a time 00143 if (! flush) break; 00144 } 00145 return true; 00146 } 00147 00148 00149 bool WvPowerSpectrumEncoder::_reset() 00150 { 00151 return true; 00152 }

Generated on Tue Oct 5 01:09:20 2004 for WvStreams by doxygen 1.3.7