changeset 110:ca565b18ba3e multiplex

Merge from default branch
author Chris Cannam
date Thu, 02 Oct 2014 14:54:48 +0100
parents 7b60603966cf (current diff) 78a7c77ba432 (diff)
children 0c2d8c945bbf
files runner/FeatureExtractionManager.cpp runner/FeatureExtractionManager.h
diffstat 6 files changed, 55 insertions(+), 68 deletions(-) [+]
line wrap: on
line diff
--- a/runner/FeatureExtractionManager.cpp	Thu Oct 02 08:16:42 2014 +0100
+++ b/runner/FeatureExtractionManager.cpp	Thu Oct 02 14:54:48 2014 +0100
@@ -351,6 +351,10 @@
         plugin = m_transformPluginMap[transform];
     }
 
+    if (m_plugins.find(plugin) == m_plugins.end()) {
+        m_orderedPlugins.push_back(plugin);
+    }
+
     m_plugins[plugin][transform] = writers;
 
     return true;
@@ -659,12 +663,11 @@
     int latestEndFrame = frameCount;
     bool haveExtents = false;
 
-    for (PluginMap::iterator pi = m_plugins.begin();
-         pi != m_plugins.end(); ++pi) {
+    foreach (Plugin *plugin, m_orderedPlugins) {
 
-        Plugin *plugin = pi->first;
+        PluginMap::iterator pi = m_plugins.find(plugin);
 
-//        std::cerr << "Calling reset on " << plugin << std::endl;
+        std::cerr << "Calling reset on " << plugin << std::endl;
         plugin->reset();
 
         for (TransformWriterMap::iterator ti = pi->second.begin();
@@ -687,6 +690,11 @@
                 latestEndFrame = startFrame + duration;
             }
 
+            cerr << "startFrame for transform " << startFrame << endl;
+            cerr << "duration for transform " << duration << endl;
+            cerr << "earliestStartFrame becomes " << earliestStartFrame << endl;
+            cerr << "latestEndFrame becomes " << latestEndFrame << endl;
+
             haveExtents = true;
 
             string outputId = transform.getOutput().toStdString();
@@ -718,8 +726,9 @@
     int startFrame = earliestStartFrame;
     int endFrame = latestEndFrame;
     
-    for (PluginMap::iterator pi = m_plugins.begin();
-         pi != m_plugins.end(); ++pi) { 
+    foreach (Plugin *plugin, m_orderedPlugins) {
+
+        PluginMap::iterator pi = m_plugins.find(plugin);
 
         for (TransformWriterMap::const_iterator ti = pi->second.begin();
              ti != pi->second.end(); ++ti) {
@@ -791,10 +800,9 @@
         Vamp::RealTime timestamp = Vamp::RealTime::frame2RealTime
             (i, m_sampleRate);
         
-        for (PluginMap::iterator pi = m_plugins.begin();
-             pi != m_plugins.end(); ++pi) {
+        foreach (Plugin *plugin, m_orderedPlugins) {
 
-            Plugin *plugin = pi->first;
+            PluginMap::iterator pi = m_plugins.find(plugin);
             Plugin::FeatureSet featureSet = plugin->process(data, timestamp);
 
             if (!m_summariesOnly) {
@@ -811,41 +819,9 @@
 
     lifemgr.destroy(); // deletes reader, data
         
-    // In order to ensure our results are written to the output in a
-    // fixed order (and not one that depends on the pointer value of
-    // each plugin on the heap in any given run of the program) we
-    // take the plugins' entries from the plugin map and sort them
-    // into a new, temporary map that is indexed by the first
-    // transform for each plugin. We then iterate over than instead of
-    // over m_plugins in order to get the right ordering.
+    foreach (Plugin *plugin, m_orderedPlugins) {
 
-    // This is not the most elegant way to do this -- it would be more
-    // elegant to impose an ordering directly on the plugins that are
-    // used as keys to m_plugins. But the plugin type comes from the
-    // Vamp SDK, so this change is more localised.
-
-    // Thanks to Matthias for this.
-
-    typedef map<Transform, PluginMap::value_type> OrderedPluginMap;
-    OrderedPluginMap orderedPlugins;
-
-    for (PluginMap::iterator pi = m_plugins.begin();
-         pi != m_plugins.end(); ++pi) { 
-        Transform firstForPlugin = (pi->second).begin()->first;
-        orderedPlugins.insert(OrderedPluginMap::value_type(firstForPlugin, *pi));
-    }
-
-    for (OrderedPluginMap::iterator superPi = orderedPlugins.begin();
-         superPi != orderedPlugins.end(); ++superPi) {
-
-        // The value we extract from this map is just the same as the
-        // value_type we get from iterating over our PluginMap
-        // directly -- but we happen to get them in the right order
-        // now because the map iterator is ordered by the Transform
-        // key type ordering
-        PluginMap::value_type pi = superPi->second;
-
-        Plugin *plugin = pi.first;
+        PluginMap::iterator pi = m_plugins.find(plugin);
         Plugin::FeatureSet featureSet = plugin->getRemainingFeatures();
 
         if (!m_summariesOnly) {
@@ -988,8 +964,9 @@
 
 void FeatureExtractionManager::finish()
 {
-    for (PluginMap::iterator pi = m_plugins.begin();
-         pi != m_plugins.end(); ++pi) {
+    foreach (Plugin *plugin, m_orderedPlugins) {
+
+        PluginMap::iterator pi = m_plugins.find(plugin);
 
         for (TransformWriterMap::iterator ti = pi->second.begin();
              ti != pi->second.end(); ++ti) {
--- a/runner/FeatureExtractionManager.h	Thu Oct 02 08:16:42 2014 +0100
+++ b/runner/FeatureExtractionManager.h	Thu Oct 02 14:54:48 2014 +0100
@@ -83,7 +83,17 @@
     typedef map<Transform, vector<FeatureWriter *> > TransformWriterMap;
     typedef map<Vamp::Plugin *, TransformWriterMap> PluginMap;
     PluginMap m_plugins;
-        
+
+    // When we run plugins, we want to run them in a known order so as
+    // to get the same results on each run of Sonic Annotator with the
+    // same transforms. But if we just iterate through our PluginMap,
+    // we get them in an arbitrary order based on pointer
+    // address. This vector provides an underlying order for us. Note
+    // that the TransformWriterMap is consistently ordered (because
+    // the key is a Transform which has a proper ordering) so using
+    // this gives us a consistent order across the whole PluginMap
+    vector<Vamp::Plugin *> m_orderedPlugins;
+
     // And a map back from transforms to their plugins.  Note that
     // this is keyed by transform, not transform ID -- two differently
     // configured transforms with the same ID must use different
--- a/tests/expected/transforms-basic-percussiononsets-multiple-outputs-start-and-duration.csv	Thu Oct 02 08:16:42 2014 +0100
+++ b/tests/expected/transforms-basic-percussiononsets-multiple-outputs-start-and-duration.csv	Thu Oct 02 14:54:48 2014 +0100
@@ -29,6 +29,7 @@
 ,1.325079365,162
 ,1.336689342,176
 ,1.348299319,169
+,1.650158730
 ,1.359909297,186
 ,1.371519274,153
 ,1.383129251,166
@@ -61,7 +62,6 @@
 ,1.696598639,160
 ,1.708208616,179
 ,1.719818594,164
-,1.650158730
 ,1.731428571,157
 ,1.743038548,157
 ,1.754648526,194
@@ -94,6 +94,7 @@
 ,2.068117913,179
 ,2.079727891,162
 ,2.091337868,168
+,2.416417233
 ,2.102947845,177
 ,2.114557823,179
 ,2.126167800,169
@@ -126,7 +127,6 @@
 ,2.439637188,161
 ,2.451247165,166
 ,2.462857142,189
-,2.416417233
 ,2.474467120,167
 ,2.486077097,166
 ,2.497687074,150
--- a/tests/test-include.sh	Thu Oct 02 08:16:42 2014 +0100
+++ b/tests/test-include.sh	Thu Oct 02 14:54:48 2014 +0100
@@ -22,4 +22,23 @@
     return `[ -z "$out" ]`
 }
 
+faildiff() {
+    echo "Test failed: $1"
+    if [ -n "$2" -a -n "$3" ]; then
+	echo "Output follows:"
+	echo "--"
+	cat $2
+	echo "--"
+	echo "Expected output follows:"
+	echo "--"
+	cat $3
+	echo "--"
+	echo "Diff:"
+	echo "--"
+	sdiff -w78 $2 $3
+	echo "--"
+    fi
+    exit 1
+}
 
+
--- a/tests/test-summaries.sh	Thu Oct 02 08:16:42 2014 +0100
+++ b/tests/test-summaries.sh	Thu Oct 02 14:54:48 2014 +0100
@@ -15,25 +15,6 @@
 
 . test-include.sh
 
-faildiff() {
-    echo "Test failed: $1"
-    if [ -n "$2" -a -n "$3" ]; then
-	echo "Output follows:"
-	echo "--"
-	cat $2
-	echo "--"
-	echo "Expected output follows:"
-	echo "--"
-	cat $3
-	echo "--"
-	echo "Diff:"
-	echo "--"
-	sdiff -w78 $2 $3
-	echo "--"
-    fi
-    exit 1
-}
-
 compare() {
     a=$1
     b=$2
--- a/tests/test-transforms-basic.sh	Thu Oct 02 08:16:42 2014 +0100
+++ b/tests/test-transforms-basic.sh	Thu Oct 02 14:54:48 2014 +0100
@@ -59,7 +59,7 @@
 	    fail "Fails to run transform $transform"
 
 	csvcompare $tmpfile2 $expected || \
-	    fail "Output mismatch for transform $transform"
+	    faildiff "Output mismatch for transform $transform" $tmpfile2 $expected
     done
 done