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