CSL  6.0
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 FFT_Wrapper 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 FFT_Wrapper FFTR_Wrapper
40 #endif
41 
42 #ifdef USE_KISSFFT
43  #include <kiss_fft.h>
44  #define FFT_Wrapper KISSFFT_Wrapper
45 #endif
46 
47 #ifndef FFT_Wrapper
48  231450p2378640123764o127i3e6ro72364501o28736r // error
49 #endif
50 
51 namespace csl {
52 
53 /// real/complex flag (determines results from forward FFT)
54 
55 typedef enum {
59 } CSL_FFTType;
60 
61 /// forward/reverse flag (determines FFT direction)
62 
63 typedef enum {
66 } CSL_FFTDir;
67 
68 ///
69 /// Abstract FFT class can do forward/reverse real/complex I/O FFTs
70 ///
71 
72 class Abst_FFT_W {
73 public: /// Constuctor sets up twiddle factor tables
75  : mSize(size), mCSize((size / 2) + 1), mType(type), mDirection(dir) { };
76 
77  virtual ~Abst_FFT_W() { }; ///< destructor frees tables
78 
79  /// run the transform between in and out
80  virtual void nextBuffer(Buffer & in, Buffer & out) throw (CException) = 0;
81 
82  unsigned mSize; ///< FFT length
83  unsigned mCSize; ///< FFT length / 2 + 1
84 protected:
85  CSL_FFTType mType; ///< real/complex output
86  CSL_FFTDir mDirection; ///< forward/reverse
87 };
88 
89 //
90 // FFTW-wrapper concrete subclass
91 //
92 
93 #ifdef USE_FFTW
94 
95 class FFTW_Wrapper : public Abst_FFT_W {
96 public:
97  FFTW_Wrapper(unsigned size, CSL_FFTType type = CSL_FFT_REAL, CSL_FFTDir forward = CSL_FFT_FORWARD);
98  ~FFTW_Wrapper();
99  /// run the transform between in and out
100  void nextBuffer(Buffer & in, Buffer & out) throw (CException);
101 
102 private:
103 // SampleBuffer mInBuf; ///< input sample* ptr
104  SampleBuffer mSampBuf; ///< temp sample buf ptr
105  fftwf_complex *mSpectBuf; ///< complex spectrum
106  fftwf_plan mPlan; ///< FFTW plan object
107 };
108 
109 #endif
110 
111 //
112 // FFTReal-wrapper concrete subclass
113 //
114 
115 #ifdef USE_FFTREAL
116 
117 class FFTR_Wrapper : public Abst_FFT_W {
118 public:
119  FFTR_Wrapper(unsigned size, CSL_FFTType type = CSL_FFT_REAL, CSL_FFTDir forward = CSL_FFT_FORWARD);
120  ~FFTR_Wrapper();
121  /// run the transform between in and out
122  void nextBuffer(Buffer & in, Buffer & out) throw (CException);
123 
124 private:
125  SampleBuffer mTempBuf; ///< temp sample buf ptr
126  FFTReal mFFT; ///< FFTReal object
127 };
128 
129 #endif
130 
131 //
132 // KISS_FFT-wrapper concrete subclass (untested)
133 //
134 
135 #ifdef USE_KISSFFT
136 
137 class KISSFFT_Wrapper : public Abst_FFT_W {
138 public:
139  KISSFFT_Wrapper(unsigned size, CSL_FFTType type = CSL_FFT_REAL, CSL_FFTDir forward = CSL_FFT_FORWARD);
140  ~KISSFFT_Wrapper();
141  /// run the transform between in and out
142  void nextBuffer(Buffer & in, Buffer & out) throw (CException);
143 
144 private:
145  SampleBuffer mTempBuf; ///< temp sample buf ptr
146  kiss_fft_cfg mFFT; ///< KISS FFT config object pointer
147  SampleComplexVector inBuf, outBuf;
148 };
149 
150 #endif
151 
152 }
153 
154 #endif
sample * SampleBuffer
1-channel buffer data type, vector of (sample)
Definition: CSL_Types.h:194
SampleComplex * SampleComplexVector
complex vector
Definition: CSL_Types.h:202
virtual ~Abst_FFT_W()
Definition: FFT_Wrapper.h:77
CSL_FFTType
real/complex flag (determines results from forward FFT)
Definition: FFT_Wrapper.h:55
AdditiveInstrument.h – Sum-of-sines synthesis instrument class.
Definition: Accessor.h:17
virtual void nextBuffer(Buffer &in, Buffer &out)=0
destructor frees tables
CSL_FFTDir mDirection
forward/reverse
Definition: FFT_Wrapper.h:86
Abstract FFT class can do forward/reverse real/complex I/O FFTs.
Definition: FFT_Wrapper.h:72
static size_t size
Definition: fft_N.c:40
unsigned mCSize
FFT length / 2 + 1.
Definition: FFT_Wrapper.h:83
CSL_FFTType mType
real/complex output
Definition: FFT_Wrapper.h:85
Abst_FFT_W(unsigned size, CSL_FFTType type=CSL_FFT_REAL, CSL_FFTDir dir=CSL_FFT_FORWARD)
Constuctor sets up twiddle factor tables.
Definition: FFT_Wrapper.h:74
Buffer – the multi-channel sample buffer class (passed around between generators and IO guys)...
Definition: CSL_Core.h:106
CSL_FFTDir
forward/reverse flag (determines FFT direction)
Definition: FFT_Wrapper.h:63
unsigned mSize
FFT length.
Definition: FFT_Wrapper.h:82
Base class of CSL exceptions (written upper-case). Has a string message.