comparison runner/FeatureExtractionManager.cpp @ 106:de76b2df518f multiplex

Start on multiplex implementation
author Chris Cannam
date Wed, 01 Oct 2014 18:38:32 +0100
parents fae326c22df5
children 7b60603966cf
comparison
equal deleted inserted replaced
105:76d9d86ae6cd 106:de76b2df518f
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>
426 Transform transform(qs); 427 Transform transform(qs);
427 428
428 return addFeatureExtractor(transform, writers); 429 return addFeatureExtractor(transform, writers);
429 } 430 }
430 431
431 void FeatureExtractionManager::addSource(QString audioSource) 432 void FeatureExtractionManager::addSource(QString audioSource, bool willMultiplex)
432 { 433 {
433 if (QFileInfo(audioSource).suffix().toLower() == "m3u") { 434 if (QFileInfo(audioSource).suffix().toLower() == "m3u") {
434 ProgressPrinter retrievalProgress("Opening playlist file..."); 435 ProgressPrinter retrievalProgress("Opening playlist file...");
435 FileSource source(audioSource, &retrievalProgress); 436 FileSource source(audioSource, &retrievalProgress);
436 if (!source.isAvailable()) { 437 if (!source.isAvailable()) {
441 source.waitForData(); 442 source.waitForData();
442 PlaylistFileReader reader(source); 443 PlaylistFileReader reader(source);
443 if (reader.isOK()) { 444 if (reader.isOK()) {
444 vector<QString> files = reader.load(); 445 vector<QString> files = reader.load();
445 for (int i = 0; i < (int)files.size(); ++i) { 446 for (int i = 0; i < (int)files.size(); ++i) {
446 addSource(files[i]); 447 addSource(files[i], willMultiplex);
447 } 448 }
448 return; 449 return;
449 } else { 450 } else {
450 cerr << "ERROR: Playlist \"" << audioSource.toStdString() 451 cerr << "ERROR: Playlist \"" << audioSource.toStdString()
451 << "\" could not be opened" << endl; 452 << "\" could not be opened" << endl;
485 486
486 retrievalProgress.done(); 487 retrievalProgress.done();
487 488
488 cerr << "File or URL \"" << audioSource.toStdString() << "\" opened successfully" << endl; 489 cerr << "File or URL \"" << audioSource.toStdString() << "\" opened successfully" << endl;
489 490
490 if (m_channels == 0) { 491 if (willMultiplex) {
491 m_channels = reader->getChannelCount(); 492 ++m_channels; // channel count is simply number of sources
492 cerr << "Taking default channel count of " 493 } else {
493 << reader->getChannelCount() << " from file" << endl; 494 if (m_channels == 0) {
495 m_channels = reader->getChannelCount();
496 cerr << "Taking default channel count of "
497 << reader->getChannelCount() << " from file" << endl;
498 }
494 } 499 }
495 500
496 if (m_defaultSampleRate == 0) { 501 if (m_defaultSampleRate == 0) {
497 m_defaultSampleRate = reader->getNativeRate(); 502 m_defaultSampleRate = reader->getNativeRate();
498 cerr << "Taking default sample rate of " 503 cerr << "Taking default sample rate of "
507 void FeatureExtractionManager::extractFeatures(QString audioSource, bool force) 512 void FeatureExtractionManager::extractFeatures(QString audioSource, bool force)
508 { 513 {
509 if (m_plugins.empty()) return; 514 if (m_plugins.empty()) return;
510 515
511 if (QFileInfo(audioSource).suffix().toLower() == "m3u") { 516 if (QFileInfo(audioSource).suffix().toLower() == "m3u") {
517 //!!! This shouldn't happen here, it should be done in
518 //!!! main.cpp when assembling the sources list
512 FileSource source(audioSource); 519 FileSource source(audioSource);
513 PlaylistFileReader reader(source); 520 PlaylistFileReader reader(source);
514 if (reader.isOK()) { 521 if (reader.isOK()) {
515 vector<QString> files = reader.load(); 522 vector<QString> files = reader.load();
516 for (int i = 0; i < (int)files.size(); ++i) { 523 for (int i = 0; i < (int)files.size(); ++i) {
544 if (m_channels == 0) { 551 if (m_channels == 0) {
545 throw FileOperationFailed 552 throw FileOperationFailed
546 (audioSource, "internal error: have sources and plugins, but no channel count"); 553 (audioSource, "internal error: have sources and plugins, but no channel count");
547 } 554 }
548 555
549 AudioFileReader *reader = 0; 556 AudioFileReader *reader = prepareReader(audioSource);
550 557 extractFeaturesFor(reader, audioSource); // Note this also deletes reader
551 if (m_readyReaders.contains(audioSource)) { 558 }
552 reader = m_readyReaders[audioSource]; 559
553 m_readyReaders.remove(audioSource); 560 void FeatureExtractionManager::extractFeaturesMultiplexed(QStringList sources)
554 if (reader->getChannelCount() != m_channels || 561 {
555 reader->getSampleRate() != m_sampleRate) { 562 if (m_plugins.empty() || sources.empty()) return;
563
564 QString nominalSource = sources[0];
565
566 testOutputFiles(nominalSource);
567
568 if (m_sampleRate == 0) {
569 throw FileOperationFailed
570 (nominalSource, "internal error: have sources and plugins, but no sample rate");
571 }
572 if (m_channels == 0) {
573 throw FileOperationFailed
574 (nominalSource, "internal error: have sources and plugins, but no channel count");
575 }
576
577 QList<AudioFileReader *> readers;
578 foreach (QString source, sources) {
579 AudioFileReader *reader = prepareReader(source);
580 readers.push_back(reader);
581 }
582
583 AudioFileReader *reader = new MultiplexedReader(readers);
584 extractFeaturesFor(reader, nominalSource); // Note this also deletes reader
585 }
586
587 AudioFileReader *
588 FeatureExtractionManager::prepareReader(QString source)
589 {
590 if (m_readyReaders.contains(source)) {
591 reader = m_readyReaders[source];
592 m_readyReaders.remove(source);
593 if (reader->getSampleRate() != m_sampleRate) {
556 // can't use this; open it again 594 // can't use this; open it again
557 delete reader; 595 delete reader;
558 reader = 0; 596 reader = 0;
559 } 597 }
560 } 598 }
561 if (!reader) { 599 if (!reader) {
562 ProgressPrinter retrievalProgress("Retrieving audio data..."); 600 ProgressPrinter retrievalProgress("Retrieving audio data...");
563 FileSource source(audioSource, &retrievalProgress); 601 FileSource fs(source, &retrievalProgress);
564 source.waitForData(); 602 fs.waitForData();
565 reader = AudioFileReaderFactory::createReader 603 reader = AudioFileReaderFactory::createReader
566 (source, m_sampleRate, false, &retrievalProgress); 604 (fs, m_sampleRate, false, &retrievalProgress);
567 retrievalProgress.done(); 605 retrievalProgress.done();
568 } 606 }
569
570 if (!reader) { 607 if (!reader) {
571 throw FailedToOpenFile(audioSource); 608 throw FailedToOpenFile(audioSource);
572 } 609 }
610 return reader;
611 }
612
613 void
614 FeatureExtractionManager::extractFeaturesFor(AudioFileReader *reader,
615 QString audioSource)
616 {
617 // Note: This also deletes reader
573 618
574 cerr << "Audio file \"" << audioSource.toStdString() << "\": " 619 cerr << "Audio file \"" << audioSource.toStdString() << "\": "
575 << reader->getChannelCount() << "ch at " 620 << reader->getChannelCount() << "ch at "
576 << reader->getNativeRate() << "Hz" << endl; 621 << reader->getNativeRate() << "Hz" << endl;
577 if (reader->getChannelCount() != m_channels || 622 if (reader->getChannelCount() != m_channels ||