Mercurial > hg > vamp-plugin-sdk
comparison src/vamp-hostsdk/PluginInputDomainAdapter.cpp @ 317:5cb298435765
Add support for changing window shape in PluginInputDomainAdapter
author | Chris Cannam |
---|---|
date | Tue, 21 Jun 2011 15:40:50 +0100 |
parents | 5940dd0a399f |
children | 7920b9519fd9 |
comparison
equal
deleted
inserted
replaced
316:c10fb3b3d029 | 317:5cb298435765 |
---|---|
38 */ | 38 */ |
39 | 39 |
40 #include <vamp-hostsdk/PluginInputDomainAdapter.h> | 40 #include <vamp-hostsdk/PluginInputDomainAdapter.h> |
41 | 41 |
42 #include <cmath> | 42 #include <cmath> |
43 | |
44 #include "Window.h" | |
43 | 45 |
44 | 46 |
45 /** | 47 /** |
46 * If you want to compile using FFTW instead of the built-in FFT | 48 * If you want to compile using FFTW instead of the built-in FFT |
47 * implementation for the PluginInputDomainAdapter, define HAVE_FFTW3 | 49 * implementation for the PluginInputDomainAdapter, define HAVE_FFTW3 |
93 void setProcessTimestampMethod(ProcessTimestampMethod m); | 95 void setProcessTimestampMethod(ProcessTimestampMethod m); |
94 ProcessTimestampMethod getProcessTimestampMethod() const; | 96 ProcessTimestampMethod getProcessTimestampMethod() const; |
95 | 97 |
96 RealTime getTimestampAdjustment() const; | 98 RealTime getTimestampAdjustment() const; |
97 | 99 |
100 WindowType getWindowType() const; | |
101 void setWindowType(WindowType type); | |
102 | |
98 protected: | 103 protected: |
99 Plugin *m_plugin; | 104 Plugin *m_plugin; |
100 float m_inputSampleRate; | 105 float m_inputSampleRate; |
101 int m_channels; | 106 int m_channels; |
102 int m_stepSize; | 107 int m_stepSize; |
103 int m_blockSize; | 108 int m_blockSize; |
104 float **m_freqbuf; | 109 float **m_freqbuf; |
105 | 110 |
106 double *m_ri; | 111 double *m_ri; |
107 double *m_window; | 112 |
113 WindowType m_windowType; | |
114 Window<double> *m_window; | |
108 | 115 |
109 ProcessTimestampMethod m_method; | 116 ProcessTimestampMethod m_method; |
110 int m_processCount; | 117 int m_processCount; |
111 float **m_shiftBuffers; | 118 float **m_shiftBuffers; |
112 | 119 |
122 | 129 |
123 FeatureSet processShiftingTimestamp(const float *const *inputBuffers, RealTime timestamp); | 130 FeatureSet processShiftingTimestamp(const float *const *inputBuffers, RealTime timestamp); |
124 FeatureSet processShiftingData(const float *const *inputBuffers, RealTime timestamp); | 131 FeatureSet processShiftingData(const float *const *inputBuffers, RealTime timestamp); |
125 | 132 |
126 size_t makeBlockSizeAcceptable(size_t) const; | 133 size_t makeBlockSizeAcceptable(size_t) const; |
134 | |
135 Window<double>::WindowType convertType(WindowType t) const; | |
127 }; | 136 }; |
128 | 137 |
129 PluginInputDomainAdapter::PluginInputDomainAdapter(Plugin *plugin) : | 138 PluginInputDomainAdapter::PluginInputDomainAdapter(Plugin *plugin) : |
130 PluginWrapper(plugin) | 139 PluginWrapper(plugin) |
131 { | 140 { |
187 | 196 |
188 RealTime | 197 RealTime |
189 PluginInputDomainAdapter::getTimestampAdjustment() const | 198 PluginInputDomainAdapter::getTimestampAdjustment() const |
190 { | 199 { |
191 return m_impl->getTimestampAdjustment(); | 200 return m_impl->getTimestampAdjustment(); |
201 } | |
202 | |
203 PluginInputDomainAdapter::WindowType | |
204 PluginInputDomainAdapter::getWindowType() const | |
205 { | |
206 return m_impl->getWindowType(); | |
207 } | |
208 | |
209 void | |
210 PluginInputDomainAdapter::setWindowType(WindowType w) | |
211 { | |
212 m_impl->setWindowType(w); | |
192 } | 213 } |
193 | 214 |
194 | 215 |
195 PluginInputDomainAdapter::Impl::Impl(Plugin *plugin, float inputSampleRate) : | 216 PluginInputDomainAdapter::Impl::Impl(Plugin *plugin, float inputSampleRate) : |
196 m_plugin(plugin), | 217 m_plugin(plugin), |
198 m_channels(0), | 219 m_channels(0), |
199 m_stepSize(0), | 220 m_stepSize(0), |
200 m_blockSize(0), | 221 m_blockSize(0), |
201 m_freqbuf(0), | 222 m_freqbuf(0), |
202 m_ri(0), | 223 m_ri(0), |
224 m_windowType(HanningWindow), | |
203 m_window(0), | 225 m_window(0), |
204 m_method(ShiftTimestamp), | 226 m_method(ShiftTimestamp), |
205 m_processCount(0), | 227 m_processCount(0), |
206 m_shiftBuffers(0), | 228 m_shiftBuffers(0), |
207 #ifdef HAVE_FFTW3 | 229 #ifdef HAVE_FFTW3 |
240 #else | 262 #else |
241 delete[] m_ri; | 263 delete[] m_ri; |
242 delete[] m_ro; | 264 delete[] m_ro; |
243 delete[] m_io; | 265 delete[] m_io; |
244 #endif | 266 #endif |
245 delete[] m_window; | 267 |
268 delete m_window; | |
246 } | 269 } |
247 } | 270 } |
248 | 271 |
249 // for some visual studii apparently | 272 // for some visual studii apparently |
250 #ifndef M_PI | 273 #ifndef M_PI |
288 #else | 311 #else |
289 delete[] m_ri; | 312 delete[] m_ri; |
290 delete[] m_ro; | 313 delete[] m_ro; |
291 delete[] m_io; | 314 delete[] m_io; |
292 #endif | 315 #endif |
293 delete[] m_window; | 316 delete m_window; |
294 } | 317 } |
295 | 318 |
296 m_stepSize = int(stepSize); | 319 m_stepSize = int(stepSize); |
297 m_blockSize = int(blockSize); | 320 m_blockSize = int(blockSize); |
298 m_channels = int(channels); | 321 m_channels = int(channels); |
299 | 322 |
300 m_freqbuf = new float *[m_channels]; | 323 m_freqbuf = new float *[m_channels]; |
301 for (int c = 0; c < m_channels; ++c) { | 324 for (int c = 0; c < m_channels; ++c) { |
302 m_freqbuf[c] = new float[m_blockSize + 2]; | 325 m_freqbuf[c] = new float[m_blockSize + 2]; |
303 } | 326 } |
304 m_window = new double[m_blockSize]; | 327 |
305 | 328 m_window = new Window<double>(convertType(m_windowType), m_blockSize); |
306 for (int i = 0; i < m_blockSize; ++i) { | |
307 // Hanning window | |
308 m_window[i] = (0.50 - 0.50 * cos((2.0 * M_PI * i) / m_blockSize)); | |
309 } | |
310 | 329 |
311 #ifdef HAVE_FFTW3 | 330 #ifdef HAVE_FFTW3 |
312 m_ri = (double *)fftw_malloc(blockSize * sizeof(double)); | 331 m_ri = (double *)fftw_malloc(blockSize * sizeof(double)); |
313 m_cbuf = (fftw_complex *)fftw_malloc((blockSize/2 + 1) * sizeof(fftw_complex)); | 332 m_cbuf = (fftw_complex *)fftw_malloc((blockSize/2 + 1) * sizeof(fftw_complex)); |
314 m_plan = fftw_plan_dft_r2c_1d(blockSize, m_ri, m_cbuf, FFTW_MEASURE); | 333 m_plan = fftw_plan_dft_r2c_1d(blockSize, m_ri, m_cbuf, FFTW_MEASURE); |
424 PluginInputDomainAdapter::Impl::getProcessTimestampMethod() const | 443 PluginInputDomainAdapter::Impl::getProcessTimestampMethod() const |
425 { | 444 { |
426 return m_method; | 445 return m_method; |
427 } | 446 } |
428 | 447 |
448 void | |
449 PluginInputDomainAdapter::Impl::setWindowType(WindowType t) | |
450 { | |
451 if (m_windowType == t) return; | |
452 m_windowType = t; | |
453 if (m_window) { | |
454 delete m_window; | |
455 m_window = new Window<double>(convertType(m_windowType), m_blockSize); | |
456 } | |
457 } | |
458 | |
459 PluginInputDomainAdapter::WindowType | |
460 PluginInputDomainAdapter::Impl::getWindowType() const | |
461 { | |
462 return m_windowType; | |
463 } | |
464 | |
465 Window<double>::WindowType | |
466 PluginInputDomainAdapter::Impl::convertType(WindowType t) const | |
467 { | |
468 switch (t) { | |
469 case RectangularWindow: | |
470 return Window<double>::RectangularWindow; | |
471 case BartlettWindow: | |
472 return Window<double>::BartlettWindow; | |
473 case HammingWindow: | |
474 return Window<double>::HammingWindow; | |
475 case HanningWindow: | |
476 return Window<double>::HanningWindow; | |
477 case BlackmanWindow: | |
478 return Window<double>::BlackmanWindow; | |
479 case NuttallWindow: | |
480 return Window<double>::NuttallWindow; | |
481 case BlackmanHarrisWindow: | |
482 return Window<double>::BlackmanHarrisWindow; | |
483 } | |
484 } | |
485 | |
429 Plugin::FeatureSet | 486 Plugin::FeatureSet |
430 PluginInputDomainAdapter::Impl::process(const float *const *inputBuffers, | 487 PluginInputDomainAdapter::Impl::process(const float *const *inputBuffers, |
431 RealTime timestamp) | 488 RealTime timestamp) |
432 { | 489 { |
433 if (m_plugin->getInputDomain() == TimeDomain) { | 490 if (m_plugin->getInputDomain() == TimeDomain) { |
449 timestamp = timestamp + getTimestampAdjustment(); | 506 timestamp = timestamp + getTimestampAdjustment(); |
450 } | 507 } |
451 | 508 |
452 for (int c = 0; c < m_channels; ++c) { | 509 for (int c = 0; c < m_channels; ++c) { |
453 | 510 |
454 for (int i = 0; i < m_blockSize; ++i) { | 511 m_window->cut(inputBuffers[c], m_ri); |
455 m_ri[i] = double(inputBuffers[c][i]) * m_window[i]; | |
456 } | |
457 | 512 |
458 for (int i = 0; i < m_blockSize/2; ++i) { | 513 for (int i = 0; i < m_blockSize/2; ++i) { |
459 // FFT shift | 514 // FFT shift |
460 double value = m_ri[i]; | 515 double value = m_ri[i]; |
461 m_ri[i] = m_ri[i + m_blockSize/2]; | 516 m_ri[i] = m_ri[i + m_blockSize/2]; |
509 } | 564 } |
510 } | 565 } |
511 | 566 |
512 for (int c = 0; c < m_channels; ++c) { | 567 for (int c = 0; c < m_channels; ++c) { |
513 | 568 |
514 for (int i = 0; i < m_blockSize; ++i) { | 569 m_window->cut(m_shiftBuffers[c], m_ri); |
515 m_ri[i] = double(m_shiftBuffers[c][i]) * m_window[i]; | |
516 } | |
517 | 570 |
518 for (int i = 0; i < m_blockSize/2; ++i) { | 571 for (int i = 0; i < m_blockSize/2; ++i) { |
519 // FFT shift | 572 // FFT shift |
520 double value = m_ri[i]; | 573 double value = m_ri[i]; |
521 m_ri[i] = m_ri[i + m_blockSize/2]; | 574 m_ri[i] = m_ri[i + m_blockSize/2]; |