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 Sat Mar 13 14:55:40 2004 for WvStreams by doxygen 1.3.6-20040222