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