Mercurial > hg > qm-dsp
comparison dsp/transforms/FFT.cpp @ 114:f6ccde089491 pvoc
Tidy real-to-complex FFT -- forward and inverse have different arguments, so make them separate functions; document
author | Chris Cannam |
---|---|
date | Wed, 02 Oct 2013 15:04:38 +0100 |
parents | e5907ae6de17 |
children | 6ec45e85ed81 |
comparison
equal
deleted
inserted
replaced
113:3cb359d043f0 | 114:f6ccde089491 |
---|---|
13 | 13 |
14 #include <cmath> | 14 #include <cmath> |
15 | 15 |
16 #include <iostream> | 16 #include <iostream> |
17 | 17 |
18 FFT::FFT(unsigned int n) : | 18 FFT::FFT(int n) : |
19 m_n(n), | 19 m_n(n) |
20 m_private(0) | |
21 { | 20 { |
22 if( !MathUtilities::isPowerOfTwo(m_n) ) | 21 if( !MathUtilities::isPowerOfTwo(m_n) ) |
23 { | 22 { |
24 std::cerr << "ERROR: FFT: Non-power-of-two FFT size " | 23 std::cerr << "ERROR: FFT: Non-power-of-two FFT size " |
25 << m_n << " not supported in this implementation" | 24 << m_n << " not supported in this implementation" |
31 FFT::~FFT() | 30 FFT::~FFT() |
32 { | 31 { |
33 | 32 |
34 } | 33 } |
35 | 34 |
36 FFTReal::FFTReal(unsigned int n) : | 35 FFTReal::FFTReal(int n) : |
37 m_n(n), | 36 m_n(n), |
38 m_private(0) | 37 m_fft(new FFT(n)), |
39 { | 38 m_r(new double[n]), |
40 m_private = new FFT(m_n); | 39 m_i(new double[n]), |
40 m_discard(new double[n]) | |
41 { | |
42 for (int i = 0; i < n; ++i) { | |
43 m_r[i] = 0; | |
44 m_i[i] = 0; | |
45 m_discard[i] = 0; | |
46 } | |
41 } | 47 } |
42 | 48 |
43 FFTReal::~FFTReal() | 49 FFTReal::~FFTReal() |
44 { | 50 { |
45 delete (FFT *)m_private; | 51 delete m_fft; |
52 delete[] m_discard; | |
53 delete[] m_r; | |
54 delete[] m_i; | |
46 } | 55 } |
47 | 56 |
48 void | 57 void |
49 FFTReal::process(bool inverse, | 58 FFTReal::forward(const double *realIn, |
50 const double *realIn, | |
51 double *realOut, double *imagOut) | 59 double *realOut, double *imagOut) |
52 { | 60 { |
53 ((FFT *)m_private)->process(inverse, realIn, 0, realOut, imagOut); | 61 m_fft->process(false, realIn, 0, realOut, imagOut); |
54 } | 62 } |
55 | 63 |
56 static unsigned int numberOfBitsNeeded(unsigned int p_nSamples) | 64 void |
65 FFTReal::inverse(const double *realIn, const double *imagIn, | |
66 double *realOut) | |
67 { | |
68 for (int i = 0; i < m_n/2 + 1; ++i) { | |
69 m_r[i] = realIn[i]; | |
70 m_i[i] = imagIn[i]; | |
71 if (i > 0 && i < m_n/2) { | |
72 m_r[m_n - i] = realIn[i]; | |
73 m_i[m_n - i] = -imagIn[i]; | |
74 } | |
75 } | |
76 m_fft->process(true, m_r, m_i, realOut, m_discard); | |
77 } | |
78 | |
79 static int numberOfBitsNeeded(int p_nSamples) | |
57 { | 80 { |
58 int i; | 81 int i; |
59 | 82 |
60 if( p_nSamples < 2 ) | 83 if( p_nSamples < 2 ) |
61 { | 84 { |
66 { | 89 { |
67 if( p_nSamples & (1 << i) ) return i; | 90 if( p_nSamples & (1 << i) ) return i; |
68 } | 91 } |
69 } | 92 } |
70 | 93 |
71 static unsigned int reverseBits(unsigned int p_nIndex, unsigned int p_nBits) | 94 static int reverseBits(int p_nIndex, int p_nBits) |
72 { | 95 { |
73 unsigned int i, rev; | 96 int i, rev; |
74 | 97 |
75 for(i=rev=0; i < p_nBits; i++) | 98 for(i=rev=0; i < p_nBits; i++) |
76 { | 99 { |
77 rev = (rev << 1) | (p_nIndex & 1); | 100 rev = (rev << 1) | (p_nIndex & 1); |
78 p_nIndex >>= 1; | 101 p_nIndex >>= 1; |
88 { | 111 { |
89 if (!p_lpRealIn || !p_lpRealOut || !p_lpImagOut) return; | 112 if (!p_lpRealIn || !p_lpRealOut || !p_lpImagOut) return; |
90 | 113 |
91 // std::cerr << "FFT::process(" << m_n << "," << p_bInverseTransform << ")" << std::endl; | 114 // std::cerr << "FFT::process(" << m_n << "," << p_bInverseTransform << ")" << std::endl; |
92 | 115 |
93 unsigned int NumBits; | 116 int NumBits; |
94 unsigned int i, j, k, n; | 117 int i, j, k, n; |
95 unsigned int BlockSize, BlockEnd; | 118 int BlockSize, BlockEnd; |
96 | 119 |
97 double angle_numerator = 2.0 * M_PI; | 120 double angle_numerator = 2.0 * M_PI; |
98 double tr, ti; | 121 double tr, ti; |
99 | 122 |
100 if( !MathUtilities::isPowerOfTwo(m_n) ) | 123 if( !MathUtilities::isPowerOfTwo(m_n) ) |
106 } | 129 } |
107 | 130 |
108 if( p_bInverseTransform ) angle_numerator = -angle_numerator; | 131 if( p_bInverseTransform ) angle_numerator = -angle_numerator; |
109 | 132 |
110 NumBits = numberOfBitsNeeded ( m_n ); | 133 NumBits = numberOfBitsNeeded ( m_n ); |
134 | |
111 | 135 |
112 | 136 |
113 for( i=0; i < m_n; i++ ) | 137 for( i=0; i < m_n; i++ ) |
114 { | 138 { |
115 j = reverseBits ( i, NumBits ); | 139 j = reverseBits ( i, NumBits ); |