comparison runner/FeatureExtractionManager.cpp @ 99:526feaad5820 start-duration

Start time and duration now working
author Chris Cannam
date Wed, 01 Oct 2014 14:06:40 +0100
parents 03b1d83fca29
children 010fbf2a3fba
comparison
equal deleted inserted replaced
97:54565c08c197 99:526feaad5820
371 } 371 }
372 372
373 bool FeatureExtractionManager::addFeatureExtractorFromFile 373 bool FeatureExtractionManager::addFeatureExtractorFromFile
374 (QString transformXmlFile, const vector<FeatureWriter*> &writers) 374 (QString transformXmlFile, const vector<FeatureWriter*> &writers)
375 { 375 {
376 RDFTransformFactory factory 376 bool tryRdf = true;
377 (QUrl::fromLocalFile(QFileInfo(transformXmlFile).absoluteFilePath()) 377
378 .toString()); 378 if (transformXmlFile.endsWith(".xml") || transformXmlFile.endsWith(".XML")) {
379 ProgressPrinter printer("Parsing transforms RDF file"); 379 // We don't support RDF-XML (and nor does the underlying
380 std::vector<Transform> transforms = factory.getTransforms(&printer); 380 // parser library) so skip the RDF parse if the filename
381 if (!factory.isOK()) { 381 // suggests XML, to avoid puking out a load of errors from
382 cerr << "WARNING: FeatureExtractionManager::addFeatureExtractorFromFile: Failed to parse transforms file: " << factory.getErrorString().toStdString() << endl; 382 // feeding XML to a Turtle parser
383 if (factory.isRDF()) { 383 tryRdf = false;
384 return false; // no point trying it as XML 384 }
385 } 385
386 } 386 if (tryRdf) {
387 if (!transforms.empty()) { 387 RDFTransformFactory factory
388 bool success = true; 388 (QUrl::fromLocalFile(QFileInfo(transformXmlFile).absoluteFilePath())
389 for (int i = 0; i < (int)transforms.size(); ++i) { 389 .toString());
390 if (!addFeatureExtractor(transforms[i], writers)) { 390 ProgressPrinter printer("Parsing transforms RDF file");
391 success = false; 391 std::vector<Transform> transforms = factory.getTransforms(&printer);
392 } 392 if (!factory.isOK()) {
393 } 393 cerr << "WARNING: FeatureExtractionManager::addFeatureExtractorFromFile: Failed to parse transforms file: " << factory.getErrorString().toStdString() << endl;
394 return success; 394 if (factory.isRDF()) {
395 return false; // no point trying it as XML
396 }
397 }
398 if (!transforms.empty()) {
399 bool success = true;
400 for (int i = 0; i < (int)transforms.size(); ++i) {
401 if (!addFeatureExtractor(transforms[i], writers)) {
402 success = false;
403 }
404 }
405 return success;
406 }
395 } 407 }
396 408
397 QFile file(transformXmlFile); 409 QFile file(transformXmlFile);
398 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { 410 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
399 cerr << "ERROR: Failed to open transform XML file \"" 411 cerr << "ERROR: Failed to open transform XML file \""
590 602
591 size_t frameCount = reader->getFrameCount(); 603 size_t frameCount = reader->getFrameCount();
592 604
593 // cerr << "file has " << frameCount << " frames" << endl; 605 // cerr << "file has " << frameCount << " frames" << endl;
594 606
607 int earliestStartFrame = 0;
608 int latestEndFrame = frameCount;
609 bool haveExtents = false;
610
595 for (PluginMap::iterator pi = m_plugins.begin(); 611 for (PluginMap::iterator pi = m_plugins.begin();
596 pi != m_plugins.end(); ++pi) { 612 pi != m_plugins.end(); ++pi) {
597 613
598 Plugin *plugin = pi->first; 614 Plugin *plugin = pi->first;
599 615
603 for (TransformWriterMap::iterator ti = pi->second.begin(); 619 for (TransformWriterMap::iterator ti = pi->second.begin();
604 ti != pi->second.end(); ++ti) { 620 ti != pi->second.end(); ++ti) {
605 621
606 const Transform &transform = ti->first; 622 const Transform &transform = ti->first;
607 623
608 //!!! we may want to set the start and duration times for extraction 624 int startFrame = RealTime::realTime2Frame
609 // in the transform record (defaults of zero indicate extraction 625 (transform.getStartTime(), m_sampleRate);
610 // from the whole file) 626 int duration = RealTime::realTime2Frame
611 // transform.setStartTime(RealTime::zeroTime); 627 (transform.getDuration(), m_sampleRate);
612 // transform.setDuration 628 if (duration == 0) {
613 // (RealTime::frame2RealTime(reader->getFrameCount(), m_sampleRate)); 629 duration = frameCount - startFrame;
630 }
631
632 if (!haveExtents || startFrame < earliestStartFrame) {
633 earliestStartFrame = startFrame;
634 }
635 if (!haveExtents || startFrame + duration > latestEndFrame) {
636 latestEndFrame = startFrame + duration;
637 }
638
639 haveExtents = true;
614 640
615 string outputId = transform.getOutput().toStdString(); 641 string outputId = transform.getOutput().toStdString();
616 if (m_pluginOutputs[plugin].find(outputId) == 642 if (m_pluginOutputs[plugin].find(outputId) ==
617 m_pluginOutputs[plugin].end()) { 643 m_pluginOutputs[plugin].end()) {
618 //!!! throw? 644 //!!! throw?
636 */ 662 */
637 } 663 }
638 } 664 }
639 } 665 }
640 666
641 long startFrame = 0; 667 int startFrame = earliestStartFrame;
642 long endFrame = frameCount; 668 int endFrame = latestEndFrame;
643
644 /*!!! No -- there is no single transform to pull this stuff from --
645 * the transforms may have various start and end times, need to be far
646 * cleverer about this if we're going to support them
647
648 RealTime trStartRT = transform.getStartTime();
649 RealTime trDurationRT = transform.getDuration();
650
651 long trStart = RealTime::realTime2Frame(trStartRT, m_sampleRate);
652 long trDuration = RealTime::realTime2Frame(trDurationRT, m_sampleRate);
653
654 if (trStart == 0 || trStart < startFrame) {
655 trStart = startFrame;
656 }
657
658 if (trDuration == 0) {
659 trDuration = endFrame - trStart;
660 }
661 if (trStart + trDuration > endFrame) {
662 trDuration = endFrame - trStart;
663 }
664
665 startFrame = trStart;
666 endFrame = trStart + trDuration;
667 */
668 669
669 for (PluginMap::iterator pi = m_plugins.begin(); 670 for (PluginMap::iterator pi = m_plugins.begin();
670 pi != m_plugins.end(); ++pi) { 671 pi != m_plugins.end(); ++pi) {
671 672
672 for (TransformWriterMap::const_iterator ti = pi->second.begin(); 673 for (TransformWriterMap::const_iterator ti = pi->second.begin();
686 } 687 }
687 688
688 ProgressPrinter extractionProgress("Extracting and writing features..."); 689 ProgressPrinter extractionProgress("Extracting and writing features...");
689 int progress = 0; 690 int progress = 0;
690 691
691 for (long i = startFrame; i < endFrame; i += m_blockSize) { 692 for (int i = startFrame; i < endFrame; i += m_blockSize) {
692 693
693 //!!! inefficient, although much of the inefficiency may be 694 //!!! inefficient, although much of the inefficiency may be
694 // susceptible to optimisation 695 // susceptible to compiler optimisation
695 696
696 SampleBlock frames; 697 SampleBlock frames;
697 reader->getInterleavedFrames(i, m_blockSize, frames); 698 reader->getInterleavedFrames(i, m_blockSize, frames);
698 699
699 // We have to do our own channel handling here; we can't just 700 // We have to do our own channel handling here; we can't just