Mercurial > hg > svcore
comparison plugin/transform/FeatureExtractionModelTransformer.cpp @ 363:0e30c8ec15a0
* Add wave file model method for reading more than one channel at once,
avoiding ludicrously expensive backward seeks and double-reads when
playing multi-channel files or using them as inputs to feature extraction
plugins
author | Chris Cannam |
---|---|
date | Thu, 24 Jan 2008 14:35:43 +0000 |
parents | 399ea254afd6 |
children | 4bb19132da23 |
comparison
equal
deleted
inserted
replaced
362:cc4eb32efc6c | 363:0e30c8ec15a0 |
---|---|
383 (((blockFrame - contextStart) / stepSize) * 99) / | 383 (((blockFrame - contextStart) / stepSize) * 99) / |
384 (contextDuration / stepSize); | 384 (contextDuration / stepSize); |
385 | 385 |
386 // channelCount is either m_input.getModel()->channelCount or 1 | 386 // channelCount is either m_input.getModel()->channelCount or 1 |
387 | 387 |
388 for (size_t ch = 0; ch < channelCount; ++ch) { | 388 if (frequencyDomain) { |
389 if (frequencyDomain) { | 389 for (size_t ch = 0; ch < channelCount; ++ch) { |
390 int column = (blockFrame - startFrame) / stepSize; | 390 int column = (blockFrame - startFrame) / stepSize; |
391 for (size_t i = 0; i <= blockSize/2; ++i) { | 391 for (size_t i = 0; i <= blockSize/2; ++i) { |
392 fftModels[ch]->getValuesAt | 392 fftModels[ch]->getValuesAt |
393 (column, i, buffers[ch][i*2], buffers[ch][i*2+1]); | 393 (column, i, buffers[ch][i*2], buffers[ch][i*2+1]); |
394 } | 394 } |
395 } else { | 395 } |
396 getFrames(ch, channelCount, | 396 } else { |
397 blockFrame, blockSize, buffers[ch]); | 397 getFrames(channelCount, blockFrame, blockSize, buffers); |
398 } | |
399 } | 398 } |
400 | 399 |
401 Vamp::Plugin::FeatureSet features = m_plugin->process | 400 Vamp::Plugin::FeatureSet features = m_plugin->process |
402 (buffers, Vamp::RealTime::frame2RealTime(blockFrame, sampleRate)); | 401 (buffers, Vamp::RealTime::frame2RealTime(blockFrame, sampleRate)); |
403 | 402 |
433 | 432 |
434 setCompletion(100); | 433 setCompletion(100); |
435 } | 434 } |
436 | 435 |
437 void | 436 void |
438 FeatureExtractionModelTransformer::getFrames(int channel, int channelCount, | 437 FeatureExtractionModelTransformer::getFrames(int channelCount, |
439 long startFrame, long size, | 438 long startFrame, long size, |
440 float *buffer) | 439 float **buffers) |
441 { | 440 { |
442 long offset = 0; | 441 long offset = 0; |
443 | 442 |
444 if (startFrame < 0) { | 443 if (startFrame < 0) { |
445 for (int i = 0; i < size && startFrame + i < 0; ++i) { | 444 for (int c = 0; c < channelCount; ++c) { |
446 buffer[i] = 0.0f; | 445 for (int i = 0; i < size && startFrame + i < 0; ++i) { |
446 buffers[c][i] = 0.0f; | |
447 } | |
447 } | 448 } |
448 offset = -startFrame; | 449 offset = -startFrame; |
449 size -= offset; | 450 size -= offset; |
450 if (size <= 0) return; | 451 if (size <= 0) return; |
451 startFrame = 0; | 452 startFrame = 0; |
452 } | 453 } |
453 | 454 |
454 DenseTimeValueModel *input = getConformingInput(); | 455 DenseTimeValueModel *input = getConformingInput(); |
455 if (!input) return; | 456 if (!input) return; |
456 | 457 |
457 long got = input->getData | 458 long got = 0; |
458 ((channelCount == 1 ? m_input.getChannel() : channel), | 459 |
459 startFrame, size, buffer + offset); | 460 if (channelCount == 1) { |
461 | |
462 got = input->getData(m_input.getChannel(), startFrame, size, | |
463 buffers[0] + offset); | |
464 | |
465 if (m_input.getChannel() == -1 && input->getChannelCount() > 1) { | |
466 // use mean instead of sum, as plugin input | |
467 float cc = float(input->getChannelCount()); | |
468 for (long i = 0; i < size; ++i) { | |
469 buffers[0][i + offset] /= cc; | |
470 } | |
471 } | |
472 | |
473 } else { | |
474 | |
475 float **writebuf = buffers; | |
476 if (offset > 0) { | |
477 writebuf = new float *[channelCount]; | |
478 for (int i = 0; i < channelCount; ++i) { | |
479 writebuf[i] = buffers[i] + offset; | |
480 } | |
481 } | |
482 | |
483 got = input->getData(0, channelCount-1, startFrame, size, writebuf); | |
484 | |
485 if (writebuf != buffers) delete[] writebuf; | |
486 } | |
460 | 487 |
461 while (got < size) { | 488 while (got < size) { |
462 buffer[offset + got] = 0.0; | 489 for (int c = 0; c < channelCount; ++c) { |
490 buffers[c][got + offset] = 0.0; | |
491 } | |
463 ++got; | 492 ++got; |
464 } | |
465 | |
466 if (m_input.getChannel() == -1 && channelCount == 1 && | |
467 input->getChannelCount() > 1) { | |
468 // use mean instead of sum, as plugin input | |
469 int cc = input->getChannelCount(); | |
470 for (long i = 0; i < size; ++i) { | |
471 buffer[i] /= cc; | |
472 } | |
473 } | 493 } |
474 } | 494 } |
475 | 495 |
476 void | 496 void |
477 FeatureExtractionModelTransformer::addFeature(size_t blockFrame, | 497 FeatureExtractionModelTransformer::addFeature(size_t blockFrame, |