changeset 239:09ed4261f3ca json-ld

Merge from default branch
author Chris Cannam
date Tue, 01 Mar 2016 14:40:24 +0000 (2016-03-01)
parents d582d5662010 (current diff) 0c87c4fca256 (diff)
children ef73773fb7e9
files runner.pro
diffstat 23 files changed, 272 insertions(+), 104 deletions(-) [+]
line wrap: on
line diff
--- a/.hgsubstate	Thu Feb 25 12:36:08 2016 +0000
+++ b/.hgsubstate	Tue Mar 01 14:40:24 2016 +0000
@@ -1,4 +1,4 @@
 d16f0fd6db6104d87882bc43788a3bb1b0f8c528 dataquay
 55ece8862b6d3a54aad271a53f9c1615e5d3bcf8 sv-dependency-builds
-7c4f4701b49fe6d0b3388788866933f03cc7849c svcore
-632d90c185ecc8655f7a85ba58dc568351449dfd vamp-plugin-sdk
+134ce7667256fb204f3bebd293c252bc57cbe07e svcore
+55de53d7c777008997721bb43051a67c3b3772d2 vamp-plugin-sdk
--- a/runner.pro	Thu Feb 25 12:36:08 2016 +0000
+++ b/runner.pro	Tue Mar 01 14:40:24 2016 +0000
@@ -13,6 +13,8 @@
     LIBS += -Lsv-dependency-builds/osx/lib
 }
 
+INCLUDEPATH += vamp-plugin-sdk
+
 exists(config.pri) {
     include(config.pri)
 }
@@ -48,10 +50,6 @@
 # look for win32 features
 win32-x-g++:QMAKE_LFLAGS += -Wl,-subsystem,console
 
-# If you have compiled your Vamp plugin SDK with FFTW (using its
-# HAVE_FFTW3 flag), you can define the same flag here to ensure the
-# program saves and restores FFTW wisdom in its configuration properly
-#
 DEFINES += HAVE_FFTW3
 
 TARGET = sonic-annotator
@@ -113,6 +111,7 @@
         vamp-plugin-sdk/src/vamp-hostsdk/PluginSummarisingAdapter.cpp \
         vamp-plugin-sdk/src/vamp-hostsdk/PluginWrapper.cpp \
         vamp-plugin-sdk/src/vamp-hostsdk/RealTime.cpp \
+        vamp-plugin-sdk/src/vamp-hostsdk/Files.cpp \
 	runner/main.cpp \
 	runner/DefaultFeatureWriter.cpp \
 	runner/FeatureExtractionManager.cpp \
--- a/runner/FeatureExtractionManager.cpp	Thu Feb 25 12:36:08 2016 +0000
+++ b/runner/FeatureExtractionManager.cpp	Tue Mar 01 14:40:24 2016 +0000
@@ -323,6 +323,8 @@
                  << " (adapter step and block size " << m_blockSize << ")"
                  << endl;
 
+//            cerr << "NOTE: That transform is: " << transform.toXmlString() << endl;
+            
             if (pida) {
                 cerr << "NOTE: PluginInputDomainAdapter timestamp adjustment is "
 
@@ -382,8 +384,11 @@
 
         m_transformPluginMap[transform] = plugin;
 
+//        cerr << "NOTE: Assigned plugin " << plugin << " for transform: " << transform.toXmlString() << endl;
+
         if (!(originalTransform == transform)) {
             m_transformPluginMap[originalTransform] = plugin;
+//            cerr << "NOTE: Also assigned plugin " << plugin << " for original transform: " << originalTransform.toXmlString() << endl;
         }
 
     } else {
@@ -742,7 +747,7 @@
 
         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();
@@ -923,6 +928,7 @@
         }
 
         if (!m_summaries.empty()) {
+            // Summaries requested on the command line, for all transforms
             PluginSummarisingAdapter *adapter =
                 dynamic_cast<PluginSummarisingAdapter *>(plugin);
             if (!adapter) {
@@ -939,12 +945,13 @@
                     featureSet = adapter->getSummaryForAllOutputs
                         (getSummaryType(*sni),
                          PluginSummarisingAdapter::ContinuousTimeAverage);
-                    writeFeatures(audioSource, plugin, featureSet,//!!! *sni);
+                    writeFeatures(audioSource, plugin, featureSet,
                                   Transform::stringToSummaryType(sni->c_str()));
                 }
             }
         }
 
+        // Summaries specified in transform definitions themselves
         writeSummaries(audioSource, plugin);
     }
 
@@ -966,11 +973,15 @@
         
         const Transform &transform = ti->first;
 
