1#ifndef __FFT_HPP__
2
3/*=============================================================================
4|
5| NAME
6|
7| FFT.hpp
8|
9| DESCRIPTION
10|
11| This program does an in-place one dimensional complex discrete
12| Fourier transform. It uses an FFT algorithm for a number of
13| input points which is a power of two. It works on both single
14| precision and double precision floating point numbers.
15|
16| AUTHOR
17|
18| Created: Sean O'Connor 19 November 2005
19|
20| LEGAL
21|
22| FFT Version 1.6 - An FFT utility library in C++.
23| Copyright (C) 2005-2024 by Sean Erik O'Connor. All Rights Reserved.
24|
25| This program is free software: you can redistribute it and/or modify
26| it under the terms of the GNU General Public License as published by
27| the Free Software Foundation, either version 3 of the License, or
28| (at your option) any later version.
29|
30| This program is distributed in the hope that it will be useful,
31| but WITHOUT ANY WARRANTY; without even the implied warranty of
32| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33| GNU General Public License for more details.
34|
35| You should have received a copy of the GNU General Public License
36| along with this program. If not, see <http://www.gnu.org/licenses/>.
37|
38| The author's address is seanerikoconnor!AT!gmail!DOT!com
39| with !DOT! replaced by . and the !AT! replaced by @
40|
41+============================================================================*/
42
43/*
44 * We must set the size of the sine and cosine table used in the FFT.
45 * The table is called starting_multiplier.
46 *
47 * Suppose MAX is the largest number of points we would ever transform. We set
48 *
49 * MAX_TABLE_SIZE = LOG ( MAX ) - 1
50 * 2
51 *
52 * to be the size of the table. This table can now be used by the FFT for
53 * any number of points from 2 up to MAX.
54 *
55 * For example, if MAX_TABLE_SIZE = 14, then we can transform anywhere from
56 * 2 to 2 ^ 15 = 32,768 points, using the same sine and cosine table.
57 *
58 */
59const int MAX_TABLE_SIZE = 13 ;
60
61
62
63// Derive the FFT class from an STL vector with a floating point type to be specified.
64// Thus we get the vector's data manipulation attributes and
65// we can substitute FFT objects into an existing software
66// framework which uses vector objects in containers.
67// But extend the class by adding a Fourier Transform capability.
68//
69template <typename FloatType>
70class FastFourierTransform
71 : public vector< complex<FloatType> > // Need spaces between angle brackets to satisfy compiler.
72{
73 public:
74 // Default constructor.
75 FastFourierTransform() ;
76
77 // Destructor.
78 ~FastFourierTransform() ;
79
80 // Copy constructor ;
81 FastFourierTransform( const FastFourierTransform & transform ) ;
82
83 // Assignment operator.
84 FastFourierTransform & operator=( const FastFourierTransform & transform ) ;
85
86 // Fast Fourier transform capability.
87 void fft( bool direction = true ) ;
88
89 // Maybe these should be private to be safe!
90 protected:
91 bool direction ;
92
93 private:
94 // Table of sines and cosines whose values are created the first
95 // time any object calls the fft() member function and which are
96 // shared among all subsequent objects.
97 static vector< complex<FloatType> > starting_multiplier ;
98 static bool called_already ;
99 static const FloatType PI ;
100
101 // Helper function used by FFT member function only.
102 static int reverse_bits( int n, int num_bits ) ;
103} ;
104
105
106/*=============================================================================
107|
108| NAME
109|
110| FastFourierTransformException
111|
112| DESCRIPTION
113|
114| Helper class for recording data thrown by FastFourierTransform.
115|
116| BUGS
117|
118+============================================================================*/
119
120class FastFourierTransformException : public runtime_error
121{
122 public:
123 // This form will be used most often in a throw.
124 FastFourierTransformException( const string & description )
125 : runtime_error( description )
126 {
127 } ;
128
129 // Throw with no error message.
130 FastFourierTransformException()
131 : runtime_error( "FFT exception: " )
132 {
133 } ;
134
135} ; // end class FastFourierTransformException
136
137
138/*==============================================================================
139| Static Class Variables Initialization |
140==============================================================================*/
141
142// Static class variables must be initialized outside the class.
143
144template <typename FloatType> // Not just a class, but a template class with a parameterized type.
145vector< complex<FloatType> > // The data type of this static variable.
146FastFourierTransform<FloatType>::starting_multiplier(MAX_TABLE_SIZE) ; // Declare the variable as a member of class having a
147 // parameterized type.
148 // Initialize the size to the maximum, and default to zeros.
149template <typename FloatType> bool FastFourierTransform<FloatType>::called_already = false ;
150template <typename FloatType> const FloatType FastFourierTransform<FloatType>::PI = static_cast<FloatType>(3.14159265358979323846264338327950288419716939) ;
151#endif // __FFT_HPP__