1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 3 /* 4 bqfft 5 6 A small library wrapping various FFT implementations for some 7 common audio processing use cases. 8 9 Copyright 2007-2016 Particular Programs Ltd. 10 11 Permission is hereby granted, free of charge, to any person 12 obtaining a copy of this software and associated documentation 13 files (the "Software"), to deal in the Software without 14 restriction, including without limitation the rights to use, copy, 15 modify, merge, publish, distribute, sublicense, and/or sell copies 16 of the Software, and to permit persons to whom the Software is 17 furnished to do so, subject to the following conditions: 18 19 The above copyright notice and this permission notice shall be 20 included in all copies or substantial portions of the Software. 21 22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 25 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR 26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 27 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 30 Except as contained in this notice, the names of Chris Cannam and 31 Particular Programs Ltd shall not be used in advertising or 32 otherwise to promote the sale, use or other dealings in this 33 Software without prior written authorization. 34 */ 35 36 #ifndef BQFFT_FFT_H 37 #define BQFFT_FFT_H 38 39 #include <bqvec/Restrict.h> 40 41 #include <string> 42 #include <set> 43 44 namespace breakfastquay { 45 46 class FFTImpl; 47 48 /** 49 * Provide basic FFT computations using one of a set of candidate FFT 50 * implementations (depending on compile flags). validateTzEntry(tzEntry * tzentry)51 * 52 * Implements real->complex FFTs of power-of-two sizes only. Note 53 * that only the first half of the output signal is returned (the 54 * complex conjugates half is omitted), so the "complex" arrays need 55 * room for size/2+1 elements. 56 * 57 * The "interleaved" functions use the format sometimes called CCS -- 58 * size/2+1 real+imaginary pairs. So, the array elements at indices 1 59 * and size+1 will always be zero (since the signal is real). 60 * 61 * All pointer arguments must point to valid data. A NullArgument 62 * exception is thrown if any argument is NULL. 63 * 64 * Neither forward nor inverse transform is scaled. 65 * 66 * This class is reentrant but not thread safe: use a separate 67 * instance per thread, or use a mutex. 68 */ 69 class FFT 70 { 71 public: 72 enum Exception { 73 NullArgument, InvalidSize, InvalidImplementation, InternalError 74 }; 75 76 FFT(int size, int debugLevel = 0); // may throw InvalidSize 77 ~FFT(); 78 79 int getSize() const; 80 81 void forward(const double *BQ_R__ realIn, double *BQ_R__ realOut, double *BQ_R__ imagOut); 82 void forwardInterleaved(const double *BQ_R__ realIn, double *BQ_R__ complexOut); 83 void forwardPolar(const double *BQ_R__ realIn, double *BQ_R__ magOut, double *BQ_R__ phaseOut); 84 void forwardMagnitude(const double *BQ_R__ realIn, double *BQ_R__ magOut); 85 86 void forward(const float *BQ_R__ realIn, float *BQ_R__ realOut, float *BQ_R__ imagOut); 87 void forwardInterleaved(const float *BQ_R__ realIn, float *BQ_R__ complexOut); 88 void forwardPolar(const float *BQ_R__ realIn, float *BQ_R__ magOut, float *BQ_R__ phaseOut); 89 void forwardMagnitude(const float *BQ_R__ realIn, float *BQ_R__ magOut); 90 91 void inverse(const double *BQ_R__ realIn, const double *BQ_R__ imagIn, double *BQ_R__ realOut); 92 void inverseInterleaved(const double *BQ_R__ complexIn, double *BQ_R__ realOut); 93 void inversePolar(const double *BQ_R__ magIn, const double *BQ_R__ phaseIn, double *BQ_R__ realOut); 94 void inverseCepstral(const double *BQ_R__ magIn, double *BQ_R__ cepOut); 95 96 void inverse(const float *BQ_R__ realIn, const float *BQ_R__ imagIn, float *BQ_R__ realOut); 97 void inverseInterleaved(const float *BQ_R__ complexIn, float *BQ_R__ realOut); 98 void inversePolar(const float *BQ_R__ magIn, const float *BQ_R__ phaseIn, float *BQ_R__ realOut); 99 void inverseCepstral(const float *BQ_R__ magIn, float *BQ_R__ cepOut); 100 101 // Calling one or both of these is optional -- if neither is 102 // called, the first call to a forward or inverse method will call 103 // init(). You only need call these if you don't want to risk 104 // expensive allocations etc happening in forward or inverse. 105 void initFloat(); 106 void initDouble(); 107 108 enum Precision { 109 SinglePrecision = 0x1, 110 DoublePrecision = 0x2 111 }; 112 typedef int Precisions; 113 114 /** 115 * Return the OR of all precisions supported by this 116 * implementation. All of the functions (float and double) are 117 * available regardless of the supported implementations, but they 118 * will be calculated at the proper precision only if it is 119 * available. (So float functions will be calculated using doubles 120 * and then truncated if single-precision is unavailable, and 121 * double functions will use single-precision arithmetic if double 122 * is unavailable.) 123 */ 124 Precisions getSupportedPrecisions() const; 125 126 static std::set<std::string> getImplementations(); 127 static std::string getDefaultImplementation(); 128 static void setDefaultImplementation(std::string); 129 130 #ifdef FFT_MEASUREMENT 131 static 132 #ifdef FFT_MEASUREMENT_RETURN_RESULT_TEXT 133 std::string 134 #else 135 void 136 #endif 137 tune(); 138 #endif 139 140 protected: 141 FFTImpl *d; 142 143 private: 144 FFT(const FFT &); // not provided 145 FFT &operator=(const FFT &); // not provided 146 }; 147 148 } 149 150 #endif 151 152