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