1 /**********************************************************************
2 
3   FFT.h
4 
5   Dominic Mazzoni
6 
7   September 2000
8 
9   This file contains a few FFT routines, including a real-FFT
10   routine that is almost twice as fast as a normal complex FFT,
11   and a power spectrum routine which is more convenient when
12   you know you don't care about phase information.  It now also
13   contains a few basic windowing functions.
14 
15   Some of this code was based on a free implementation of an FFT
16   by Don Cross, available on the web at:
17 
18     http://www.intersrv.com/~dcross/fft.html
19 
20   The basic algorithm for his code was based on Numerical Recipes
21   in Fortran.  I optimized his code further by reducing array
22   accesses, caching the bit reversal table, and eliminating
23   float-to-double conversions, and I added the routines to
24   calculate a real FFT and a real power spectrum.
25 
26   Note: all of these routines use single-precision floats.
27   I have found that in practice, floats work well until you
28   get above 8192 samples.  If you need to do a larger FFT,
29   you need to use doubles.
30 
31 **********************************************************************/
32 #ifndef __AUDACITY_FFT_H__
33 #define __AUDACITY_FFT_H__
34 
35 #include <wx/defs.h>
36 
37 class TranslatableString;
38 
39 /*
40   Salvo Ventura - November 2006
41   Added more window functions:
42     * 4: Blackman
43     * 5: Blackman-Harris
44     * 6: Welch
45     * 7: Gaussian(a=2.5)
46     * 8: Gaussian(a=3.5)
47     * 9: Gaussian(a=4.5)
48 */
49 
50 #include <wx/defs.h>
51 #include <wx/wxchar.h>
52 
53 #ifndef M_PI
54 #define	M_PI		3.14159265358979323846  /* pi */
55 #endif
56 
57 /*
58  * This is the function you will use the most often.
59  * Given an array of floats, this will compute the power
60  * spectrum by doing a Real FFT and then computing the
61  * sum of the squares of the real and imaginary parts.
62  * Note that the output array is half the length of the
63  * input array, and that NumSamples must be a power of two.
64  */
65 
66 MATH_API
67 void PowerSpectrum(size_t NumSamples, const float *In, float *Out);
68 
69 /*
70  * Computes an FFT when the input data is real but you still
71  * want complex data as output.  The output arrays are the
72  * same length as the input, but will be conjugate-symmetric
73  * NumSamples must be a power of two.
74  */
75 
76 MATH_API
77 void RealFFT(size_t NumSamples,
78              const float *RealIn, float *RealOut, float *ImagOut);
79 
80 /*
81  * Computes an Inverse FFT when the input data is conjugate symmetric
82  * so the output is purely real.  NumSamples must be a power of
83  * two.
84  */
85 MATH_API
86 void InverseRealFFT(size_t NumSamples,
87 		    const float *RealIn, const float *ImagIn, float *RealOut);
88 
89 /*
90  * Computes a FFT of complex input and returns complex output.
91  * Currently this is the only function here that supports the
92  * inverse transform as well.
93  */
94 
95 MATH_API
96 void FFT(size_t NumSamples,
97          bool InverseTransform,
98          const float *RealIn, const float *ImagIn, float *RealOut, float *ImagOut);
99 
100 /*
101  * Multiply values in data by values of the chosen function
102  * DO NOT REUSE!  Prefer NewWindowFunc instead
103  * This version was inconsistent whether the window functions were
104  * symmetrical about NumSamples / 2, or about (NumSamples - 1) / 2
105  * It remains for compatibility until we decide to upgrade all the old uses
106  * All functions have 0 in data[0] except Rectangular, Hamming and Gaussians
107  */
108 
109 enum eWindowFunctions : int
110 {
111    eWinFuncRectangular,
112    eWinFuncBartlett,
113    eWinFuncHamming,
114    eWinFuncHann,
115    eWinFuncBlackman,
116    eWinFuncBlackmanHarris,
117    eWinFuncWelch,
118    eWinFuncGaussian25,
119    eWinFuncGaussian35,
120    eWinFuncGaussian45,
121    eWinFuncCount
122 };
123 
124 MATH_API
125 void WindowFunc(int whichFunction, size_t NumSamples, float *data);
126 
127 /*
128  * Multiply values in data by values of the chosen function
129  * All functions are symmetrical about NumSamples / 2 if extraSample is false,
130  * otherwise about (NumSamples - 1) / 2
131  * All functions have 0 in data[0] except Rectangular, Hamming and Gaussians
132  */
133 MATH_API
134 void NewWindowFunc(int whichFunction, size_t NumSamples, bool extraSample, float *data);
135 
136 /*
137  * Multiply values in data by derivative of the chosen function, assuming
138  * sampling interval is unit
139  * All functions are symmetrical about NumSamples / 2 if extraSample is false,
140  * otherwise about (NumSamples - 1) / 2
141  * All functions have 0 in data[0] except Rectangular, Hamming and Gaussians
142  */
143 MATH_API
144 void DerivativeOfWindowFunc(int whichFunction, size_t NumSamples, bool extraSample, float *data);
145 
146 /*
147  * Returns the name of the windowing function (for UI display)
148  */
149 
150 MATH_API const TranslatableString WindowFuncName(int whichFunction);
151 
152 /*
153  * Returns the number of windowing functions supported
154  */
155 
156 MATH_API int NumWindowFuncs();
157 
158 MATH_API void DeinitFFT();
159 
160 #endif
161