changeset 93:4bed6bf67243

Return simple array for simple data
author Chris Cannam
date Mon, 02 Feb 2015 16:08:42 +0000
parents 18b412a9c4d5
children c3318a95625b
files native/PyPluginObject.cpp test/test_collect.py vamp/collect.py
diffstat 3 files changed, 66 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/native/PyPluginObject.cpp	Mon Jan 26 12:28:30 2015 +0000
+++ b/native/PyPluginObject.cpp	Mon Feb 02 16:08:42 2015 +0000
@@ -173,6 +173,8 @@
 static PyObject *
 convertOutput(const Plugin::OutputDescriptor &desc, int ix)
 {
+    VectorConversion conv;
+    
     PyObject *outdict = PyDict_New();
     PyDict_SetItemString
         (outdict, "identifier", pystr(desc.identifier));
@@ -181,8 +183,19 @@
     PyDict_SetItemString
         (outdict, "description", pystr(desc.description));
     PyDict_SetItemString
-        (outdict, "bin_count", PyInt_FromLong(desc.binCount));
-    if (desc.binCount > 0) {
+        (outdict, "unit", pystr(desc.unit));
+    PyDict_SetItemString
+        (outdict, "has_fixed_bin_count", PyInt_FromLong(desc.hasFixedBinCount));
+    if (desc.hasFixedBinCount) {
+        PyDict_SetItemString
+            (outdict, "bin_count", PyInt_FromLong(desc.binCount));
+        if (!desc.binNames.empty()) {
+            PyDict_SetItemString
+                (outdict, "bin_names", conv.PyValue_From_StringVector(desc.binNames));
+        }
+    }
+    if (!desc.hasFixedBinCount ||
+        (desc.hasFixedBinCount && (desc.binCount > 0))) {
         if (desc.hasKnownExtents) {
             PyDict_SetItemString
                 (outdict, "has_known_extents", Py_True);
--- a/test/test_collect.py	Mon Jan 26 12:28:30 2015 +0000
+++ b/test/test_collect.py	Mon Feb 02 16:08:42 2015 +0000
@@ -29,28 +29,26 @@
     buf = input_data(blocksize * 10)
     results = list(vamp.collect(buf, rate, plugin_key, "input-timestamp"))
     assert len(results) == 10
-    for r in results:
-        assert r["timestamp"] == vamp.vampyhost.frame_to_realtime(r["values"][0], rate)
+    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]
+        assert actual == expected
 
 def test_collect_fixed_sample_rate():
     buf = input_data(blocksize * 10)
     results = list(vamp.collect(buf, rate, plugin_key, "curve-fsr"))
     assert len(results) == 10
-    i = 0
-    for r in results:
-        assert r["timestamp"] == vamp.vampyhost.RealTime('seconds', i * 0.4)
-        assert abs(r["values"][0] - i * 0.1) < eps
-        i = i + 1
+    for i in range(len(results)):
+        assert abs(results[i] - i * 0.1) < eps
 
 def test_collect_fixed_sample_rate_2():
     buf = input_data(blocksize * 10)
     results = list(vamp.collect(buf, rate, plugin_key, "curve-fsr-timed"))
     assert len(results) == 10
-    i = 0
-    for r in results:
-        assert r["timestamp"] == vamp.vampyhost.RealTime('seconds', i * 0.4)
-        assert abs(r["values"][0] - i * 0.1) < eps
-        i = i + 1
+    for i in range(len(results)):
+        assert abs(results[i] - i * 0.1) < eps
         
 def test_collect_variable_sample_rate():
     buf = input_data(blocksize * 10)
--- a/vamp/collect.py	Mon Jan 26 12:28:30 2015 +0000
+++ b/vamp/collect.py	Mon Feb 02 16:08:42 2015 +0000
@@ -5,6 +5,8 @@
 import process
 import frames
 
+import numpy as np
+
 
 def timestamp_features(sample_rate, step_size, output_desc, features):
     n = -1
@@ -28,7 +30,33 @@
             yield f
 
 
-def process_and_fill_timestamps(data, sample_rate, key, output, parameters = {}):
+def fill_timestamps(results, sample_rate, step_size, output_desc):
+
+    output = output_desc["identifier"]
+    
+    selected = [ r[output] for r in results ]
+
+    stamped = timestamp_features(sample_rate, step_size, output_desc, selected)
+
+    for s in stamped:
+        yield s
+
+
+def deduce_shape(output_desc):
+    if output_desc["has_duration"]:
+        return "individual"
+    if output_desc["sample_type"] == vampyhost.VARIABLE_SAMPLE_RATE:
+        return "individual"
+    if not output_desc["has_fixed_bin_count"]:
+        return "individual"
+    if output_desc["bin_count"] == 0:
+        return "individual"
+    if output_desc["bin_count"] > 1:
+        return "matrix"
+    return "vector"
+
+
+def process_and_reshape(data, sample_rate, key, output, parameters = {}):
 
     plugin, step_size, block_size = load.load_and_configure(data, sample_rate, key, parameters)
 
@@ -42,15 +70,20 @@
 
     results = process.process_frames_with_plugin(ff, sample_rate, step_size, plugin, [output])
 
-    selected = [ r[output] for r in results ]
+    shape = deduce_shape(output_desc)
 
-    stamped = timestamp_features(sample_rate, step_size, output_desc, selected)
-
-    for s in stamped:
-        yield s
+    if shape == "vector":
+        rv = np.array([r[output]["values"][0] for r in results])
+    elif shape == "matrix":
+        rv = np.array(
+            [[r[output]["values"][i] for r in results]
+             for i in range(0, output_desc["bin_count"]-1)])
+    else:
+        rv = list(fill_timestamps(results, sample_rate, step_size, output_desc))
 
     plugin.unload()
-        
+    return rv
+
 
 def collect(data, sample_rate, key, output, parameters = {}):
-    return process_and_fill_timestamps(data, sample_rate, key, output, parameters)
+    return process_and_reshape(data, sample_rate, key, output, parameters)