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,