annotate src/vamp-hostsdk/PluginInputDomainAdapter.cpp @ 435:27c3448df198 vampipe

Fix m_ri initialisation
author Chris Cannam
date Tue, 16 Aug 2016 16:37:57 +0100
parents e979a9c4ffb6
children 7bab0c5422f4
rev   line source
cannam@233 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
cannam@233 2
cannam@233 3 /*
cannam@233 4 Vamp
cannam@233 5
cannam@233 6 An API for audio analysis and feature extraction plugins.
cannam@233 7
cannam@233 8 Centre for Digital Music, Queen Mary, University of London.
cannam@290 9 Copyright 2006-2009 Chris Cannam and QMUL.
cannam@233 10
cannam@233 11 This file is based in part on Don Cross's public domain FFT
cannam@233 12 implementation.
cannam@233 13
cannam@233 14 Permission is hereby granted, free of charge, to any person
cannam@233 15 obtaining a copy of this software and associated documentation
cannam@233 16 files (the "Software"), to deal in the Software without
cannam@233 17 restriction, including without limitation the rights to use, copy,
cannam@233 18 modify, merge, publish, distribute, sublicense, and/or sell copies
cannam@233 19 of the Software, and to permit persons to whom the Software is
cannam@233 20 furnished to do so, subject to the following conditions:
cannam@233 21
cannam@233 22 The above copyright notice and this permission notice shall be
cannam@233 23 included in all copies or substantial portions of the Software.
cannam@233 24
cannam@233 25 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
cannam@233 26 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
cannam@233 27 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
cannam@233 28 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
cannam@233 29 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
cannam@233 30 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
cannam@233 31 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
cannam@233 32
cannam@233 33 Except as contained in this notice, the names of the Centre for
cannam@233 34 Digital Music; Queen Mary, University of London; and Chris Cannam
cannam@233 35 shall not be used in advertising or otherwise to promote the sale,
cannam@233 36 use or other dealings in this Software without prior written
cannam@233 37 authorization.
cannam@233 38 */
cannam@233 39
cannam@233 40 #include <vamp-hostsdk/PluginInputDomainAdapter.h>
cannam@233 41
cannam@233 42 #include <cmath>
cannam@233 43
Chris@317 44 #include "Window.h"
Chris@317 45
Chris@434 46 #include <stdlib.h>
Chris@434 47 #include <stdio.h>
Chris@434 48 #include <math.h>
Chris@434 49 #include <string.h>
Chris@434 50 #include <limits.h>
cannam@233 51
Chris@434 52 // Override C linkage for KissFFT headers. So long as we have already
Chris@434 53 // included all of the other (system etc) headers KissFFT depends on,
Chris@434 54 // this should work out OK
Chris@434 55 #undef __cplusplus
cannam@233 56
Chris@434 57 namespace KissSingle {
Chris@434 58 #undef KISS_FFT_H
Chris@434 59 #undef KISS_FTR_H
Chris@434 60 #undef KISS_FFT__GUTS_H
Chris@434 61 #undef FIXED_POINT
Chris@434 62 #undef USE_SIMD
Chris@434 63 #undef kiss_fft_scalar
Chris@434 64 #define kiss_fft_scalar float
Chris@434 65 inline void free(void *ptr) { ::free(ptr); }
Chris@434 66 #include "../vamp-sdk/ext/kiss_fft.c"
Chris@434 67 #include "../vamp-sdk/ext/kiss_fftr.c"
Chris@434 68 }
cannam@233 69
cannam@263 70 _VAMP_SDK_HOSTSPACE_BEGIN(PluginInputDomainAdapter.cpp)
cannam@263 71
cannam@233 72 namespace Vamp {
cannam@233 73
cannam@233 74 namespace HostExt {
cannam@233 75
cannam@233 76 class PluginInputDomainAdapter::Impl
cannam@233 77 {
cannam@233 78 public:
cannam@233 79 Impl(Plugin *plugin, float inputSampleRate);
cannam@233 80 ~Impl();
cannam@233 81
cannam@233 82 bool initialise(size_t channels, size_t stepSize, size_t blockSize);
cannam@288 83 void reset();
cannam@233 84
cannam@233 85 size_t getPreferredStepSize() const;
cannam@233 86 size_t getPreferredBlockSize() const;
cannam@233 87
cannam@233 88 FeatureSet process(const float *const *inputBuffers, RealTime timestamp);
cannam@288 89
cannam@288 90 void setProcessTimestampMethod(ProcessTimestampMethod m);
cannam@288 91 ProcessTimestampMethod getProcessTimestampMethod() const;
cannam@233 92
cannam@233 93 RealTime getTimestampAdjustment() const;
cannam@233 94
Chris@317 95 WindowType getWindowType() const;
Chris@317 96 void setWindowType(WindowType type);
Chris@317 97
cannam@233 98 protected:
cannam@233 99 Plugin *m_plugin;
cannam@233 100 float m_inputSampleRate;
cannam@233 101 int m_channels;
cannam@288 102 int m_stepSize;
cannam@233 103 int m_blockSize;
cannam@233 104 float **m_freqbuf;
Chris@434 105 float *m_ri;
Chris@317 106
Chris@317 107 WindowType m_windowType;
Chris@434 108 Window<float> *m_window;
cannam@233 109
cannam@288 110 ProcessTimestampMethod m_method;
cannam@288 111 int m_processCount;
cannam@289 112 float **m_shiftBuffers;
cannam@288 113
Chris@434 114 KissSingle::kiss_fftr_cfg m_cfg;
Chris@434 115 KissSingle::kiss_fft_cpx *m_cbuf;
cannam@233 116
cannam@289 117 FeatureSet processShiftingTimestamp(const float *const *inputBuffers, RealTime timestamp);
cannam@289 118 FeatureSet processShiftingData(const float *const *inputBuffers, RealTime timestamp);
cannam@289 119
cannam@233 120 size_t makeBlockSizeAcceptable(size_t) const;
Chris@317 121
Chris@434 122 Window<float>::WindowType convertType(WindowType t) const;
cannam@233 123 };
cannam@233 124
cannam@233 125 PluginInputDomainAdapter::PluginInputDomainAdapter(Plugin *plugin) :
cannam@233 126 PluginWrapper(plugin)
cannam@233 127 {
cannam@233 128 m_impl = new Impl(plugin, m_inputSampleRate);
cannam@233 129 }
cannam@233 130
cannam@233 131 PluginInputDomainAdapter::~PluginInputDomainAdapter()
cannam@233 132 {
cannam@233 133 delete m_impl;
cannam@233 134 }
cannam@233 135
cannam@233 136 bool
cannam@233 137 PluginInputDomainAdapter::initialise(size_t channels, size_t stepSize, size_t blockSize)
cannam@233 138 {
cannam@233 139 return m_impl->initialise(channels, stepSize, blockSize);
cannam@233 140 }
cannam@233 141
cannam@288 142 void
cannam@288 143 PluginInputDomainAdapter::reset()
cannam@288 144 {
cannam@288 145 m_impl->reset();
cannam@288 146 }
cannam@288 147
cannam@233 148 Plugin::InputDomain
cannam@233 149 PluginInputDomainAdapter::getInputDomain() const
cannam@233 150 {
cannam@233 151 return TimeDomain;
cannam@233 152 }
cannam@233 153
cannam@233 154 size_t
cannam@233 155 PluginInputDomainAdapter::getPreferredStepSize() const
cannam@233 156 {
cannam@233 157 return m_impl->getPreferredStepSize();
cannam@233 158 }
cannam@233 159
cannam@233 160 size_t
cannam@233 161 PluginInputDomainAdapter::getPreferredBlockSize() const
cannam@233 162 {
cannam@233 163 return m_impl->getPreferredBlockSize();
cannam@233 164 }
cannam@233 165
cannam@233 166 Plugin::FeatureSet
cannam@233 167 PluginInputDomainAdapter::process(const float *const *inputBuffers, RealTime timestamp)
cannam@233 168 {
cannam@233 169 return m_impl->process(inputBuffers, timestamp);
cannam@233 170 }
cannam@233 171
cannam@288 172 void
cannam@288 173 PluginInputDomainAdapter::setProcessTimestampMethod(ProcessTimestampMethod m)
cannam@288 174 {
cannam@288 175 m_impl->setProcessTimestampMethod(m);
cannam@288 176 }
cannam@288 177
cannam@288 178 PluginInputDomainAdapter::ProcessTimestampMethod
cannam@288 179 PluginInputDomainAdapter::getProcessTimestampMethod() const
cannam@288 180 {
cannam@288 181 return m_impl->getProcessTimestampMethod();
cannam@288 182 }
cannam@288 183
cannam@233 184 RealTime
cannam@233 185 PluginInputDomainAdapter::getTimestampAdjustment() const
cannam@233 186 {
cannam@233 187 return m_impl->getTimestampAdjustment();
cannam@233 188 }
cannam@233 189
Chris@317 190 PluginInputDomainAdapter::WindowType
Chris@317 191 PluginInputDomainAdapter::getWindowType() const
Chris@317 192 {
Chris@317 193 return m_impl->getWindowType();
Chris@317 194 }
Chris@317 195
Chris@317 196 void
Chris@317 197 PluginInputDomainAdapter::setWindowType(WindowType w)
Chris@317 198 {
Chris@317 199 m_impl->setWindowType(w);
Chris@317 200 }
Chris@317 201
cannam@233 202
cannam@233 203 PluginInputDomainAdapter::Impl::Impl(Plugin *plugin, float inputSampleRate) :
cannam@233 204 m_plugin(plugin),
cannam@233 205 m_inputSampleRate(inputSampleRate),
cannam@233 206 m_channels(0),
cannam@288 207 m_stepSize(0),
cannam@233 208 m_blockSize(0),
cannam@233 209 m_freqbuf(0),
cannam@233 210 m_ri(0),
Chris@317 211 m_windowType(HanningWindow),
cannam@233 212 m_window(0),
cannam@288 213 m_method(ShiftTimestamp),
cannam@288 214 m_processCount(0),
cannam@289 215 m_shiftBuffers(0),
Chris@434 216 m_cfg(0),
cannam@233 217 m_cbuf(0)
cannam@233 218 {
cannam@233 219 }
cannam@233 220
cannam@233 221 PluginInputDomainAdapter::Impl::~Impl()
cannam@233 222 {
cannam@233 223 // the adapter will delete the plugin
cannam@233 224
cannam@289 225 if (m_shiftBuffers) {
cannam@289 226 for (int c = 0; c < m_channels; ++c) {
cannam@289 227 delete[] m_shiftBuffers[c];
cannam@289 228 }
cannam@289 229 delete[] m_shiftBuffers;
cannam@289 230 }
cannam@289 231
cannam@233 232 if (m_channels > 0) {
cannam@233 233 for (int c = 0; c < m_channels; ++c) {
cannam@233 234 delete[] m_freqbuf[c];
cannam@233 235 }
cannam@233 236 delete[] m_freqbuf;
Chris@435 237 delete[] m_ri;
Chris@434 238 if (m_cfg) {
Chris@434 239 KissSingle::kiss_fftr_free(m_cfg);
Chris@435 240 m_cfg = 0;
Chris@434 241 delete[] m_cbuf;
Chris@435 242 m_cbuf = 0;
cannam@233 243 }
Chris@317 244 delete m_window;
cannam@233 245 }
cannam@233 246 }
cannam@233 247
cannam@233 248 // for some visual studii apparently
cannam@233 249 #ifndef M_PI
cannam@233 250 #define M_PI 3.14159265358979232846
cannam@233 251 #endif
cannam@233 252
cannam@233 253 bool
cannam@233 254 PluginInputDomainAdapter::Impl::initialise(size_t channels, size_t stepSize, size_t blockSize)
cannam@233 255 {
cannam@233 256 if (m_plugin->getInputDomain() == TimeDomain) {
cannam@233 257
cannam@288 258 m_stepSize = int(stepSize);
cannam@233 259 m_blockSize = int(blockSize);
cannam@233 260 m_channels = int(channels);
cannam@233 261
cannam@233 262 return m_plugin->initialise(channels, stepSize, blockSize);
cannam@233 263 }
cannam@233 264
cannam@233 265 if (blockSize < 2) {
cannam@283 266 std::cerr << "ERROR: PluginInputDomainAdapter::initialise: blocksize < 2 not supported" << std::endl;
cannam@233 267 return false;
cannam@233 268 }
cannam@233 269
Chris@434 270 if (blockSize % 2) {
Chris@434 271 std::cerr << "ERROR: PluginInputDomainAdapter::initialise: odd blocksize " << blockSize << " not supported" << std::endl;
cannam@233 272 return false;
cannam@233 273 }
cannam@233 274
cannam@233 275 if (m_channels > 0) {
cannam@233 276 for (int c = 0; c < m_channels; ++c) {
cannam@233 277 delete[] m_freqbuf[c];
cannam@233 278 }
cannam@233 279 delete[] m_freqbuf;
Chris@435 280 delete[] m_ri;
Chris@434 281 if (m_cfg) {
Chris@434 282 KissSingle::kiss_fftr_free(m_cfg);
Chris@435 283 m_cfg = 0;
Chris@434 284 delete[] m_cbuf;
Chris@435 285 m_cbuf = 0;
cannam@233 286 }
Chris@317 287 delete m_window;
cannam@233 288 }
cannam@233 289
cannam@288 290 m_stepSize = int(stepSize);
cannam@233 291 m_blockSize = int(blockSize);
cannam@233 292 m_channels = int(channels);
cannam@233 293
cannam@233 294 m_freqbuf = new float *[m_channels];
cannam@233 295 for (int c = 0; c < m_channels; ++c) {
cannam@233 296 m_freqbuf[c] = new float[m_blockSize + 2];
cannam@233 297 }
Chris@435 298 m_ri = new float[m_blockSize];
cannam@233 299
Chris@434 300 m_window = new Window<float>(convertType(m_windowType), m_blockSize);
cannam@233 301
Chris@435 302 m_cfg = KissSingle::kiss_fftr_alloc(m_blockSize, false, 0, 0);
Chris@435 303 m_cbuf = new KissSingle::kiss_fft_cpx[m_blockSize/2+1];
cannam@233 304
cannam@288 305 m_processCount = 0;
cannam@288 306
Chris@435 307 return m_plugin->initialise(channels, stepSize, m_blockSize);
cannam@233 308 }
cannam@233 309
cannam@288 310 void
cannam@288 311 PluginInputDomainAdapter::Impl::reset()
cannam@288 312 {
cannam@288 313 m_processCount = 0;
cannam@288 314 m_plugin->reset();
cannam@288 315 }
cannam@288 316
cannam@233 317 size_t
cannam@233 318 PluginInputDomainAdapter::Impl::getPreferredStepSize() const
cannam@233 319 {
cannam@233 320 size_t step = m_plugin->getPreferredStepSize();
cannam@233 321
cannam@233 322 if (step == 0 && (m_plugin->getInputDomain() == FrequencyDomain)) {
cannam@233 323 step = getPreferredBlockSize() / 2;
cannam@233 324 }
cannam@233 325
cannam@233 326 return step;
cannam@233 327 }
cannam@233 328
cannam@233 329 size_t
cannam@233 330 PluginInputDomainAdapter::Impl::getPreferredBlockSize() const
cannam@233 331 {
cannam@233 332 size_t block = m_plugin->getPreferredBlockSize();
cannam@233 333
cannam@233 334 if (m_plugin->getInputDomain() == FrequencyDomain) {
cannam@233 335 if (block == 0) {
cannam@233 336 block = 1024;
cannam@233 337 } else {
cannam@233 338 block = makeBlockSizeAcceptable(block);
cannam@233 339 }
cannam@233 340 }
cannam@233 341
cannam@233 342 return block;
cannam@233 343 }
cannam@233 344
cannam@233 345 size_t
cannam@233 346 PluginInputDomainAdapter::Impl::makeBlockSizeAcceptable(size_t blockSize) const
cannam@233 347 {
cannam@233 348 if (blockSize < 2) {
cannam@233 349
cannam@283 350 std::cerr << "WARNING: PluginInputDomainAdapter::initialise: blocksize < 2 not" << std::endl
cannam@233 351 << "supported, increasing from " << blockSize << " to 2" << std::endl;
cannam@233 352 blockSize = 2;
Chris@434 353
Chris@434 354 } else if (blockSize % 2) {
cannam@233 355
Chris@434 356 std::cerr << "WARNING: PluginInputDomainAdapter::initialise: odd blocksize not" << std::endl
Chris@434 357 << "supported, increasing from " << blockSize << " to " << (blockSize+1) << std::endl;
Chris@434 358 blockSize = blockSize+1;
cannam@233 359 }
cannam@233 360
cannam@233 361 return blockSize;
cannam@233 362 }
cannam@233 363
cannam@233 364 RealTime
cannam@233 365 PluginInputDomainAdapter::Impl::getTimestampAdjustment() const
cannam@233 366 {
cannam@233 367 if (m_plugin->getInputDomain() == TimeDomain) {
cannam@233 368 return RealTime::zeroTime;
cannam@298 369 } else if (m_method == ShiftData || m_method == NoShift) {
cannam@289 370 return RealTime::zeroTime;
cannam@233 371 } else {
cannam@233 372 return RealTime::frame2RealTime
cannam@233 373 (m_blockSize/2, int(m_inputSampleRate + 0.5));
cannam@233 374 }
cannam@233 375 }
cannam@233 376
cannam@288 377 void
cannam@288 378 PluginInputDomainAdapter::Impl::setProcessTimestampMethod(ProcessTimestampMethod m)
cannam@288 379 {
cannam@288 380 m_method = m;
cannam@288 381 }
cannam@288 382
cannam@288 383 PluginInputDomainAdapter::ProcessTimestampMethod
cannam@288 384 PluginInputDomainAdapter::Impl::getProcessTimestampMethod() const
cannam@288 385 {
cannam@288 386 return m_method;
cannam@288 387 }
cannam@288 388
Chris@317 389 void
Chris@317 390 PluginInputDomainAdapter::Impl::setWindowType(WindowType t)
Chris@317 391 {
Chris@317 392 if (m_windowType == t) return;
Chris@317 393 m_windowType = t;
Chris@317 394 if (m_window) {
Chris@317 395 delete m_window;
Chris@434 396 m_window = new Window<float>(convertType(m_windowType), m_blockSize);
Chris@317 397 }
Chris@317 398 }
Chris@317 399
Chris@317 400 PluginInputDomainAdapter::WindowType
Chris@317 401 PluginInputDomainAdapter::Impl::getWindowType() const
Chris@317 402 {
Chris@317 403 return m_windowType;
Chris@317 404 }
Chris@317 405
Chris@434 406 Window<float>::WindowType
Chris@317 407 PluginInputDomainAdapter::Impl::convertType(WindowType t) const
Chris@317 408 {
Chris@317 409 switch (t) {
Chris@317 410 case RectangularWindow:
Chris@434 411 return Window<float>::RectangularWindow;
Chris@317 412 case BartlettWindow:
Chris@434 413 return Window<float>::BartlettWindow;
Chris@317 414 case HammingWindow:
Chris@434 415 return Window<float>::HammingWindow;
Chris@317 416 case HanningWindow:
Chris@434 417 return Window<float>::HanningWindow;
Chris@317 418 case BlackmanWindow:
Chris@434 419 return Window<float>::BlackmanWindow;
Chris@317 420 case NuttallWindow:
Chris@434 421 return Window<float>::NuttallWindow;
Chris@317 422 case BlackmanHarrisWindow:
Chris@434 423 return Window<float>::BlackmanHarrisWindow;
Chris@319 424 default:
Chris@434 425 return Window<float>::HanningWindow;
Chris@317 426 }
Chris@317 427 }
Chris@317 428
cannam@233 429 Plugin::FeatureSet
cannam@233 430 PluginInputDomainAdapter::Impl::process(const float *const *inputBuffers,
cannam@233 431 RealTime timestamp)
cannam@233 432 {
cannam@233 433 if (m_plugin->getInputDomain() == TimeDomain) {
cannam@233 434 return m_plugin->process(inputBuffers, timestamp);
cannam@233 435 }
cannam@233 436
cannam@298 437 if (m_method == ShiftTimestamp || m_method == NoShift) {
cannam@289 438 return processShiftingTimestamp(inputBuffers, timestamp);
cannam@289 439 } else {
cannam@289 440 return processShiftingData(inputBuffers, timestamp);
cannam@289 441 }
cannam@289 442 }
cannam@233 443
cannam@289 444 Plugin::FeatureSet
cannam@289 445 PluginInputDomainAdapter::Impl::processShiftingTimestamp(const float *const *inputBuffers,
cannam@289 446 RealTime timestamp)
cannam@289 447 {
Chris@421 448 unsigned int roundedRate = 1;
Chris@421 449 if (m_inputSampleRate > 0.f) {
Chris@421 450 roundedRate = (unsigned int)round(m_inputSampleRate);
Chris@421 451 }
Chris@421 452
cannam@298 453 if (m_method == ShiftTimestamp) {
Chris@386 454 // we may need to add one nsec if timestamp +
Chris@386 455 // getTimestampAdjustment() rounds down
cannam@298 456 timestamp = timestamp + getTimestampAdjustment();
Chris@386 457 RealTime nsec(0, 1);
Chris@421 458 if (RealTime::realTime2Frame(timestamp, roundedRate) <
Chris@421 459 RealTime::realTime2Frame(timestamp + nsec, roundedRate)) {
Chris@386 460 timestamp = timestamp + nsec;
Chris@386 461 }
cannam@298 462 }
cannam@233 463
cannam@233 464 for (int c = 0; c < m_channels; ++c) {
cannam@233 465
Chris@317 466 m_window->cut(inputBuffers[c], m_ri);
cannam@233 467
cannam@233 468 for (int i = 0; i < m_blockSize/2; ++i) {
cannam@233 469 // FFT shift
Chris@434 470 float value = m_ri[i];
cannam@233 471 m_ri[i] = m_ri[i + m_blockSize/2];
cannam@233 472 m_ri[i + m_blockSize/2] = value;
cannam@233 473 }
cannam@233 474
Chris@434 475 KissSingle::kiss_fftr(m_cfg, m_ri, m_cbuf);
Chris@434 476
cannam@233 477 for (int i = 0; i <= m_blockSize/2; ++i) {
Chris@434 478 m_freqbuf[c][i * 2] = m_cbuf[i].r;
Chris@434 479 m_freqbuf[c][i * 2 + 1] = m_cbuf[i].i;
cannam@233 480 }
cannam@233 481 }
cannam@233 482
cannam@289 483 return m_plugin->process(m_freqbuf, timestamp);
cannam@288 484 }
cannam@288 485
cannam@288 486 Plugin::FeatureSet
cannam@289 487 PluginInputDomainAdapter::Impl::processShiftingData(const float *const *inputBuffers,
cannam@289 488 RealTime timestamp)
cannam@288 489 {
cannam@289 490 if (m_processCount == 0) {
cannam@289 491 if (!m_shiftBuffers) {
cannam@289 492 m_shiftBuffers = new float *[m_channels];
cannam@289 493 for (int c = 0; c < m_channels; ++c) {
cannam@289 494 m_shiftBuffers[c] = new float[m_blockSize + m_blockSize/2];
cannam@289 495 }
cannam@289 496 }
cannam@289 497 for (int c = 0; c < m_channels; ++c) {
cannam@289 498 for (int i = 0; i < m_blockSize + m_blockSize/2; ++i) {
cannam@289 499 m_shiftBuffers[c][i] = 0.f;
cannam@289 500 }
cannam@289 501 }
cannam@289 502 }
cannam@289 503
cannam@289 504 for (int c = 0; c < m_channels; ++c) {
cannam@289 505 for (int i = m_stepSize; i < m_blockSize + m_blockSize/2; ++i) {
cannam@289 506 m_shiftBuffers[c][i - m_stepSize] = m_shiftBuffers[c][i];
cannam@289 507 }
cannam@289 508 for (int i = 0; i < m_blockSize; ++i) {
cannam@289 509 m_shiftBuffers[c][i + m_blockSize/2] = inputBuffers[c][i];
cannam@289 510 }
cannam@289 511 }
cannam@289 512
cannam@289 513 for (int c = 0; c < m_channels; ++c) {
cannam@289 514
Chris@317 515 m_window->cut(m_shiftBuffers[c], m_ri);
cannam@289 516
cannam@289 517 for (int i = 0; i < m_blockSize/2; ++i) {
cannam@289 518 // FFT shift
Chris@434 519 float value = m_ri[i];
cannam@289 520 m_ri[i] = m_ri[i + m_blockSize/2];
cannam@289 521 m_ri[i + m_blockSize/2] = value;
cannam@289 522 }
cannam@289 523
Chris@434 524 KissSingle::kiss_fftr(m_cfg, m_ri, m_cbuf);
Chris@434 525
cannam@289 526 for (int i = 0; i <= m_blockSize/2; ++i) {
Chris@434 527 m_freqbuf[c][i * 2] = m_cbuf[i].r;
Chris@434 528 m_freqbuf[c][i * 2 + 1] = m_cbuf[i].i;
cannam@289 529 }
cannam@289 530 }
cannam@289 531
cannam@289 532 ++m_processCount;
cannam@289 533
cannam@289 534 return m_plugin->process(m_freqbuf, timestamp);
cannam@233 535 }
cannam@233 536
cannam@233 537 }
cannam@233 538
cannam@233 539 }
cannam@233 540
cannam@263 541 _VAMP_SDK_HOSTSPACE_END(PluginInputDomainAdapter.cpp)
cannam@263 542