1 // ================================================================================== 2 // Copyright (c) 2016 HiFi-LoFi 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a copy 5 // of this software and associated documentation files (the "Software"), to deal 6 // in the Software without restriction, including without limitation the rights 7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 // copies of the Software, and to permit persons to whom the Software is furnished 9 // to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 16 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 17 // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 18 // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 19 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 // ================================================================================== 21 22 #ifndef _AUDIOFFT_H 23 #define _AUDIOFFT_H 24 25 26 /** 27 * AudioFFT provides real-to-complex/complex-to-real FFT routines. 28 * 29 * Features: 30 * 31 * - Real-complex FFT and complex-real inverse FFT for power-of-2-sized real data. 32 * 33 * - Uniform interface to different FFT implementations (currently Ooura, FFTW3 and Apple Accelerate). 34 * 35 * - Complex data is handled in "split-complex" format, i.e. there are separate 36 * arrays for the real and imaginary parts which can be useful for SIMD optimizations 37 * (split-complex arrays have to be of length (size/2+1) representing bins from DC 38 * to Nyquist frequency). 39 * 40 * - Output is "ready to use" (all scaling etc. is already handled internally). 41 * 42 * - No allocations/deallocations after the initialization which makes it usable 43 * for real-time audio applications (that's what I wrote it for and using it). 44 * 45 * 46 * How to use it in your project: 47 * 48 * - Add the .h and .cpp file to your project - that's all. 49 * 50 * - To get extra speed, you can link FFTW3 to your project and define 51 * AUDIOFFT_FFTW3 (however, please check whether your project suits the 52 * according license). 53 * 54 * - To get the best speed on Apple platforms, you can link the Apple 55 * Accelerate framework to your project and define 56 * AUDIOFFT_APPLE_ACCELERATE (however, please check whether your 57 * project suits the according license). 58 * 59 * 60 * Remarks: 61 * 62 * - AudioFFT is not intended to be the fastest FFT, but to be a fast-enough 63 * FFT suitable for most audio applications. 64 * 65 * - AudioFFT uses the quite liberal MIT license. 66 * 67 * 68 * Example usage: 69 * @code 70 * #include "AudioFFT.h" 71 * 72 * void Example() 73 * { 74 * const size_t fftSize = 1024; // Needs to be power of 2! 75 * 76 * std::vector<float> input(fftSize, 0.0f); 77 * std::vector<float> re(audiofft::AudioFFT::ComplexSize(fftSize)); 78 * std::vector<float> im(audiofft::AudioFFT::ComplexSize(fftSize)); 79 * std::vector<float> output(fftSize); 80 * 81 * audiofft::AudioFFT fft; 82 * fft.init(1024); 83 * fft.fft(input.data(), re.data(), im.data()); 84 * fft.ifft(output.data(), re.data(), im.data()); 85 * } 86 * @endcode 87 */ 88 89 90 #include <cstddef> 91 #include <memory> 92 93 94 namespace audiofft 95 { 96 97 namespace details 98 { 99 100 class AudioFFTImpl 101 { 102 public: 103 AudioFFTImpl() = default; 104 virtual ~AudioFFTImpl() = default; 105 virtual void init(size_t size) = 0; 106 virtual void fft(const float* data, float* re, float* im) = 0; 107 virtual void ifft(float* data, const float* re, const float* im) = 0; 108 109 private: 110 AudioFFTImpl(const AudioFFTImpl&) = delete; 111 AudioFFTImpl& operator=(const AudioFFTImpl&) = delete; 112 }; 113 } 114 115 116 // ====================================================== 117 118 119 /** 120 * @class AudioFFT 121 * @brief Performs 1D FFTs 122 */ 123 class AudioFFT 124 { 125 public: 126 /** 127 * @brief Constructor 128 */ 129 AudioFFT(); 130 131 /** 132 * @brief Initializes the FFT object 133 * @param size Size of the real input (must be power 2) 134 */ 135 void init(size_t size); 136 137 /** 138 * @brief Performs the forward FFT 139 * @param data The real input data (has to be of the length as specified in init()) 140 * @param re The real part of the complex output (has to be of length as returned by ComplexSize()) 141 * @param im The imaginary part of the complex output (has to be of length as returned by ComplexSize()) 142 */ 143 void fft(const float* data, float* re, float* im); 144 145 /** 146 * @brief Performs the inverse FFT 147 * @param data The real output data (has to be of the length as specified in init()) 148 * @param re The real part of the complex input (has to be of length as returned by ComplexSize()) 149 * @param im The imaginary part of the complex input (has to be of length as returned by ComplexSize()) 150 */ 151 void ifft(float* data, const float* re, const float* im); 152 153 /** 154 * @brief Calculates the necessary size of the real/imaginary complex arrays 155 * @param size The size of the real data 156 * @return The size of the real/imaginary complex arrays 157 */ 158 static size_t ComplexSize(size_t size); 159 160 private: 161 std::unique_ptr<details::AudioFFTImpl> _impl; 162 163 AudioFFT(const AudioFFT&) = delete; 164 AudioFFT& operator=(const AudioFFT&) = delete; 165 }; 166 167 168 /** 169 * @deprecated 170 * @brief Let's keep an AudioFFTBase type around for now because it has been here already in the 1st version in order to avoid breaking existing code. 171 */ 172 typedef AudioFFT AudioFFTBase; 173 174 } // End of namespace 175 176 #endif // Header guard 177