changeset 76:b2afd385586f

Split out process, processMultipleOutputs
author Chris Cannam
date Wed, 21 Jan 2015 12:13:45 +0000
parents ad08a0fe6673
children aa8491a11530
files test/test_process.py vamp/__init__.py vamp/process.py
diffstat 3 files changed, 118 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/test/test_process.py	Wed Jan 21 11:16:50 2015 +0000
+++ b/test/test_process.py	Wed Jan 21 12:13:45 2015 +0000
@@ -11,7 +11,7 @@
 # blocksize of 1024, and with a step of 1024 for the time-domain version or 512
 # for the frequency-domain one. That is certainly expected to be the norm for a
 # plugin like this that declares no preference, and the Python Vamp module is
-# expected to follow the norm
+# expected to follow the norm.
 
 blocksize = 1024
 
@@ -21,37 +21,61 @@
 
 def test_process_n():
     buf = input_data(blocksize)
-    results = list(vamp.process(buf, rate, testPluginKey, {}, [ "input-summary" ]))
+    results = list(vamp.process(buf, rate, testPluginKey, "input-summary"))
     assert len(results) == 1
 
 def test_process_freq_n():
     buf = input_data(blocksize)
-    results = list(vamp.process(buf, rate, testPluginKeyFreq, {}, [ "input-summary" ]))
+    results = list(vamp.process(buf, rate, testPluginKeyFreq, "input-summary", {}))
     assert len(results) == 2 # one complete block starting at zero, one half-full
 
 def test_process_default_output():
     # If no output is specified, we should get the first one (instants)
     buf = input_data(blocksize)
-    results = list(vamp.process(buf, rate, testPluginKey, {}, []))
+    results = list(vamp.process(buf, rate, testPluginKey, "", {}))
     assert len(results) == 10
     for i in range(len(results)):
         expectedTime = vamp.vampyhost.RealTime('seconds', i * 1.5)
-        actualTime = results[i]["instants"]["timestamp"]
+        actualTime = results[i]["timestamp"]
         assert expectedTime == actualTime
-    
+
 def test_process_summary_param():
     buf = input_data(blocksize * 10)
-    results = list(vamp.process(buf, rate, testPluginKey, { "produce_output": 0 }, [ "input-summary" ]))
+    results = list(vamp.process(buf, rate, testPluginKey, "input-summary", { "produce_output": 0 }))
+    assert len(results) == 0
+
+def test_process_multi_summary_param():
+    buf = input_data(blocksize * 10)
+    results = list(vamp.processMultipleOutputs(buf, rate, testPluginKey, [ "input-summary" ], { "produce_output": 0 }))
     assert len(results) == 0
 
 def test_process_summary_param_bool():
     buf = input_data(blocksize * 10)
-    results = list(vamp.process(buf, rate, testPluginKey, { "produce_output": False }, [ "input-summary" ]))
+    results = list(vamp.process(buf, rate, testPluginKey, "input-summary", { "produce_output": False }))
+    assert len(results) == 0
+
+def test_process_multi_summary_param_bool():
+    buf = input_data(blocksize * 10)
+    results = list(vamp.processMultipleOutputs(buf, rate, testPluginKey, [ "input-summary" ], { "produce_output": False }))
     assert len(results) == 0
 
 def test_process_summary():
     buf = input_data(blocksize * 10)
-    results = list(vamp.process(buf, rate, testPluginKey, {}, [ "input-summary" ]))
+    results = list(vamp.process(buf, rate, testPluginKey, "input-summary", {}))
+    assert len(results) == 10
+    for i in range(len(results)):
+        #
+        # each feature has a single value, equal to the number of non-zero elts
+        # in the input block (which is all of them, i.e. the blocksize) plus
+        # the first elt (which is i * blockSize + 1)
+        #
+        expected = blocksize + i * blocksize + 1
+        actual = results[i]["values"][0]
+        assert actual == expected
+
+def test_process_multi_summary():
+    buf = input_data(blocksize * 10)
+    results = list(vamp.processMultipleOutputs(buf, rate, testPluginKey, [ "input-summary" ], {}))
     assert len(results) == 10
     for i in range(len(results)):
         #
@@ -65,7 +89,7 @@
 
 def test_process_freq_summary():
     buf = input_data(blocksize * 10)
-    results = list(vamp.process(buf, rate, testPluginKeyFreq, {}, [ "input-summary" ]))
+    results = list(vamp.process(buf, rate, testPluginKeyFreq, "input-summary", {}))
     assert len(results) == 20
     for i in range(len(results)):
         #
@@ -97,13 +121,37 @@
         if (i == len(results)-1):
             expected = 0
         expected = expected + blocksize - 1              # non-zero elts
+        actual = results[i]["values"][0]
+        eps = 1e-6
+        assert abs(actual - expected) < eps
+
+def test_process_multi_freq_summary():
+    buf = input_data(blocksize * 10)
+    results = list(vamp.processMultipleOutputs(buf, rate, testPluginKeyFreq, [ "input-summary" ], {}))
+    assert len(results) == 20
+    for i in range(len(results)):
+        expected = i * (blocksize/2) + blocksize/2 + 1   # "first" elt
+        if (i == len(results)-1):
+            expected = 0
+        expected = expected + blocksize - 1              # non-zero elts
         actual = results[i]["input-summary"]["values"][0]
         eps = 1e-6
         assert abs(actual - expected) < eps
 
 def test_process_timestamps():
     buf = input_data(blocksize * 10)
