# HG changeset patch # User Chris Cannam # Date 1326120470 0 # Node ID 513230b1924818254a7dd2ba237c5ae3ae416e3b # Parent 52d71675a953abda37134d138665774f29d07fcf Fix #311 following the patch from Matthias diff -r 52d71675a953 -r 513230b19248 runner/FeatureExtractionManager.cpp --- a/runner/FeatureExtractionManager.cpp Mon Jan 09 14:23:32 2012 +0000 +++ b/runner/FeatureExtractionManager.cpp Mon Jan 09 14:47:50 2012 +0000 @@ -757,11 +757,44 @@ // std::cerr << "FeatureExtractionManager: deleting audio file reader" << std::endl; 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. + + // 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. + + // Not the same as PluginMap::value_type (which has const key) + typedef pair PluginMapEntry; + typedef map TransformOrderedPluginMap; + TransformOrderedPluginMap orderedPlugins; + for (PluginMap::iterator pi = m_plugins.begin(); pi != m_plugins.end(); ++pi) { + Transform firstForPlugin = (pi->second).begin()->first; + orderedPlugins[firstForPlugin] = PluginMapEntry(pi->first, pi->second); + } - Plugin *plugin = pi->first; + for (TransformOrderedPluginMap::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 + PluginMapEntry pi = superPi->second; + + Plugin *plugin = pi.first; Plugin::FeatureSet featureSet = plugin->getRemainingFeatures(); if (!m_summariesOnly) {