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