-    results = list(vamp.process(buf, rate, testPluginKey, {}, [ "input-timestamp" ]))
+    results = list(vamp.process(buf, rate, testPluginKey, "input-timestamp", {}))
+    assert len(results) == 10
+    for i in range(len(results)):
+        # The timestamp should be the frame number of the first frame in the
+        # input buffer
+        expected = i * blocksize
+        actual = results[i]["values"][0]
+        assert actual == expected
+
+def test_process_multi_timestamps():
+    buf = input_data(blocksize * 10)
+    results = list(vamp.processMultipleOutputs(buf, rate, testPluginKey, [ "input-timestamp" ]))
     assert len(results) == 10
     for i in range(len(results)):
         # The timestamp should be the frame number of the first frame in the
@@ -114,7 +162,18 @@
 
 def test_process_freq_timestamps():
     buf = input_data(blocksize * 10)
-    results = list(vamp.process(buf, rate, testPluginKeyFreq, {}, [ "input-timestamp" ]))
+    results = list(vamp.process(buf, rate, testPluginKeyFreq, "input-timestamp", {}))
+    assert len(results) == 20
+    for i in range(len(results)):
+        # The timestamp should be the frame number of the frame just beyond
+        # half-way through the input buffer
+        expected = i * (blocksize/2) + blocksize/2
+        actual = results[i]["values"][0]
+        assert actual == expected
+
+def test_process_multi_freq_timestamps():
+    buf = input_data(blocksize * 10)
+    results = list(vamp.processMultipleOutputs(buf, rate, testPluginKeyFreq, [ "input-timestamp" ], {}))
     assert len(results) == 20
     for i in range(len(results)):
         # The timestamp should be the frame number of the frame just beyond
@@ -125,7 +184,7 @@
 
 def test_process_multiple_outputs():
     buf = input_data(blocksize * 10)
-    results = list(vamp.process(buf, rate, testPluginKey, {}, [ "input-summary", "input-timestamp" ]))
+    results = list(vamp.processMultipleOutputs(buf, rate, testPluginKey, [ "input-summary", "input-timestamp" ], {}))
     assert len(results) == 20
     si = 0
     ti = 0
--- a/vamp/__init__.py	Wed Jan 21 11:16:50 2015 +0000
+++ b/vamp/__init__.py	Wed Jan 21 12:13:45 2015 +0000
@@ -4,5 +4,5 @@
 
 from load import listPlugins, loadAndConfigureFor
 from frames import framesFromArray
-from process import process
+from process import process, processMultipleOutputs
 from collect import collect
--- a/vamp/process.py	Wed Jan 21 11:16:50 2015 +0000
+++ b/vamp/process.py	Wed Jan 21 12:13:45 2015 +0000
@@ -4,43 +4,70 @@
 import frames
 import load
 
-def process(data, sampleRate, key, parameters = {}, outputs = []):
+def loadAndQuery(data, sampleRate, key, parameters):
+    plug, stepSize, blockSize = load.loadAndConfigureFor(data, sampleRate, key, parameters)
+    plugOuts = plug.getOutputs()
+    outIndices = dict(zip([o["identifier"] for o in plugOuts],
+                          range(0, len(plugOuts))))  # id -> n
+    return plug, stepSize, blockSize, outIndices
+    
+
+def processMultipleOutputs(data, sampleRate, key, outputs, parameters = {}):
 #!!! docstring
 
-    plug, stepSize, blockSize = load.loadAndConfigureFor(data, sampleRate, key, parameters)
-
-    plugOuts = plug.getOutputs()
-    if plugOuts == []:
-        return
-
-    outIndices = dict(zip([o["identifier"] for o in plugOuts],
-                          range(0, len(plugOuts))))  # id -> n
+    plug, stepSize, blockSize, outIndices = loadAndQuery(data, sampleRate, key, parameters)
 
     for o in outputs:
         assert o in outIndices
 
-    if outputs == []:
-        outputs = [plugOuts[0]["identifier"]]
-
     ff = frames.framesFromArray(data, stepSize, blockSize)
     fi = 0
 
-    #!!! should we fill in the correct timestamps here?
-
     for f in ff:
         results = plug.processBlock(f, vampyhost.frame2RealTime(fi, sampleRate))
         # results is a dict mapping output number -> list of feature dicts
         for o in outputs:
-            if outIndices[o] in results:
-                for r in results[outIndices[o]]:
+            outix = outIndices[o]
+            if outix in results:
+                for r in results[outix]:
                     yield { o: r }
         fi = fi + stepSize
 
     results = plug.getRemainingFeatures()
     for o in outputs:
-        if outIndices[o] in results:
-            for r in results[outIndices[o]]:
+        outix = outIndices[o]
+        if outix in results:
+            for r in results[outix]:
                 yield { o: r }
 
     plug.unload()
 
+def process(data, sampleRate, key, output = "", parameters = {}):
+#!!! docstring
+
+    plug, stepSize, blockSize, outIndices = loadAndQuery(data, sampleRate, key, parameters)
+
+    if output == "":
+        outix = 0
+    else:
+        assert output in outIndices
+        outix = outIndices[output]
+    
+    ff = frames.framesFromArray(data, stepSize, blockSize)
+    fi = 0
+
+    for f in ff:
+        results = plug.processBlock(f, vampyhost.frame2RealTime(fi, sampleRate))
+        # results is a dict mapping output number -> list of feature dicts
+        if outix in results:
+            for r in results[outix]:
+                yield r
+        fi = fi + stepSize
+
+    results = plug.getRemainingFeatures()
+    if outix in results:
+        for r in results[outix]:
+            yield r
+
+    plug.unload()
+