annotate src/vamp-hostsdk/PluginInputDomainAdapter.cpp @ 434:e979a9c4ffb6 vampipe

Switch from Cross FFT with option of FFTW build, to KissFFT only (code bundled). This is much faster than the default build and simpler than managing two options.
author Chris Cannam
date Tue, 16 Aug 2016 16:04:09 +0100
parents 9a2998401bbe
children 27c3448df198
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@434 237 if (m_cfg) {
Chris@434 238 KissSingle::kiss_fftr_free(m_cfg);
Chris@434 239 delete[] m_cbuf;
Chris@434 240 m_cfg = 0;
cannam@233 241 }
Chris@317 242 delete m_window;
cannam@233 243 }
cannam@233 244 }
cannam@233 245
cannam@233 246 // for some visual studii apparently
cannam@233 247 #ifndef M_PI
cannam@233 248 #define M_PI 3.14159265358979232846
cannam@233 249 #endif
cannam@233 250
cannam@233 251 bool
cannam@233 252 PluginInputDomainAdapter::Impl::initialise(size_t channels, size_t stepSize, size_t blockSize)
cannam@233 253 {
cannam@233 254 if (m_plugin->getInputDomain() == TimeDomain) {
cannam@233 255
cannam@288 256 m_stepSize = int(stepSize);
cannam@233 257 m_blockSize = int(blockSize);
cannam@233 258 m_channels = int(channels);
cannam@233 259
cannam@233 260 return m_plugin->initialise(channels, stepSize, blockSize);
cannam@233 261 }
cannam@233 262
cannam@233 263 if (blockSize < 2) {
cannam@283 264 std::cerr << "ERROR: PluginInputDomainAdapter::initialise: blocksize < 2 not supported" << std::endl;
cannam@233 265 return false;
cannam@233 266 }
cannam@233 267
Chris@434 268 if (blockSize % 2) {
Chris@434 269 std::cerr << "ERROR: PluginInputDomainAdapter::initialise: odd blocksize " << blockSize << " not supported" << std::endl;
cannam@233 270 return false;
cannam@233 271 }
cannam@233 272
cannam@233 273 if (m_channels > 0) {
cannam@233 274 for (int c = 0; c < m_channels; ++c) {
cannam@233 275 delete[] m_freqbuf[c];
cannam@233 276 }
cannam@233 277 delete[] m_freqbuf;
Chris@434 278 if (m_cfg) {
Chris@434 279 KissSingle::kiss_fftr_free(m_cfg);
Chris@434 280 delete[] m_cbuf;
Chris@434 281 m_cfg = 0;
cannam@233 282 }
Chris@317 283 delete m_window;
cannam@233 284 }
cannam@233 285
cannam@288 286 m_stepSize = int(stepSize);
cannam@233 287 m_blockSize = int(blockSize);
cannam@233 288 m_channels = int(channels);
cannam@233 289
cannam@233 290 m_freqbuf = new float *[m_channels];
cannam@233 291 for (int c = 0; c < m_channels; ++c) {
cannam@233 292 m_freqbuf[c] = new float[m_blockSize + 2];
cannam@233 293 }
cannam@233 294
Chris@434 295 m_window = new Window<float>(convertType(m_windowType), m_blockSize);
cannam@233 296
Chris@434 297 m_cfg = KissSingle::kiss_fftr_alloc(blockSize, false, 0, 0);
Chris@434 298 m_cbuf = new KissSingle::kiss_fft_cpx[blockSize/2+1];
cannam@233 299
cannam@288 300 m_processCount = 0;
cannam@288 301
cannam@233 302 return m_plugin->initialise(channels, stepSize, blockSize);
cannam@233 303 }
cannam@233 304
cannam@288 305 void
cannam@288 306 PluginInputDomainAdapter::Impl::reset()
cannam@288 307 {
cannam@288 308 m_processCount = 0;
cannam@288 309 m_plugin->reset();
cannam@288 310 }
cannam@288 311
cannam@233 312 size_t
cannam@233 313 PluginInputDomainAdapter::Impl::getPreferredStepSize() const
cannam@233 314 {
cannam@233 315 size_t step = m_plugin->getPreferredStepSize();
cannam@233 316
cannam@233 317 if (step == 0 && (m_plugin->getInputDomain() == FrequencyDomain)) {
cannam@233 318 step = getPreferredBlockSize() / 2;
cannam@233 319 }
cannam@233 320
cannam@233 321 return step;
cannam@233 322 }
cannam@233 323
cannam@233 324 size_t
cannam@233 325 PluginInputDomainAdapter::Impl::getPreferredBlockSize() const
cannam@233 326 {
cannam@233 327 size_t block = m_plugin->getPreferredBlockSize();
cannam@233 328
cannam@233 329 if (m_plugin->getInputDomain() == FrequencyDomain) {
cannam@233 330 if (block == 0) {
cannam@233 331 block = 1024;
cannam@233 332 } else {
cannam@233 333 block = makeBlockSizeAcceptable(block);
cannam@233 334 }
cannam@233 335 }
cannam@233 336
cannam@233 337 return block;
cannam@233 338 }
cannam@233 339
cannam@233 340 size_t
cannam@233 341 PluginInputDomainAdapter::Impl::makeBlockSizeAcceptable(size_t blockSize) const
cannam@233 342 {
cannam@233 343 if (blockSize < 2) {
cannam@233 344
cannam@283 345 std::cerr << "WARNING: PluginInputDomainAdapter::initialise: blocksize < 2 not" << std::endl
cannam@233 346 << "supported, increasing from " << blockSize << " to 2" << std::endl;
cannam@233 347 blockSize = 2;
Chris@434 348
Chris@434 349 } else if (blockSize % 2) {
cannam@233 350
Chris@434 351 std::cerr << "WARNING: PluginInputDomainAdapter::initialise: odd blocksize not" << std::endl
Chris@434 352 << "supported, increasing from " << blockSize << " to " << (blockSize+1) << std::endl;
Chris@434 353 blockSize = blockSize+1;
cannam@233 354 }
cannam@233 355
cannam@233 356 return blockSize;
cannam@233 357 }
cannam@233 358
cannam@233 359 RealTime
cannam@233 360 PluginInputDomainAdapter::Impl::getTimestampAdjustment() const
cannam@233 361 {
cannam@233 362 if (m_plugin->getInputDomain() == TimeDomain) {
cannam@233 363 return RealTime::zeroTime;
cannam@298 364 } else if (m_method == ShiftData || m_method == NoShift) {
cannam@289 365 return RealTime::zeroTime;
cannam@233 366 } else {
cannam@233 367 return RealTime::frame2RealTime
cannam@233 368 (m_blockSize/2, int(m_inputSampleRate + 0.5));
cannam@233 369 }
cannam@233 370 }
cannam@233 371
cannam@288 372 void
cannam@288 373 PluginInputDomainAdapter::Impl::setProcessTimestampMethod(ProcessTimestampMethod m)
cannam@288 374 {
cannam@288 375 m_method = m;
cannam@288 376 }
cannam@288 377
cannam@288 378 PluginInputDomainAdapter::ProcessTimestampMethod
cannam@288 379 PluginInputDomainAdapter::Impl::getProcessTimestampMethod() const
cannam@288 380 {
cannam@288 381 return m_method;
cannam@288 382 }
cannam@288 383
Chris@317 384 void
Chris@317 385 PluginInputDomainAdapter::Impl::setWindowType(WindowType t)
Chris@317 386 {
Chris@317 387 if (m_windowType == t) return;
Chris@317 388 m_windowType = t;
Chris@317 389 if (m_window) {
Chris@317 390 delete m_window;
Chris@434 391 m_window = new Window<float>(convertType(m_windowType), m_blockSize);
Chris@317 392 }
Chris@317 393 }
Chris@317 394
Chris@317 395 PluginInputDomainAdapter::WindowType
Chris@317 396 PluginInputDomainAdapter::Impl::getWindowType() const
Chris@317 397 {
Chris@317 398 return m_windowType;
Chris@317 399 }
Chris@317 400
Chris@434 401 Window<float>::WindowType
Chris@317 402 PluginInputDomainAdapter::Impl::convertType(WindowType t) const
Chris@317 403 {
Chris@317 404 switch (t) {
Chris@317 405 case RectangularWindow:
Chris@434 406 return Window<float>::RectangularWindow;
Chris@317 407 case BartlettWindow:
Chris@434 408 return Window<float>::BartlettWindow;
Chris@317 409 case HammingWindow:
Chris@434 410 return Window<float>::HammingWindow;
Chris@317 411 case HanningWindow:
Chris@434 412 return Window<float>::HanningWindow;
Chris@317 413 case BlackmanWindow:
Chris@434 414 return Window<float>::BlackmanWindow;
Chris@317 415 case NuttallWindow:
Chris@434 416 return Window<float>::NuttallWindow;
Chris@317 417 case BlackmanHarrisWindow:
Chris@434 418 return Window<float>::BlackmanHarrisWindow;
Chris@319 419 default:
Chris@434 420 return Window<float>::HanningWindow;
Chris@317 421 }
Chris@317 422 }
Chris@317 423
cannam@233 424 Plugin::FeatureSet
cannam@233 425 PluginInputDomainAdapter::Impl::process(const float *const *inputBuffers,
cannam@233 426 RealTime timestamp)
cannam@233 427 {
cannam@233 428 if (m_plugin->getInputDomain() == TimeDomain) {
cannam@233 429 return m_plugin->process(inputBuffers, timestamp);
cannam@233 430 }
cannam@233 431
cannam@298 432 if (m_method == ShiftTimestamp || m_method == NoShift) {
cannam@289 433 return processShiftingTimestamp(inputBuffers, timestamp);
cannam@289 434 } else {
cannam@289 435 return processShiftingData(inputBuffers, timestamp);
cannam@289 436 }
cannam@289 437 }
cannam@233 438
cannam@289 439 Plugin::FeatureSet
cannam@289 440 PluginInputDomainAdapter::Impl::processShiftingTimestamp(const float *const *inputBuffers,
cannam@289 441 RealTime timestamp)
cannam@289 442 {
Chris@421 443 unsigned int roundedRate = 1;
Chris@421 444 if (m_inputSampleRate > 0.f) {
Chris@421 445 roundedRate = (unsigned int)round(m_inputSampleRate);
Chris@421 446 }
Chris@421 447
cannam@298 448 if (m_method == ShiftTimestamp) {
Chris@386 449 // we may need to add one nsec if timestamp +
Chris@386 450 // getTimestampAdjustment() rounds down
cannam@298 451 timestamp = timestamp + getTimestampAdjustment();
Chris@386 452 RealTime nsec(0, 1);
Chris@421 453 if (RealTime::realTime2Frame(timestamp, roundedRate) <
Chris@421 454 RealTime::realTime2Frame(timestamp + nsec, roundedRate)) {
Chris@386 455 timestamp = timestamp + nsec;
Chris@386 456 }
cannam@298 457 }
cannam@233 458
cannam@233 459 for (int c = 0; c < m_channels; ++c) {
cannam@233 460
Chris@317 461 m_window->cut(inputBuffers[c], m_ri);
cannam@233 462
cannam@233 463 for (int i = 0; i < m_blockSize/2; ++i) {
cannam@233 464 // FFT shift
Chris@434 465 float value = m_ri[i];
cannam@233 466 m_ri[i] = m_ri[i + m_blockSize/2];
cannam@233 467 m_ri[i + m_blockSize/2] = value;
cannam@233 468 }
cannam@233 469
Chris@434 470 KissSingle::kiss_fftr(m_cfg, m_ri, m_cbuf);
Chris@434 471
cannam@233 472 for (int i = 0; i <= m_blockSize/2; ++i) {
Chris@434 473 m_freqbuf[c][i * 2] = m_cbuf[i].r;
Chris@434 474 m_freqbuf[c][i * 2 + 1] = m_cbuf[i].i;
cannam@233 475 }
cannam@233 476 }
cannam@233 477
cannam@289 478 return m_plugin->process(m_freqbuf, timestamp);
cannam@288 479 }
cannam@288 480
cannam@288 481 Plugin::FeatureSet
cannam@289 482 PluginInputDomainAdapter::Impl::processShiftingData(const float *const *inputBuffers,
cannam@289 483 RealTime timestamp)
cannam@288 484 {
cannam@289 485 if (m_processCount == 0) {
cannam@289 486 if (!m_shiftBuffers) {
cannam@289 487 m_shiftBuffers = new float *[m_channels];
cannam@289 488 for (int c = 0; c < m_channels; ++c) {
cannam@289 489 m_shiftBuffers[c] = new float[m_blockSize + m_blockSize/2];
cannam@289 490 }
cannam@289 491 }
cannam@289 492 for (int c = 0; c < m_channels; ++c) {
cannam@289 493 for (int i = 0; i < m_blockSize + m_blockSize/2; ++i) {
cannam@289 494 m_shiftBuffers[c][i] = 0.f;
cannam@289 495 }
cannam@289 496 }
cannam@289 497 }
cannam@289 498
cannam@289 499 for (int c = 0; c < m_channels; ++c) {
cannam@289 500 for (int i = m_stepSize; i < m_blockSize + m_blockSize/2; ++i) {
cannam@289 501 m_shiftBuffers[c][i - m_stepSize] = m_shiftBuffers[c][i];
cannam@289 502 }
cannam@289 503 for (int i = 0; i < m_blockSize; ++i) {
cannam@289 504 m_shiftBuffers[c][i + m_blockSize/2] = inputBuffers[c][i];
cannam@289 505 }
cannam@289 506 }
cannam@289 507
cannam@289 508 for (int c = 0; c < m_channels; ++c) {
cannam@289 509
Chris@317 510 m_window->cut(m_shiftBuffers[c], m_ri);
cannam@289 511
cannam@289 512 for (int i = 0; i < m_blockSize/2; ++i) {
cannam@289 513 // FFT shift
Chris@434 514 float value = m_ri[i];
cannam@289 515 m_ri[i] = m_ri[i + m_blockSize/2];
cannam@289 516 m_ri[i + m_blockSize/2] = value;
cannam@289 517 }
cannam@289 518
Chris@434 519 KissSingle::kiss_fftr(m_cfg, m_ri, m_cbuf);
Chris@434 520
cannam@289 521 for (int i = 0; i <= m_blockSize/2; ++i) {
Chris@434 522 m_freqbuf[c][i * 2] = m_cbuf[i].r;
Chris@434 523 m_freqbuf[c][i * 2 + 1] = m_cbuf[i].i;
cannam@289 524 }
cannam@289 525 }
cannam@289 526
cannam@289 527 ++m_processCount;
cannam@289 528
cannam@289 529 return m_plugin->process(m_freqbuf, timestamp);
cannam@233 530 }
cannam@233 531
cannam@233 532 }
cannam@233 533
cannam@233 534 }
cannam@233 535
cannam@263 536 _VAMP_SDK_HOSTSPACE_END(PluginInputDomainAdapter.cpp)
cannam@263 537