comparison dsp/transforms/FFT.cpp @ 211:a41bea655151 msvc

Rename FFT back again, now we have our own project
author Chris Cannam
date Mon, 05 Feb 2018 17:40:13 +0000
parents
children 0307327a3869
comparison
equal deleted inserted replaced
210:cf62f73766e9 211:a41bea655151
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2
3 /*
4 QM DSP Library
5
6 Centre for Digital Music, Queen Mary, University of London.
7 */
8
9 #include "FFT.h"
10
11 #include "maths/MathUtilities.h"
12
13 #include "kiss_fft.h"
14 #include "kiss_fftr.h"
15
16 #include <cmath>
17
18 #include <iostream>
19
20 #include <stdexcept>
21
22 class FFT::D
23 {
24 public:
25 D(int n) : m_n(n) {
26 m_planf = kiss_fft_alloc(m_n, 0, NULL, NULL);
27 m_plani = kiss_fft_alloc(m_n, 1, NULL, NULL);
28 m_kin = new kiss_fft_cpx[m_n];
29 m_kout = new kiss_fft_cpx[m_n];
30 }
31
32 ~D() {
33 kiss_fft_free(m_planf);
34 kiss_fft_free(m_plani);
35 delete[] m_kin;
36 delete[] m_kout;
37 }
38
39 void process(bool inverse,
40 const double *ri,
41 const double *ii,
42 double *ro,
43 double *io) {
44
45 for (int i = 0; i < m_n; ++i) {
46 m_kin[i].r = ri[i];
47 m_kin[i].i = (ii ? ii[i] : 0.0);
48 }
49
50 if (!inverse) {
51
52 kiss_fft(m_planf, m_kin, m_kout);
53
54 for (int i = 0; i < m_n; ++i) {
55 ro[i] = m_kout[i].r;
56 io[i] = m_kout[i].i;
57 }
58
59 } else {
60
61 kiss_fft(m_plani, m_kin, m_kout);
62
63 double scale = 1.0 / m_n;
64
65 for (int i = 0; i < m_n; ++i) {
66 ro[i] = m_kout[i].r * scale;
67 io[i] = m_kout[i].i * scale;
68 }
69 }
70 }
71
72 private:
73 int m_n;
74 kiss_fft_cfg m_planf;
75 kiss_fft_cfg m_plani;
76 kiss_fft_cpx *m_kin;
77 kiss_fft_cpx *m_kout;
78 };
79
80 FFT::FFT(int n) :
81 m_d(new D(n))
82 {
83 }
84
85 FFT::~FFT()
86 {
87 delete m_d;
88 }
89
90 void
91 FFT::process(bool inverse,
92 const double *p_lpRealIn, const double *p_lpImagIn,
93 double *p_lpRealOut, double *p_lpImagOut)
94 {
95 m_d->process(inverse,
96 p_lpRealIn, p_lpImagIn,
97 p_lpRealOut, p_lpImagOut);
98 }
99
100 class FFTReal::D
101 {
102 public:
103 D(int n) : m_n(n) {
104 if (n % 2) {
105 throw std::invalid_argument
106 ("nsamples must be even in FFTReal constructor");
107 }
108 m_planf = kiss_fftr_alloc(m_n, 0, NULL, NULL);
109 m_plani = kiss_fftr_alloc(m_n, 1, NULL, NULL);
110 m_c = new kiss_fft_cpx[m_n];
111 }
112
113 ~D() {
114 kiss_fftr_free(m_planf);
115 kiss_fftr_free(m_plani);
116 delete[] m_c;
117 }
118
119 void forward(const double *ri, double *ro, double *io) {
120
121 kiss_fftr(m_planf, ri, m_c);
122
123 for (int i = 0; i <= m_n/2; ++i) {
124 ro[i] = m_c[i].r;
125 io[i] = m_c[i].i;
126 }
127
128 for (int i = 0; i + 1 < m_n/2; ++i) {
129 ro[m_n - i - 1] = ro[i + 1];
130 io[m_n - i - 1] = -io[i + 1];
131 }
132 }
133
134 void forwardMagnitude(const double *ri, double *mo) {
135
136 double *io = new double[m_n];
137
138 forward(ri, mo, io);
139
140 for (int i = 0; i < m_n; ++i) {
141 mo[i] = sqrt(mo[i] * mo[i] + io[i] * io[i]);
142 }
143
144 delete[] io;
145 }
146
147 void inverse(const double *ri, const double *ii, double *ro) {
148
149 // kiss_fftr.h says
150 // "input freqdata has nfft/2+1 complex points"
151
152 for (int i = 0; i < m_n/2 + 1; ++i) {
153 m_c[i].r = ri[i];
154 m_c[i].i = ii[i];
155 }
156
157 kiss_fftri(m_plani, m_c, ro);
158
159 double scale = 1.0 / m_n;
160
161 for (int i = 0; i < m_n; ++i) {
162 ro[i] *= scale;
163 }
164 }
165
166 private:
167 int m_n;
168 kiss_fftr_cfg m_planf;
169 kiss_fftr_cfg m_plani;
170 kiss_fft_cpx *m_c;
171 };
172
173 FFTReal::FFTReal(int n) :
174 m_d(new D(n))
175 {
176 }
177
178 FFTReal::~FFTReal()
179 {
180 delete m_d;
181 }
182
183 void
184 FFTReal::forward(const double *ri, double *ro, double *io)
185 {
186 m_d->forward(ri, ro, io);
187 }
188
189 void
190 FFTReal::forwardMagnitude(const double *ri, double *mo)
191 {
192 m_d->forwardMagnitude(ri, mo);
193 }
194
195 void
196 FFTReal::inverse(const double *ri, const double *ii, double *ro)
197 {
198 m_d->inverse(ri, ii, ro);
199 }
200
201
202