Mercurial > hg > sonic-annotator
comparison runner/FeatureExtractionManager.cpp @ 115:95de6db296a1
Merge from multiplex branch
author | Chris Cannam |
---|---|
date | Fri, 03 Oct 2014 15:07:19 +0100 |
parents | 297f9e415e39 |
children | 1c0799754670 |
comparison
equal
deleted
inserted
replaced
111:74f7ad72fee6 | 115:95de6db296a1 |
---|---|
12 License, or (at your option) any later version. See the file | 12 License, or (at your option) any later version. See the file |
13 COPYING included with this distribution for more information. | 13 COPYING included with this distribution for more information. |
14 */ | 14 */ |
15 | 15 |
16 #include "FeatureExtractionManager.h" | 16 #include "FeatureExtractionManager.h" |
17 #include "MultiplexedReader.h" | |
17 | 18 |
18 #include <vamp-hostsdk/PluginChannelAdapter.h> | 19 #include <vamp-hostsdk/PluginChannelAdapter.h> |
19 #include <vamp-hostsdk/PluginBufferingAdapter.h> | 20 #include <vamp-hostsdk/PluginBufferingAdapter.h> |
20 #include <vamp-hostsdk/PluginInputDomainAdapter.h> | 21 #include <vamp-hostsdk/PluginInputDomainAdapter.h> |
21 #include <vamp-hostsdk/PluginSummarisingAdapter.h> | 22 #include <vamp-hostsdk/PluginSummarisingAdapter.h> |
429 Transform transform(qs); | 430 Transform transform(qs); |
430 | 431 |
431 return addFeatureExtractor(transform, writers); | 432 return addFeatureExtractor(transform, writers); |
432 } | 433 } |
433 | 434 |
434 void FeatureExtractionManager::addSource(QString audioSource) | 435 void FeatureExtractionManager::addSource(QString audioSource, bool willMultiplex) |
435 { | 436 { |
436 std::cerr << "Have audio source: \"" << audioSource.toStdString() << "\"" << std::endl; | 437 std::cerr << "Have audio source: \"" << audioSource.toStdString() << "\"" << std::endl; |
437 | 438 |
438 // We don't actually do anything with it here, unless it's the | 439 // We don't actually do anything with it here, unless it's the |
439 // first audio source and we need it to establish default channel | 440 // first audio source and we need it to establish default channel |
465 | 466 |
466 retrievalProgress.done(); | 467 retrievalProgress.done(); |
467 | 468 |
468 cerr << "File or URL \"" << audioSource.toStdString() << "\" opened successfully" << endl; | 469 cerr << "File or URL \"" << audioSource.toStdString() << "\" opened successfully" << endl; |
469 | 470 |
470 if (m_channels == 0) { | 471 if (!willMultiplex) { |
471 m_channels = reader->getChannelCount(); | 472 if (m_channels == 0) { |
472 cerr << "Taking default channel count of " | 473 m_channels = reader->getChannelCount(); |
473 << reader->getChannelCount() << " from file" << endl; | 474 cerr << "Taking default channel count of " |
475 << reader->getChannelCount() << " from file" << endl; | |
476 } | |
474 } | 477 } |
475 | 478 |
476 if (m_defaultSampleRate == 0) { | 479 if (m_defaultSampleRate == 0) { |
477 m_defaultSampleRate = reader->getNativeRate(); | 480 m_defaultSampleRate = reader->getNativeRate(); |
478 cerr << "Taking default sample rate of " | 481 cerr << "Taking default sample rate of " |
480 cerr << "(Note: Default may be overridden by transforms)" << endl; | 483 cerr << "(Note: Default may be overridden by transforms)" << endl; |
481 } | 484 } |
482 | 485 |
483 m_readyReaders[audioSource] = reader; | 486 m_readyReaders[audioSource] = reader; |
484 } | 487 } |
485 } | 488 |
486 | 489 if (willMultiplex) { |
487 void FeatureExtractionManager::extractFeatures(QString audioSource, bool force) | 490 ++m_channels; // channel count is simply number of sources |
491 cerr << "Multiplexing, incremented target channel count to " | |
492 << m_channels << endl; | |
493 } | |
494 } | |
495 | |
496 void FeatureExtractionManager::extractFeatures(QString audioSource) | |
488 { | 497 { |
489 if (m_plugins.empty()) return; | 498 if (m_plugins.empty()) return; |
490 | 499 |
491 testOutputFiles(audioSource); | 500 testOutputFiles(audioSource); |
492 | 501 |
497 if (m_channels == 0) { | 506 if (m_channels == 0) { |
498 throw FileOperationFailed | 507 throw FileOperationFailed |
499 (audioSource, "internal error: have sources and plugins, but no channel count"); | 508 (audioSource, "internal error: have sources and plugins, but no channel count"); |
500 } | 509 } |
501 | 510 |
511 AudioFileReader *reader = prepareReader(audioSource); | |
512 extractFeaturesFor(reader, audioSource); // Note this also deletes reader | |
513 } | |
514 | |
515 void FeatureExtractionManager::extractFeaturesMultiplexed(QStringList sources) | |
516 { | |
517 if (m_plugins.empty() || sources.empty()) return; | |
518 | |
519 QString nominalSource = sources[0]; | |
520 | |
521 testOutputFiles(nominalSource); | |
522 | |
523 if (m_sampleRate == 0) { | |
524 throw FileOperationFailed | |
525 (nominalSource, "internal error: have sources and plugins, but no sample rate"); | |
526 } | |
527 if (m_channels == 0) { | |
528 throw FileOperationFailed | |
529 (nominalSource, "internal error: have sources and plugins, but no channel count"); | |
530 } | |
531 | |
532 QList<AudioFileReader *> readers; | |
533 foreach (QString source, sources) { | |
534 AudioFileReader *reader = prepareReader(source); | |
535 readers.push_back(reader); | |
536 } | |
537 | |
538 AudioFileReader *reader = new MultiplexedReader(readers); | |
539 extractFeaturesFor(reader, nominalSource); // Note this also deletes reader | |
540 } | |
541 | |
542 AudioFileReader * | |
543 FeatureExtractionManager::prepareReader(QString source) | |
544 { | |
502 AudioFileReader *reader = 0; | 545 AudioFileReader *reader = 0; |
503 | 546 if (m_readyReaders.contains(source)) { |
504 if (m_readyReaders.contains(audioSource)) { | 547 reader = m_readyReaders[source]; |
505 reader = m_readyReaders[audioSource]; | 548 m_readyReaders.remove(source); |
506 m_readyReaders.remove(audioSource); | 549 if (reader->getSampleRate() != m_sampleRate) { |
507 if (reader->getChannelCount() != m_channels || | |
508 reader->getSampleRate() != m_sampleRate) { | |
509 // can't use this; open it again | 550 // can't use this; open it again |
510 delete reader; | 551 delete reader; |
511 reader = 0; | 552 reader = 0; |
512 } | 553 } |
513 } | 554 } |
514 if (!reader) { | 555 if (!reader) { |
515 ProgressPrinter retrievalProgress("Retrieving audio data..."); | 556 ProgressPrinter retrievalProgress("Retrieving audio data..."); |
516 FileSource source(audioSource, &retrievalProgress); | 557 FileSource fs(source, &retrievalProgress); |
517 source.waitForData(); | 558 fs.waitForData(); |
518 reader = AudioFileReaderFactory::createReader | 559 reader = AudioFileReaderFactory::createReader |
519 (source, m_sampleRate, false, &retrievalProgress); | 560 (fs, m_sampleRate, false, &retrievalProgress); |
520 retrievalProgress.done(); | 561 retrievalProgress.done(); |
521 } | 562 } |
522 | |
523 if (!reader) { | 563 if (!reader) { |
524 throw FailedToOpenFile(audioSource); | 564 throw FailedToOpenFile(source); |
525 } | 565 } |
566 return reader; | |
567 } | |
568 | |
569 void | |
570 FeatureExtractionManager::extractFeaturesFor(AudioFileReader *reader, | |
571 QString audioSource) | |
572 { | |
573 // Note: This also deletes reader | |
526 | 574 |
527 cerr << "Audio file \"" << audioSource.toStdString() << "\": " | 575 cerr << "Audio file \"" << audioSource.toStdString() << "\": " |
528 << reader->getChannelCount() << "ch at " | 576 << reader->getChannelCount() << "ch at " |
529 << reader->getNativeRate() << "Hz" << endl; | 577 << reader->getNativeRate() << "Hz" << endl; |
530 if (reader->getChannelCount() != m_channels || | 578 if (reader->getChannelCount() != m_channels || |
531 reader->getNativeRate() != m_sampleRate) { | 579 reader->getNativeRate() != m_sampleRate) { |
532 cerr << "NOTE: File will be mixed or resampled for processing: " | 580 cerr << "NOTE: File will be mixed or resampled for processing, to: " |
533 << m_channels << "ch at " | 581 << m_channels << "ch at " |
534 << m_sampleRate << "Hz" << endl; | 582 << m_sampleRate << "Hz" << endl; |
535 } | 583 } |
536 | 584 |
537 // allocate audio buffers | 585 // allocate audio buffers |