Mercurial > hg > sonic-annotator
comparison runner/FeatureExtractionManager.cpp @ 109:78a7c77ba432
A more general solution (I hope) to the problem of making sure transforms are always run in a consistent order
author | Chris Cannam |
---|---|
date | Thu, 02 Oct 2014 14:54:09 +0100 |
parents | fae326c22df5 |
children | ca565b18ba3e 74f7ad72fee6 |
comparison
equal
deleted
inserted
replaced
108:8b4924a9a072 | 109:78a7c77ba432 |
---|---|
348 } else { | 348 } else { |
349 | 349 |
350 plugin = m_transformPluginMap[transform]; | 350 plugin = m_transformPluginMap[transform]; |
351 } | 351 } |
352 | 352 |
353 if (m_plugins.find(plugin) == m_plugins.end()) { | |
354 m_orderedPlugins.push_back(plugin); | |
355 } | |
356 | |
353 m_plugins[plugin][transform] = writers; | 357 m_plugins[plugin][transform] = writers; |
354 | 358 |
355 return true; | 359 return true; |
356 } | 360 } |
357 | 361 |
611 | 615 |
612 int earliestStartFrame = 0; | 616 int earliestStartFrame = 0; |
613 int latestEndFrame = frameCount; | 617 int latestEndFrame = frameCount; |
614 bool haveExtents = false; | 618 bool haveExtents = false; |
615 | 619 |
616 for (PluginMap::iterator pi = m_plugins.begin(); | 620 foreach (Plugin *plugin, m_orderedPlugins) { |
617 pi != m_plugins.end(); ++pi) { | 621 |
618 | 622 PluginMap::iterator pi = m_plugins.find(plugin); |
619 Plugin *plugin = pi->first; | 623 |
620 | 624 std::cerr << "Calling reset on " << plugin << std::endl; |
621 // std::cerr << "Calling reset on " << plugin << std::endl; | |
622 plugin->reset(); | 625 plugin->reset(); |
623 | 626 |
624 for (TransformWriterMap::iterator ti = pi->second.begin(); | 627 for (TransformWriterMap::iterator ti = pi->second.begin(); |
625 ti != pi->second.end(); ++ti) { | 628 ti != pi->second.end(); ++ti) { |
626 | 629 |
638 earliestStartFrame = startFrame; | 641 earliestStartFrame = startFrame; |
639 } | 642 } |
640 if (!haveExtents || startFrame + duration > latestEndFrame) { | 643 if (!haveExtents || startFrame + duration > latestEndFrame) { |
641 latestEndFrame = startFrame + duration; | 644 latestEndFrame = startFrame + duration; |
642 } | 645 } |
646 | |
647 cerr << "startFrame for transform " << startFrame << endl; | |
648 cerr << "duration for transform " << duration << endl; | |
649 cerr << "earliestStartFrame becomes " << earliestStartFrame << endl; | |
650 cerr << "latestEndFrame becomes " << latestEndFrame << endl; | |
643 | 651 |
644 haveExtents = true; | 652 haveExtents = true; |
645 | 653 |
646 string outputId = transform.getOutput().toStdString(); | 654 string outputId = transform.getOutput().toStdString(); |
647 if (m_pluginOutputs[plugin].find(outputId) == | 655 if (m_pluginOutputs[plugin].find(outputId) == |
670 } | 678 } |
671 | 679 |
672 int startFrame = earliestStartFrame; | 680 int startFrame = earliestStartFrame; |
673 int endFrame = latestEndFrame; | 681 int endFrame = latestEndFrame; |
674 | 682 |
675 for (PluginMap::iterator pi = m_plugins.begin(); | 683 foreach (Plugin *plugin, m_orderedPlugins) { |
676 pi != m_plugins.end(); ++pi) { | 684 |
685 PluginMap::iterator pi = m_plugins.find(plugin); | |
677 | 686 |
678 for (TransformWriterMap::const_iterator ti = pi->second.begin(); | 687 for (TransformWriterMap::const_iterator ti = pi->second.begin(); |
679 ti != pi->second.end(); ++ti) { | 688 ti != pi->second.end(); ++ti) { |
680 | 689 |
681 const vector<FeatureWriter *> &writers = ti->second; | 690 const vector<FeatureWriter *> &writers = ti->second; |
743 } | 752 } |
744 | 753 |
745 Vamp::RealTime timestamp = Vamp::RealTime::frame2RealTime | 754 Vamp::RealTime timestamp = Vamp::RealTime::frame2RealTime |
746 (i, m_sampleRate); | 755 (i, m_sampleRate); |
747 | 756 |
748 for (PluginMap::iterator pi = m_plugins.begin(); | 757 foreach (Plugin *plugin, m_orderedPlugins) { |
749 pi != m_plugins.end(); ++pi) { | 758 |
750 | 759 PluginMap::iterator pi = m_plugins.find(plugin); |
751 Plugin *plugin = pi->first; | |
752 Plugin::FeatureSet featureSet = plugin->process(data, timestamp); | 760 Plugin::FeatureSet featureSet = plugin->process(data, timestamp); |
753 | 761 |
754 if (!m_summariesOnly) { | 762 if (!m_summariesOnly) { |
755 writeFeatures(audioSource, plugin, featureSet); | 763 writeFeatures(audioSource, plugin, featureSet); |
756 } | 764 } |
763 | 771 |
764 // std::cerr << "FeatureExtractionManager: deleting audio file reader" << std::endl; | 772 // std::cerr << "FeatureExtractionManager: deleting audio file reader" << std::endl; |
765 | 773 |
766 lifemgr.destroy(); // deletes reader, data | 774 lifemgr.destroy(); // deletes reader, data |
767 | 775 |
768 // In order to ensure our results are written to the output in a | 776 foreach (Plugin *plugin, m_orderedPlugins) { |
769 // fixed order (and not one that depends on the pointer value of | 777 |
770 // each plugin on the heap in any given run of the program) we | 778 PluginMap::iterator pi = m_plugins.find(plugin); |
771 // take the plugins' entries from the plugin map and sort them | |
772 // into a new, temporary map that is indexed by the first | |
773 // transform for each plugin. We then iterate over than instead of | |
774 // over m_plugins in order to get the right ordering. | |
775 | |
776 // This is not the most elegant way to do this -- it would be more | |
777 // elegant to impose an ordering directly on the plugins that are | |
778 // used as keys to m_plugins. But the plugin type comes from the | |
779 // Vamp SDK, so this change is more localised. | |
780 | |
781 // Thanks to Matthias for this. | |
782 | |
783 typedef map<Transform, PluginMap::value_type> OrderedPluginMap; | |
784 OrderedPluginMap orderedPlugins; | |
785 | |
786 for (PluginMap::iterator pi = m_plugins.begin(); | |
787 pi != m_plugins.end(); ++pi) { | |
788 Transform firstForPlugin = (pi->second).begin()->first; | |
789 orderedPlugins.insert(OrderedPluginMap::value_type(firstForPlugin, *pi)); | |
790 } | |
791 | |
792 for (OrderedPluginMap::iterator superPi = orderedPlugins.begin(); | |
793 superPi != orderedPlugins.end(); ++superPi) { | |
794 | |
795 // The value we extract from this map is just the same as the | |
796 // value_type we get from iterating over our PluginMap | |
797 // directly -- but we happen to get them in the right order | |
798 // now because the map iterator is ordered by the Transform | |
799 // key type ordering | |
800 PluginMap::value_type pi = superPi->second; | |
801 | |
802 Plugin *plugin = pi.first; | |
803 Plugin::FeatureSet featureSet = plugin->getRemainingFeatures(); | 779 Plugin::FeatureSet featureSet = plugin->getRemainingFeatures(); |
804 | 780 |
805 if (!m_summariesOnly) { | 781 if (!m_summariesOnly) { |
806 writeFeatures(audioSource, plugin, featureSet); | 782 writeFeatures(audioSource, plugin, featureSet); |
807 } | 783 } |
940 } | 916 } |
941 } | 917 } |
942 | 918 |
943 void FeatureExtractionManager::finish() | 919 void FeatureExtractionManager::finish() |
944 { | 920 { |
945 for (PluginMap::iterator pi = m_plugins.begin(); | 921 foreach (Plugin *plugin, m_orderedPlugins) { |
946 pi != m_plugins.end(); ++pi) { | 922 |
923 PluginMap::iterator pi = m_plugins.find(plugin); | |
947 | 924 |
948 for (TransformWriterMap::iterator ti = pi->second.begin(); | 925 for (TransformWriterMap::iterator ti = pi->second.begin(); |
949 ti != pi->second.end(); ++ti) { | 926 ti != pi->second.end(); ++ti) { |
950 | 927 |
951 vector<FeatureWriter *> &writers = ti->second; | 928 vector<FeatureWriter *> &writers = ti->second; |