Mercurial > hg > vamp-plugin-sdk
comparison src/vamp-sdk/FFT.cpp @ 446:d132b92ec65d vampipe
Add FFTComplex class by analogy to FFTReal
author | Chris Cannam |
---|---|
date | Thu, 18 Aug 2016 16:04:25 +0100 |
parents | 7f7a10bcaff1 |
children | 90571dcc371a |
comparison
equal
deleted
inserted
replaced
445:7f7a10bcaff1 | 446:d132b92ec65d |
---|---|
106 Kiss::kiss_fft_free(c); | 106 Kiss::kiss_fft_free(c); |
107 delete[] in; | 107 delete[] in; |
108 delete[] out; | 108 delete[] out; |
109 } | 109 } |
110 | 110 |
111 class FFTReal::D | 111 class FFTComplex::D |
112 { | 112 { |
113 public: | 113 public: |
114 | |
115 D(int n) : | 114 D(int n) : |
116 m_n(n), | 115 m_n(n), |
117 m_cf(Kiss::kiss_fftr_alloc(n, false, 0, 0)), | 116 m_fconf(Kiss::kiss_fft_alloc(n, false, 0, 0)), |
118 m_ci(Kiss::kiss_fftr_alloc(n, true, 0, 0)), | 117 m_iconf(Kiss::kiss_fft_alloc(n, true, 0, 0)), |
118 m_ci(new Kiss::kiss_fft_cpx[m_n]), | |
119 m_co(new Kiss::kiss_fft_cpx[m_n]) { } | |
120 | |
121 ~D() { | |
122 Kiss::kiss_fftr_free(m_fconf); | |
123 Kiss::kiss_fftr_free(m_iconf); | |
124 delete[] m_ci; | |
125 delete[] m_co; | |
126 } | |
127 | |
128 void forward(const double *ci, double *co) { | |
129 for (int i = 0; i < m_n; ++i) { | |
130 m_ci[i].r = ci[i*2]; | |
131 m_ci[i].i = ci[i*2+1]; | |
132 } | |
133 Kiss::kiss_fft(m_fconf, m_ci, m_co); | |
134 for (int i = 0; i < m_n; ++i) { | |
135 co[i*2] = m_co[i].r; | |
136 co[i*2+1] = m_co[i].i; | |
137 } | |
138 } | |
139 | |
140 void inverse(const double *ci, double *co) { | |
141 for (int i = 0; i < m_n; ++i) { | |
142 m_ci[i].r = ci[i*2]; | |
143 m_ci[i].i = ci[i*2+1]; | |
144 } | |
145 Kiss::kiss_fft(m_iconf, m_ci, m_co); | |
146 double scale = 1.0 / double(m_n); | |
147 for (int i = 0; i < m_n; ++i) { | |
148 co[i*2] = m_co[i].r * scale; | |
149 co[i*2+1] = m_co[i].i * scale; | |
150 } | |
151 } | |
152 | |
153 private: | |
154 int m_n; | |
155 Kiss::kiss_fft_cfg m_fconf; | |
156 Kiss::kiss_fft_cfg m_iconf; | |
157 Kiss::kiss_fft_cpx *m_ci; | |
158 Kiss::kiss_fft_cpx *m_co; | |
159 }; | |
160 | |
161 FFTComplex::FFTComplex(unsigned int n) : | |
162 m_d(new D(n)) | |
163 { | |
164 } | |
165 | |
166 FFTComplex::~FFTComplex() | |
167 { | |
168 delete m_d; | |
169 } | |
170 | |
171 void | |
172 FFTComplex::forward(const double *ci, double *co) | |
173 { | |
174 m_d->forward(ci, co); | |
175 } | |
176 | |
177 void | |
178 FFTComplex::inverse(const double *ci, double *co) | |
179 { | |
180 m_d->inverse(ci, co); | |
181 } | |
182 | |
183 class FFTReal::D | |
184 { | |
185 public: | |
186 D(int n) : | |
187 m_n(n), | |
188 m_fconf(Kiss::kiss_fftr_alloc(n, false, 0, 0)), | |
189 m_iconf(Kiss::kiss_fftr_alloc(n, true, 0, 0)), | |
119 m_ri(new Kiss::kiss_fft_scalar[m_n]), | 190 m_ri(new Kiss::kiss_fft_scalar[m_n]), |
120 m_ro(new Kiss::kiss_fft_scalar[m_n]), | 191 m_ro(new Kiss::kiss_fft_scalar[m_n]), |
121 m_freq(new Kiss::kiss_fft_cpx[n/2+1]) { } | 192 m_freq(new Kiss::kiss_fft_cpx[n/2+1]) { } |
122 | 193 |
123 ~D() { | 194 ~D() { |
124 Kiss::kiss_fftr_free(m_cf); | 195 Kiss::kiss_fftr_free(m_fconf); |
125 Kiss::kiss_fftr_free(m_ci); | 196 Kiss::kiss_fftr_free(m_iconf); |
126 delete[] m_ri; | 197 delete[] m_ri; |
127 delete[] m_ro; | 198 delete[] m_ro; |
128 delete[] m_freq; | 199 delete[] m_freq; |
129 } | 200 } |
130 | 201 |
131 void forward(const double *ri, double *co) { | 202 void forward(const double *ri, double *co) { |
132 for (int i = 0; i < m_n; ++i) { | 203 for (int i = 0; i < m_n; ++i) { |
133 // in case kiss_fft_scalar is float | 204 // in case kiss_fft_scalar is float |
134 m_ri[i] = ri[i]; | 205 m_ri[i] = ri[i]; |
135 } | 206 } |
136 Kiss::kiss_fftr(m_cf, m_ri, m_freq); | 207 Kiss::kiss_fftr(m_fconf, m_ri, m_freq); |
137 int hs = m_n/2 + 1; | 208 int hs = m_n/2 + 1; |
138 for (int i = 0; i < hs; ++i) { | 209 for (int i = 0; i < hs; ++i) { |
139 co[i*2] = m_freq[i].r; | 210 co[i*2] = m_freq[i].r; |
140 co[i*2+1] = m_freq[i].i; | 211 co[i*2+1] = m_freq[i].i; |
141 } | 212 } |
145 int hs = m_n/2 + 1; | 216 int hs = m_n/2 + 1; |
146 for (int i = 0; i < hs; ++i) { | 217 for (int i = 0; i < hs; ++i) { |
147 m_freq[i].r = ci[i*2]; | 218 m_freq[i].r = ci[i*2]; |
148 m_freq[i].i = ci[i*2+1]; | 219 m_freq[i].i = ci[i*2+1]; |
149 } | 220 } |
150 Kiss::kiss_fftri(m_ci, m_freq, m_ro); | 221 Kiss::kiss_fftri(m_iconf, m_freq, m_ro); |
151 double scale = 1.0 / double(m_n); | 222 double scale = 1.0 / double(m_n); |
152 for (int i = 0; i < m_n; ++i) { | 223 for (int i = 0; i < m_n; ++i) { |
153 ro[i] = m_ro[i] * scale; | 224 ro[i] = m_ro[i] * scale; |
154 } | 225 } |
155 } | 226 } |
156 | 227 |
157 private: | 228 private: |
158 int m_n; | 229 int m_n; |
159 Kiss::kiss_fftr_cfg m_cf; | 230 Kiss::kiss_fftr_cfg m_fconf; |
160 Kiss::kiss_fftr_cfg m_ci; | 231 Kiss::kiss_fftr_cfg m_iconf; |
161 Kiss::kiss_fft_scalar *m_ri; | 232 Kiss::kiss_fft_scalar *m_ri; |
162 Kiss::kiss_fft_scalar *m_ro; | 233 Kiss::kiss_fft_scalar *m_ro; |
163 Kiss::kiss_fft_cpx *m_freq; | 234 Kiss::kiss_fft_cpx *m_freq; |
164 }; | 235 }; |
165 | 236 |