+//        cerr << "FeatureExtractionManager::writeSummaries: plugin is " << plugin
+//             << ", found transform: " << transform.toXmlString() << endl;
+        
         Transform::SummaryType summaryType = transform.getSummaryType();
         PluginSummarisingAdapter::SummaryType pType =
             (PluginSummarisingAdapter::SummaryType)summaryType;
 
         if (transform.getSummaryType() == Transform::NoSummary) {
+//            cerr << "(no summary, continuing)" << endl;
             continue;
         }
 
@@ -984,7 +995,7 @@
         Plugin::FeatureSet featureSet = adapter->getSummaryForAllOutputs
             (pType, PluginSummarisingAdapter::ContinuousTimeAverage);
 
-//        cout << "summary type " << int(pType) << " for transform:" << endl << transform.toXmlString().toStdString()<< endl << "... feature set with " << featureSet.size() << " elts" << endl;
+//        cerr << "summary type " << int(pType) << " for transform:" << endl << transform.toXmlString().toStdString()<< endl << "... feature set with " << featureSet.size() << " elts" << endl;
 
         writeFeatures(audioSource, plugin, featureSet, summaryType);
     }
@@ -998,21 +1009,25 @@
     // caller should have ensured plugin is in m_plugins
     PluginMap::iterator pi = m_plugins.find(plugin);
 
