CSL  5.2
FFT_Wrapper.h
Go to the documentation of this file.
1 ///
2 /// FFT_Wrapper.h -- wrapper class for FFTs that hides implementation details
3 /// This class can be used with FFTW, FFTReal, or other FFT implementations.
4 /// It assumes real-values float vectors as input to the FFT, and can deliver
5 /// real or complex results in several formats (complex #s or mag/phase).
6 /// The IFFT assumes complex input and delivers real-valued output.
7 ///
8 /// The API is minimal, with a constructor method and the work-horse
9 /// nextBuffer(Buffer & in, Buffer & out) method doing a single FFT or IFFT
10 ///
11 /// This file includes both the abstract wrapper, and the 3 standard concrete subclasses.
12 /// Compile this with one of the API flags defined in the compiler (-DUSE_FFTW), or define it below.
13 /// There are 3 standard concrete subclasses:
14 /// RealFFT (RealFFT code included in CSL), and
15 /// FFTW (assumes fftw3f is installed),
16 /// KISS FFT, built-in FFT from Laurent de Soras (included, untested).
17 ///
18 /// See the copyright notice and acknowledgment of authors in the file COPYRIGHT
19 ///
20 
21 #ifndef CSL_FFT_WRAPPER_H
22 #define CSL_FFT_WRAPPER_H
23 
24  // I use compiler flags for these, so different apps can share the same code base.
25 //#define USE_FFTW // use FFTW (faster but complicated to build)
26 //#define USE_FFTREAL // use FFTReal (smaller and simpler)
27 //#define USE_KISSFFT // use KISS FFT (smaller and simpler)
28 
29 #include "CSL_Core.h"
30 
31 #ifdef USE_FFTW
32  #include <fftw3.h>
33  #define FFTWrapper FFTW_Wrapper // which FFT wrapper class to use?
34  #define FFTWF_FLAGS FFTW_MEASURE // or use FFTW_ESTIMATE; FFTW_PRESERVE_INPUT not necessary
35 #endif
36 
37 #ifdef USE_FFTREAL
38  #include <FFTReal.h>
39  #define FFTWrapper FFTR_Wrapper
40 #endif
41 
42 #ifdef USE_KISSFFT
43  #include <kiss_fft.h>
44  #define FFTWrapper KISSFFT_Wrapper
45 #endif
46 
47 namespace csl {
48 
49 /// real/complex flag (determines results from forward FFT)
50 
51 typedef enum {
55 } CSL_FFTType;
56 
57 /// forward/reverse flag (determines FFT direction)
58 
59 typedef enum {
62 } CSL_FFTDir;
63 
64 ///
65 /// Abstract FFT class can do forward/reverse real/complex I/O FFTs
66 ///
67 
68 class Abst_FFT_W {
69 public: /// Constuctor sets up twiddle factor tables
71  : mSize(size), mCSize((size / 2) + 1), mType(type), mDirection(dir) { };
72 
73  virtual ~Abst_FFT_W() { }; ///< destructor frees tables
74 
75  /// run the transform between in and out
76  virtual void nextBuffer(Buffer & in, Buffer & out) throw (CException) = 0;
77 
78  unsigned mSize; ///< FFT length
79  unsigned mCSize; ///< FFT length / 2 + 1
80 protected:
81  CSL_FFTType mType; ///< real/complex output
82  CSL_FFTDir mDirection; ///< forward/reverse
83 };
84 
85 //
86 // FFTW-wrapper concrete subclass
87 //
88 
89 #ifdef USE_FFTW
90 
91 class FFTW_Wrapper : public Abst_FFT_W {
92 public:
93  FFTW_Wrapper(unsigned size, CSL_FFTType type = CSL_FFT_REAL, CSL_FFTDir forward = CSL_FFT_FORWARD);
94  ~FFTW_Wrapper();
95  /// run the transform between in and out
96  void nextBuffer(Buffer & in, Buffer & out) throw (CException);
97 
98 private:
99 // SampleBuffer mInBuf; ///< input sample* ptr
100  SampleBuffer mSampBuf; ///< temp sample buf ptr
101  fftwf_complex *mSpectBuf; ///< complex spectrum
102  fftwf_plan mPlan; ///< FFTW plan object
103 };
104 
105 #endif
106 
107 //
108 // FFTReal-wrapper concrete subclass
109 //
110 
111 #ifdef USE_FFTREAL
112 
113 class FFTR_Wrapper : public Abst_FFT_W {
114 public:
115  FFTR_Wrapper(unsigned size, CSL_FFTType type = CSL_FFT_REAL, CSL_FFTDir forward = CSL_FFT_FORWARD);
116  ~FFTR_Wrapper();
117  /// run the transform between in and out
118  void nextBuffer(Buffer & in, Buffer & out) throw (CException);
119 
120 private:
121  SampleBuffer mTempBuf; ///< temp sample buf ptr
122  FFTReal mFFT; ///< FFTReal object
123 };
124 
125 #endif
126 
127 //
128 // KISS_FFT-wrapper concrete subclass (untested)
129 //
130 
131 #ifdef USE_KISSFFT
132 
133 class KISSFFT_Wrapper : public Abst_FFT_W {
134 public:
135  KISSFFT_Wrapper(unsigned size, CSL_FFTType type = CSL_FFT_REAL, CSL_FFTDir forward = CSL_FFT_FORWARD);
136  ~KISSFFT_Wrapper();
137  /// run the transform between in and out
138  void nextBuffer(Buffer & in, Buffer & out) throw (CException);
139 
140 private:
141  SampleBuffer mTempBuf; ///< temp sample buf ptr
142  kiss_fft_cfg mFFT; ///< KISS FFT config object pointer
143  SampleComplexVector inBuf, outBuf;
144 };
145 
146 #endif
147 
148 }
149 
150 #endif