+    // Write features from the feature set passed in, according to the
+    // transforms listed for the given plugin with the given summary type
+    
     for (TransformWriterMap::const_iterator ti = pi->second.begin();
          ti != pi->second.end(); ++ti) {
         
         const Transform &transform = ti->first;
         const vector<FeatureWriter *> &writers = ti->second;
-        
-        if (transform.getSummaryType() != Transform::NoSummary &&
-            m_summaries.empty() &&
-            summaryType == Transform::NoSummary) {
-            continue;
-        }
 
-        if (transform.getSummaryType() != Transform::NoSummary &&
-            summaryType != Transform::NoSummary &&
-            transform.getSummaryType() != summaryType) {
+//        cerr << "writeFeatures: plugin " << plugin << " has transform: " << transform.toXmlString() << endl;
+
+        if (transform.getSummaryType() == Transform::NoSummary &&
+            !m_summaries.empty()) {
+//            cerr << "transform has no summary, but summaries requested on command line, so going for it anyway" << endl;
+        } else if (transform.getSummaryType() != summaryType) {
+            // Either we're not writing a summary and the transform
+            // has one, or we're writing a summary but the transform
+            // has none or a different one; either way, skip it
+//            cerr << "summary type differs from passed-in one " << summaryType << endl;
             continue;
         }
 
@@ -1030,6 +1045,8 @@
         Plugin::FeatureSet::const_iterator fsi = features.find(outputIndex);
         if (fsi == features.end()) continue;
 
+//        cerr << "this transform has " << writers.size() << " writer(s)" << endl;
+        
         for (int j = 0; j < (int)writers.size(); ++j) {
             writers[j]->write
                 (audioSource, transform, desc, fsi->second,
--- a/runner/FeatureExtractionManager.h	Thu Feb 25 12:36:08 2016 +0000
+++ b/runner/FeatureExtractionManager.h	Tue Mar 01 14:40:24 2016 +0000
@@ -114,8 +114,8 @@
     OutputIndexMap m_pluginOutputIndices;
 
     typedef set<std::string> SummaryNameSet;
-    SummaryNameSet m_summaries;
-    bool m_summariesOnly;
+    SummaryNameSet m_summaries; // requested on command line for all transforms
+    bool m_summariesOnly; // command line flag
     Vamp::HostExt::PluginSummarisingAdapter::SegmentBoundaries m_boundaries;
 
     AudioFileReader *prepareReader(QString audioSource);
--- a/runner/main.cpp	Thu Feb 25 12:36:08 2016 +0000
+++ b/runner/main.cpp	Tue Mar 01 14:40:24 2016 +0000
@@ -857,8 +857,7 @@
     if (!requestedSummaryTypes.empty()) {
         if (!manager.setSummaryTypes(requestedSummaryTypes,
                                      boundaries)) {
-            cerr << myname
-                 << ": failed to set requested summary types" << endl;
+            cerr << myname << ": failed to set requested summary types" << endl;
             exit(1);
         }
     }
--- a/tests/test-multiple-audio/expected/all-files.csv	Thu Feb 25 12:36:08 2016 +0000
+++ b/tests/test-multiple-audio/expected/all-files.csv	Tue Mar 01 14:40:24 2016 +0000
@@ -1,36 +1,36 @@
 "./../audio/20sec-silence.wav",0.000000000,20.015600906,mean,61.1636,"(mean value, continuous-time average)"
 ,0.000000000,20.015600906,median,0,"(median value, continuous-time average)"
 ,0.000000000,20.015600906,mode,0,"(modal value, continuous-time average)"
-,0.000000000,20.015600906,mean,893.139,"(mean value, continuous-time average)"
-"./../audio/3clicks.mp3",0.000000000,5.061950112,mean,169.206,"(mean value, continuous-time average)"
-,0.000000000,5.061950112,median,170,"(median value, continuous-time average)"
-,0.000000000,5.061950112,mode,162,"(modal value, continuous-time average)"
-,0.000000000,5.061950112,mean,699.101,"(mean value, continuous-time average)"
-"./../audio/3clicks.ogg",0.000000000,4.992290248,mean,169.505,"(mean value, continuous-time average)"
-,0.000000000,4.992290248,median,170,"(median value, continuous-time average)"
-,0.000000000,4.992290248,mode,174,"(modal value, continuous-time average)"
-,0.000000000,4.992290248,mean,724.777,"(mean value, continuous-time average)"
+,0.000000000,20.015600906,mean,1406.56,"(mean value, continuous-time average)"
+"./../audio/3clicks.mp3",0.000000000,5.061950112,mean,174.507,"(mean value, continuous-time average)"
+,0.000000000,5.061950112,median,173,"(median value, continuous-time average)"
+,0.000000000,5.061950112,mode,173,"(modal value, continuous-time average)"
+,0.000000000,5.061950112,mean,1510.95,"(mean value, continuous-time average)"
+"./../audio/3clicks.ogg",0.000000000,4.992290248,mean,169.481,"(mean value, continuous-time average)"
+,0.000000000,4.992290248,median,156,"(median value, continuous-time average)"
+,0.000000000,4.992290248,mode,132,"(modal value, continuous-time average)"
+,0.000000000,4.992290248,mean,1480.59,"(mean value, continuous-time average)"
 "./../audio/3clicks8.wav",0.000000000,4.992290248,mean,169.391,"(mean value, continuous-time average)"
 ,0.000000000,4.992290248,median,169,"(median value, continuous-time average)"
 ,0.000000000,4.992290248,mode,164,"(modal value, continuous-time average)"
-,0.000000000,4.992290248,mean,703.191,"(mean value, continuous-time average)"
+,0.000000000,4.992290248,mean,1403.77,"(mean value, continuous-time average)"
 "./../audio/3clicks8quiet.wav",0.000000000,4.992290248,mean,169.058,"(mean value, continuous-time average)"
 ,0.000000000,4.992290248,median,169,"(median value, continuous-time average)"
 ,0.000000000,4.992290248,mode,165,"(modal value, continuous-time average)"
-,0.000000000,4.992290248,mean,673.623,"(mean value, continuous-time average)"
-"./../audio/6clicks.ogg",0.000000000,9.961360543,mean,167.58,"(mean value, continuous-time average)"
-,0.000000000,9.961360543,median,167,"(median value, continuous-time average)"
-,0.000000000,9.961360543,mode,170,"(modal value, continuous-time average)"
-,0.000000000,9.961360543,mean,714.928,"(mean value, continuous-time average)"
+,0.000000000,4.992290248,mean,1342.8,"(mean value, continuous-time average)"
+"./../audio/6clicks.ogg",0.000000000,9.961360543,mean,168.686,"(mean value, continuous-time average)"
+,0.000000000,9.961360543,median,158,"(median value, continuous-time average)"
+,0.000000000,9.961360543,mode,138,"(modal value, continuous-time average)"
+,0.000000000,9.961360543,mean,1423.64,"(mean value, continuous-time average)"
 "./../audio/6clicks8.wav",0.000000000,9.961360543,mean,170.174,"(mean value, continuous-time average)"
 ,0.000000000,9.961360543,median,169,"(median value, continuous-time average)"
 ,0.000000000,9.961360543,mode,164,"(modal value, continuous-time average)"
-,0.000000000,9.961360543,mean,698.921,"(mean value, continuous-time average)"
-"./../audio/id3v2-iso-8859-1.mp3",0.000000000,5.015510203,mean,170.655,"(mean value, continuous-time average)"
-,0.000000000,5.015510203,median,171,"(median value, continuous-time average)"
-,0.000000000,5.015510203,mode,171,"(modal value, continuous-time average)"
-,0.000000000,5.015510203,mean,690.028,"(mean value, continuous-time average)"
-"./../audio/id3v2-ucs-2.mp3",0.000000000,5.061950112,mean,169.206,"(mean value, continuous-time average)"
-,0.000000000,5.061950112,median,170,"(median value, continuous-time average)"
-,0.000000000,5.061950112,mode,162,"(modal value, continuous-time average)"
-,0.000000000,5.061950112,mean,699.101,"(mean value, continuous-time average)"
+,0.000000000,9.961360543,mean,1411.85,"(mean value, continuous-time average)"
+"./../audio/id3v2-iso-8859-1.mp3",0.000000000,5.015510203,mean,176.083,"(mean value, continuous-time average)"
+,0.000000000,5.015510203,median,172,"(median value, continuous-time average)"
+,0.000000000,5.015510203,mode,164,"(modal value, continuous-time average)"
+,0.000000000,5.015510203,mean,1492.7,"(mean value, continuous-time average)"
+"./../audio/id3v2-ucs-2.mp3",0.000000000,5.061950112,mean,174.507,"(mean value, continuous-time average)"
+,0.000000000,5.061950112,median,173,"(median value, continuous-time average)"
+,0.000000000,5.061950112,mode,173,"(modal value, continuous-time average)"
+,0.000000000,5.061950112,mean,1510.95,"(mean value, continuous-time average)"
--- a/tests/test-multiple-audio/expected/multiplexed.csv	Thu Feb 25 12:36:08 2016 +0000
+++ b/tests/test-multiple-audio/expected/multiplexed.csv	Tue Mar 01 14:40:24 2016 +0000
@@ -1,4 +1,4 @@
-"3clicks.mp3",0.000000000,9.961360543,mean,168.319,"(mean value, continuous-time average)"
-,0.000000000,9.961360543,median,167,"(median value, continuous-time average)"
-,0.000000000,9.961360543,mode,170,"(modal value, continuous-time average)"
-,0.000000000,9.961360543,mean,710.597,"(mean value, continuous-time average)"
+"3clicks.mp3",0.000000000,9.961360543,mean,168.908,"(mean value, continuous-time average)"
+,0.000000000,9.961360543,median,162,"(median value, continuous-time average)"
+,0.000000000,9.961360543,mode,144,"(modal value, continuous-time average)"
+,0.000000000,9.961360543,mean,1418.17,"(mean value, continuous-time average)"
--- a/tests/test-multiple-audio/expected/playlist.csv	Thu Feb 25 12:36:08 2016 +0000
+++ b/tests/test-multiple-audio/expected/playlist.csv	Tue Mar 01 14:40:24 2016 +0000
@@ -1,8 +1,8 @@
-"3clicks.mp3",0.000000000,5.061950112,mean,169.206,"(mean value, continuous-time average)"
-,0.000000000,5.061950112,median,170,"(median value, continuous-time average)"
-,0.000000000,5.061950112,mode,162,"(modal value, continuous-time average)"
-,0.000000000,5.061950112,mean,699.101,"(mean value, continuous-time average)"
-"6clicks.ogg",0.000000000,9.961360543,mean,167.58,"(mean value, continuous-time average)"
-,0.000000000,9.961360543,median,167,"(median value, continuous-time average)"
-,0.000000000,9.961360543,mode,170,"(modal value, continuous-time average)"
-,0.000000000,9.961360543,mean,714.928,"(mean value, continuous-time average)"
+"3clicks.mp3",0.000000000,5.061950112,mean,174.507,"(mean value, continuous-time average)"
+,0.000000000,5.061950112,median,173,"(median value, continuous-time average)"
+,0.000000000,5.061950112,mode,173,"(modal value, continuous-time average)"
+,0.000000000,5.061950112,mean,1510.95,"(mean value, continuous-time average)"
+"6clicks.ogg",0.000000000,9.961360543,mean,168.686,"(mean value, continuous-time average)"
+,0.000000000,9.961360543,median,158,"(median value, continuous-time average)"
+,0.000000000,9.961360543,mode,138,"(modal value, continuous-time average)"
+,0.000000000,9.961360543,mean,1423.64,"(mean value, continuous-time average)"
--- a/tests/test-multiple-audio/test-multiple-audio.sh	Thu Feb 25 12:36:08 2016 +0000
+++ b/tests/test-multiple-audio/test-multiple-audio.sh	Tue Mar 01 14:40:24 2016 +0000
@@ -2,14 +2,21 @@
 
 . ../include.sh
 
-tmpfile=$mypath/tmp_1_$$
+tmpfile1=$mypath/tmp_1_$$
+tmpfile2=$mypath/tmp_2_$$
 
-trap "rm -f $tmpfile" 0
+trap "rm -f $tmpfile1 $tmpfile2" 0
 
 transform=$mypath/transforms/detectionfunction.n3 
 
 urlbase=http://vamp-plugins.org/sonic-annotator/testfiles
 
+have_network=yes
+if ! ping -c 1 8.8.8.8 2>/dev/null 1>&2 ; then
+    echo "(network appears unavailable, skipping networking tests)"
+    have_network=no
+fi
+
 
 # 1. Recursive local directory
 
@@ -17,11 +24,11 @@
 # would have to regenerate it if we added more test audio files. Note
 # that the -r flag is not supposed to pick up playlist files, only
 # audio files
-$r -t $transform -w csv --csv-stdout -r --summary-only $audiopath > $tmpfile 2>/dev/null || \
+$r -t $transform -w csv --csv-stdout -r --summary-only $audiopath > $tmpfile1 2>/dev/null || \
     fail "Fails to run transform $transform with recursive dir option"
 
 expected=$mypath/expected/all-files
-csvcompare $tmpfile $expected.csv || \
+csvcompare $tmpfile1 $expected.csv || \
     faildiff "Output mismatch for transform $transform with summaries and recursive dir option" $tmpfile $expected.csv
 
 
@@ -30,82 +37,101 @@
 # Here we strip any leading path from the audio file in the output,
 # because the playlist reader will have resolved files to absolute
 # paths and those will differ between systems
-$r -t $transform -w csv --csv-stdout $audiopath/playlist.m3u --summary-only 2>/dev/null | sed 's,^"[^"]*/,",' > $tmpfile || \
+$r -t $transform -w csv --csv-stdout $audiopath/playlist.m3u --summary-only 2>/dev/null > "$tmpfile2" || \
     fail "Fails to run transform $transform with playlist input"
 
+cat "$tmpfile2" | sed 's,^"[^"]*/,",' > "$tmpfile1"
+
 expected=$mypath/expected/playlist
-csvcompare $tmpfile $expected.csv || \
-    faildiff "Output mismatch for transform $transform with summaries and playlist input" $tmpfile $expected.csv
+csvcompare $tmpfile1 $expected.csv || \
+    faildiff "Output mismatch for transform $transform with summaries and playlist input" $tmpfile1 $expected.csv
 
 
 # 3. Multiple files supplied directly on command line
 
 # Strip paths again, just so we can use the same output comparison
 # file as above
-$r -t $transform -w csv --csv-stdout $audiopath/3clicks.mp3 $audiopath/6clicks.ogg --summary-only 2>/dev/null | sed 's,^"[^"]*/,",' > $tmpfile || \
+$r -t $transform -w csv --csv-stdout $audiopath/3clicks.mp3 $audiopath/6clicks.ogg --summary-only 2>/dev/null > $tmpfile2 || \
     fail "Fails to run transform $transform with 2-file input"
 
+cat "$tmpfile2" | sed 's,^"[^"]*/,",' > "$tmpfile1"
+
 expected=$mypath/expected/playlist
-csvcompare $tmpfile $expected.csv || \
-    faildiff "Output mismatch for transform $transform with summaries and 2-file input" $tmpfile $expected.csv
+csvcompare $tmpfile1 $expected.csv || \
+    faildiff "Output mismatch for transform $transform with summaries and 2-file input" $tmpfile1 $expected.csv
 
 
 # 4. Multiple files supplied directly on command line, with file: URL
 
-$r -t $transform -w csv --csv-stdout $audiopath/3clicks.mp3 file://`pwd`/$audiopath/6clicks.ogg --summary-only 2>/dev/null | sed 's,^"[^"]*/,",' > $tmpfile || \
+$r -t $transform -w csv --csv-stdout $audiopath/3clicks.mp3 file://`pwd`/$audiopath/6clicks.ogg --summary-only 2>/dev/null > $tmpfile2 || \
     fail "Fails to run transform $transform with 2-file input"
 
-expected=$mypath/expected/playlist
-csvcompare $tmpfile $expected.csv || \
-    faildiff "Output mismatch for transform $transform with summaries and 2-file input using file:// URL" $tmpfile $expected.csv
-
-
-# 5. Remote playlist file referring to remote audio files
-
-$r -t $transform -w csv --csv-stdout $urlbase/playlist.m3u --summary-only 2>/dev/null | sed 's,^"[^"]*/,",' > $tmpfile || \
-    fail "Fails to run transform $transform with remote playlist input"
+cat "$tmpfile2" | sed 's,^"[^"]*/,",' > "$tmpfile1"
 
 expected=$mypath/expected/playlist
-csvcompare $tmpfile $expected.csv || \
-    faildiff "Output mismatch for transform $transform with summaries and remote playlist input" $tmpfile $expected.csv
+csvcompare $tmpfile1 $expected.csv || \
+    faildiff "Output mismatch for transform $transform with summaries and 2-file input using file:// URL" $tmpfile1 $expected.csv
 
 
-# 6. Local playlist file referring to mixture of remote and local audio files
+if [ "$have_network" = "yes" ]; then
 
-$r -t $transform -w csv --csv-stdout $audiopath/remote-playlist.m3u --summary-only 2>/dev/null | sed 's,^"[^"]*/,",' > $tmpfile || \
-    fail "Fails to run transform $transform with playlist of remote files"
+    # 5. Remote playlist file referring to remote audio files
 
-expected=$mypath/expected/playlist
-csvcompare $tmpfile $expected.csv || \
-    faildiff "Output mismatch for transform $transform with summaries and remote playlist input" $tmpfile $expected.csv
+    $r -t $transform -w csv --csv-stdout $urlbase/playlist.m3u --summary-only 2>/dev/null > $tmpfile2 || \
+	fail "Fails to run transform $transform with remote playlist input"
 
+    cat "$tmpfile2" | sed 's,^"[^"]*/,",' > "$tmpfile1"
 
-# 7. Multiple remote files supplied directly on command line
+    expected=$mypath/expected/playlist
+    csvcompare $tmpfile1 $expected.csv || \
+	faildiff "Output mismatch for transform $transform with summaries and remote playlist input" $tmpfile1 $expected.csv
 
-$r -t $transform -w csv --csv-stdout $urlbase/3clicks.mp3 $urlbase/6clicks.ogg --summary-only 2>/dev/null | sed 's,^"[^"]*/,",' > $tmpfile || \
-    fail "Fails to run transform $transform with 2-file remote input"
 
-expected=$mypath/expected/playlist
-csvcompare $tmpfile $expected.csv || \
-    faildiff "Output mismatch for transform $transform with summaries and 2-file input" $tmpfile $expected.csv
+    # 6. Local playlist file referring to mixture of remote and local audio files
 
+    $r -t $transform -w csv --csv-stdout $audiopath/remote-playlist.m3u --summary-only 2>/dev/null > $tmpfile2 || \
+	fail "Fails to run transform $transform with playlist of remote files"
 
-# 8. Mixture of remote and local files supplied on command line
+    cat "$tmpfile2" | sed 's,^"[^"]*/,",' > "$tmpfile1"
 
-$r -t $transform -w csv --csv-stdout $audiopath/3clicks.mp3 $urlbase/6clicks.ogg --summary-only 2>/dev/null | sed 's,^"[^"]*/,",' > $tmpfile || \
-    fail "Fails to run transform $transform with 2-file remote input"
+    expected=$mypath/expected/playlist
+    csvcompare $tmpfile1 $expected.csv || \
+	faildiff "Output mismatch for transform $transform with summaries and remote playlist input" $tmpfile1 $expected.csv
 
-expected=$mypath/expected/playlist
-csvcompare $tmpfile $expected.csv || \
-    faildiff "Output mismatch for transform $transform with summaries and mixed local/remote 2-file input" $tmpfile $expected.csv
 
+    # 7. Multiple remote files supplied directly on command line
+
+    $r -t $transform -w csv --csv-stdout $urlbase/3clicks.mp3 $urlbase/6clicks.ogg --summary-only 2>/dev/null > $tmpfile2 || \
+	fail "Fails to run transform $transform with 2-file remote input"
+
+    cat "$tmpfile2" | sed 's,^"[^"]*/,",' > "$tmpfile1"
+
+    expected=$mypath/expected/playlist
+    csvcompare $tmpfile1 $expected.csv || \
+	faildiff "Output mismatch for transform $transform with summaries and 2-file input" $tmpfile1 $expected.csv
+
+
+    # 8. Mixture of remote and local files supplied on command line
+
+    $r -t $transform -w csv --csv-stdout $audiopath/3clicks.mp3 $urlbase/6clicks.ogg --summary-only 2>/dev/null > $tmpfile2 || \
+	fail "Fails to run transform $transform with 2-file remote input"
+
+    cat "$tmpfile2" | sed 's,^"[^"]*/,",' > "$tmpfile1"
+
+    expected=$mypath/expected/playlist
+    csvcompare $tmpfile1 $expected.csv || \
+	faildiff "Output mismatch for transform $transform with summaries and mixed local/remote 2-file input" $tmpfile1 $expected.csv
+
+fi
 
 # 9. As 3, but multiplexing rather than extracting separately from each file
 
-$r -t $transform --multiplex -w csv --csv-stdout $audiopath/3clicks.mp3 $audiopath/6clicks.ogg --summary-only 2>/dev/null | sed 's,^"[^"]*/,",' > $tmpfile || \
+$r -t $transform --multiplex -w csv --csv-stdout $audiopath/3clicks.mp3 $audiopath/6clicks.ogg --summary-only 2>/dev/null > $tmpfile2 || \
     fail "Fails to run transform $transform with 2-file input"
 
+cat "$tmpfile2" | sed 's,^"[^"]*/,",' > "$tmpfile1"
+
 expected=$mypath/expected/multiplexed
-csvcompare $tmpfile $expected.csv || \
-    faildiff "Output mismatch for transform $transform with summaries and 2-file multiplexed input" $tmpfile $expected.csv
+csvcompare $tmpfile1 $expected.csv || \
+    faildiff "Output mismatch for transform $transform with summaries and 2-file multiplexed input" $tmpfile1 $expected.csv
 
--- a/tests/test-multiple-audio/transforms/detectionfunction.n3	Thu Feb 25 12:36:08 2016 +0000
+++ b/tests/test-multiple-audio/transforms/detectionfunction.n3	Tue Mar 01 14:40:24 2016 +0000
@@ -13,6 +13,7 @@
 	vamp:output examples:percussiononsets_output_detectionfunction ;
 	vamp:summary_type "median" .
 
+# This is not a summary and so should not appear with --summary-only
 :transform2 a vamp:Transform;
 	vamp:plugin examples:percussiononsets ;
 	vamp:output examples:percussiononsets_output_onsets .
@@ -22,11 +23,19 @@
 	vamp:output examples:percussiononsets_output_detectionfunction ;
 	vamp:summary_type "mode" .
 
+# This has different step and block sizes from the default
+# (:transform0), and so should be listed separately with different
+# values in the output
 :transform4 a vamp:Transform;
 	vamp:plugin examples:percussiononsets ;
 	vamp:output examples:percussiononsets_output_detectionfunction ;
-	vamp:step_size 2048 ;
-	vamp:block_size 4096 ;
+	vamp:step_size 4096 ;
+	vamp:block_size 8192 ;
 	vamp:summary_type "mean" .
 
+# This is not a summary and so should not appear with --summary-only
+:transform5 a vamp:Transform;
+	vamp:plugin examples:percussiononsets ;
+	vamp:output examples:percussiononsets_output_detectionfunction .
+
  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-summaries/expected/testplug-curve-vsr-count.csv	Tue Mar 01 14:40:24 2016 +0000
@@ -0,0 +1,1 @@
+0.000000000,9.750000000,count,10,"(count)"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-summaries/expected/testplug-curve-vsr-max.csv	Tue Mar 01 14:40:24 2016 +0000
@@ -0,0 +1,1 @@
+0.000000000,9.750000000,max,0.9,"(maximum value)"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-summaries/expected/testplug-curve-vsr-mean.csv	Tue Mar 01 14:40:24 2016 +0000
@@ -0,0 +1,20 @@
+# Sonic Annotator's summary method integrates the values across
+# time. If an output lacks duration for its features, each feature is
+# considered to extend until the timestamp of the following feature,
+# and the final feature is considered to extend until the end of the
+# input or the last-ending output, whichever is later.
+#
+# The curve-vsr output is therefore considered to have 9 values (0.0
+# to 0.8) that span 0.75 seconds each, followed by one value (0.9)
+# that spans the 3 seconds from 6.75 to 9.75 where the final output of
+# the plugin ends (that's the notes-regions output).
+#
+# The sum of 0.0..0.8 is 3.6, so the mean is (3.6 * 0.75 + 0.9 * 3.0)
+# / 9.75 = 0.553846 approx.
+# 
+# Equivalently we can consider the last feature the same as four
+# features of 0.75 seconds each (i.e. the same durations as the first
+# 9) each with the same value, 0.9. The mean is then the sum of
+# 0.0..0.9 plus three more 0.9s, i.e. 7.2, divided by 13.
+#
+0.000000000,9.750000000,mean,0.553846,"(mean value, continuous-time average)"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-summaries/expected/testplug-curve-vsr-median.csv	Tue Mar 01 14:40:24 2016 +0000
@@ -0,0 +1,16 @@
+# Sonic Annotator's summary method integrates the values across
+# time. If an output lacks duration for its features, each feature is
+# considered to extend until the timestamp of the following feature,
+# and the final feature is considered to extend until the end of the
+# input or the last-ending output, whichever is later.
+#
+# The curve-vsr output is therefore considered to have 9 values (0.0
+# to 0.8) that span 0.75 seconds each, followed by one value (0.9)
+# that spans the 3 seconds from 6.75 to 9.75 where the final output of
+# the plugin ends (that's the notes-regions output).
+#
+# Since the values from this output are already sorted and are
+# distinct, the integrated median is just whatever is in effect at
+# time 9.75 / 2.0 = 4.875. This value is 0.6.
+#
+0.000000000,9.750000000,median,0.6,"(median value, continuous-time average)"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-summaries/expected/testplug-curve-vsr-min.csv	Tue Mar 01 14:40:24 2016 +0000
@@ -0,0 +1,1 @@
+0.000000000,9.750000000,min,0,"(minimum value)"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-summaries/expected/testplug-curve-vsr-mode.csv	Tue Mar 01 14:40:24 2016 +0000
@@ -0,0 +1,15 @@
+# Sonic Annotator's summary method integrates the values across
+# time. If an output lacks duration for its features, each feature is
+# considered to extend until the timestamp of the following feature,
+# and the final feature is considered to extend until the end of the
+# input or the last-ending output, whichever is later.
+#
+# The curve-vsr output is therefore considered to have 9 values (0.0
+# to 0.8) that span 0.75 seconds each, followed by one value (0.9)
+# that spans the 3 seconds from 6.75 to 9.75 where the final output of
+# the plugin ends (that's the notes-regions output).
+#
+# The modal value is the one spanning the longest, which of course is
+# that final one, 0.9.
+#
+0.000000000,9.750000000,mode,0.9,"(modal value, continuous-time average)"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-summaries/expected/testplug-curve-vsr-sd.csv	Tue Mar 01 14:40:24 2016 +0000
@@ -0,0 +1,4 @@
+# Standard deviation is sqrt(variance), see the variance file for
+# notes on that value.
+#
+0.000000000,9.750000000,sd,0.315291,"(standard deviation, continuous-time average)"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-summaries/expected/testplug-curve-vsr-sum.csv	Tue Mar 01 14:40:24 2016 +0000
@@ -0,0 +1,1 @@
+0.000000000,9.750000000,sum,4.5,"(sum)"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-summaries/expected/testplug-curve-vsr-variance.csv	Tue Mar 01 14:40:24 2016 +0000
@@ -0,0 +1,20 @@
+# Sonic Annotator's summary method integrates the values across
+# time. If an output lacks duration for its features, each feature is
+# considered to extend until the timestamp of the following feature,
+# and the final feature is considered to extend until the end of the
+# input or the last-ending output, whichever is later.
+#
+# The curve-vsr output is therefore considered to have 9 values (0.0
+# to 0.8) that span 0.75 seconds each, followed by one value (0.9)
+# that spans the 3 seconds from 6.75 to 9.75 where the final output of
+# the plugin ends (that's the notes-regions output).
+#
+# We can consider the last feature the same as four features of 0.75
+# seconds each (i.e. the same durations as the first 9) each with the
+# same value, 0.9.
+#
+# The mean m is then 7.2 / 13 = 0.553846 approx, and the variance is
+# the sum for each of the 13 (partly fictitious) values v of (v-m)^2,
+# divided by 13. This works out as 0.0994083 ish.
+#
+0.000000000,9.750000000,variance,0.0994083,"(variance, continuous-time average)"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-summaries/expected/testplug-grid-fsr-max.csv	Tue Mar 01 14:40:24 2016 +0000
@@ -0,0 +1,1 @@
+0.000000000,9.750000000,max,0.55,0.6,0.65,0.7,0.75,0.8,0.85,0.9,0.95,1,"(maximum value)"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-summaries/expected/testplug-grid-fsr-min.csv	Tue Mar 01 14:40:24 2016 +0000
@@ -0,0 +1,1 @@
+0.000000000,9.750000000,min,0.1,0.15,0.2,0.25,0.3,0.35,0.4,0.45,0.5,0.55,"(minimum value)"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-summaries/test-summaries-testplugin.sh	Tue Mar 01 14:40:24 2016 +0000
@@ -0,0 +1,36 @@
+#!/bin/bash
+
+. ../include.sh
+
+infile=$audiopath/3clicks8.wav
+tmpfile=$mypath/tmp_1_$$
+tmpfile2=$mypath/tmp_2_$$
+
+trap "rm -f $tmpfile $tmpfile2" 0
+
+for output in curve-vsr grid-fsr; do
+
+    for summary in min max mean median mode sum variance sd count; do
+
+	# grid-fsr is bulkier, and we're only really concerned that
+	# we're getting a sane result per bin, so just do min and max
+	# there
+	if [ "$output" = "grid-fsr" ]; then
+	    case "$summary" in
+		mean|median|mode|sum|variance|sd|count) continue;;
+	    esac
+	fi
+	
+	id="$testplug:$output"
+	expected="$mypath/expected/testplug-$output-$summary.csv"
+
+	cat "$expected" | grep -v '^#' > "$tmpfile2"
+	
+	$r -d $id -w csv --csv-stdout -S $summary --summary-only --csv-omit-filename $infile > $tmpfile 2>/dev/null || \
+	    fail "Fails to run transform id $id with summary type $summary"
+
+	csvcompare "$tmpfile" "$tmpfile2" ||
+	    faildiff "Output mismatch for output $output with summary type $summary" "$tmpfile" "$tmpfile2"
+
+    done
+done
--- a/tests/test-summaries/test-summaries.sh	Thu Feb 25 12:36:08 2016 +0000
+++ b/tests/test-summaries/test-summaries.sh	Tue Mar 01 14:40:24 2016 +0000
@@ -83,5 +83,6 @@
 compare $tmpcanonical $expcanonical || \
     faildiff "Output mismatch against expected $sexpected.n3 for canonicalised version of transform $stransform" $tmpcanonical $expcanonical
 
-exit 0
+bash "$mypath/test-summaries-testplugin.sh"
 
+