diff vamp/process.py @ 98:f0c18ba7b54e

Fixes to process_frames, and tests; doc strings
author Chris Cannam
date Tue, 03 Feb 2015 14:43:50 +0000
parents 3e5791890b65
children 7764eb74a3c6
line wrap: on
line diff
--- a/vamp/process.py	Tue Feb 03 10:29:21 2015 +0000
+++ b/vamp/process.py	Tue Feb 03 14:43:50 2015 +0000
@@ -4,10 +4,10 @@
 import frames
 import load
 
-
 def process_frames_with_plugin(ff, sample_rate, step_size, plugin, outputs):
 
-    out_indices = dict([(id, plugin.get_output(id)["output_index"]) for id in outputs])
+    out_indices = dict([(id, plugin.get_output(id)["output_index"])
+                        for id in outputs])
     plugin.reset()
     fi = 0
 
@@ -31,7 +31,28 @@
 
 
 def process(data, sample_rate, key, output = "", parameters = {}):
-#!!! docstring
+    """Process audio data with a Vamp plugin, and make the results from a
+    single plugin output available as a generator.
+
+    The provided data should be a 1- or 2-dimensional list or NumPy
+    array of floats. If it is 2-dimensional, the first dimension is
+    taken to be the channel count.
+
+    The returned results will be those calculated by the plugin with
+    the given key and returned through its output with the given
+    output identifier. If the requested output is the empty string,
+    the first output provided by the plugin will be used.
+
+    If the parameters dict is non-empty, the plugin will be configured
+    by setting its parameters according to the (string) key and
+    (float) value data found in the dict.
+
+    This function acts as a generator, yielding a sequence of result
+    features as it obtains them. Each feature is represented as a
+    dictionary containing, optionally, timestamp and duration
+    (RealTime objects), label (string), and a 1-dimensional array of
+    float values.
+    """
 
     plugin, step_size, block_size = load.load_and_configure(data, sample_rate, key, parameters)
 
@@ -46,24 +67,71 @@
     plugin.unload()
 
 
-def process_frames(ff, channels, sample_rate, step_size, key, output = "", parameters = {}):
+def process_frames(ff, sample_rate, step_size, key, output = "", parameters = {}):
+    """Process audio data with a Vamp plugin, and make the results from a
+    single plugin output available as a generator.
 
-    plug = vampyhost.load_plugin(key, sample_rate,
-                                 vampyhost.ADAPT_INPUT_DOMAIN +
-                                 vampyhost.ADAPT_BUFFER_SIZE +
-                                 vampyhost.ADAPT_CHANNEL_COUNT)
+    The provided data should be an enumerable sequence of time-domain
+    audio frames, of which each frame is 2-dimensional list or NumPy
+    array of floats. The first dimension is taken to be the channel
+    count, and the second dimension the frame or block size. The
+    step_size argument gives the increment in audio samples from one
+    frame to the next. Each frame must have the same size.
 
-    plug.set_parameter_values(parameters)
+    The returned results will be those calculated by the plugin with
+    the given key and returned through its output with the given
+    output identifier. If the requested output is the empty string,
+    the first output provided by the plugin will be used.
 
-    if not plug.initialise(channels, step_size, block_size):
-        raise "Failed to initialise plugin"
+    If the parameters dict is non-empty, the plugin will be configured
+    by setting its parameters according to the (string) key and
+    (float) value data found in the dict.
+
+    This function acts as a generator, yielding a sequence of result
+    features as it obtains them. Each feature is represented as a
+    dictionary containing, optionally, timestamp and duration
+    (RealTime objects), label (string), and a 1-dimensional array of
+    float values.
+    """
+
+    plugin = vampyhost.load_plugin(key, sample_rate,
+                                   vampyhost.ADAPT_INPUT_DOMAIN +
+                                   vampyhost.ADAPT_BUFFER_SIZE +
+                                   vampyhost.ADAPT_CHANNEL_COUNT)
+
+    fi = 0
+    channels = 0
+    block_size = 0
+
+    if output == "":
+        out_index = 0
+    else:
+        out_index = plugin.get_output(output)["output_index"]
     
-    if output == "":
-        output = plugin.get_output(0)["identifier"]
+    for f in ff:
 
-    for r in process_frames_with_plugin(ff, sample_rate, step_size, plugin, [output]):
-        yield r[output]
-    
+        if fi == 0:
+            channels = f.shape[0]
+            block_size = f.shape[1]
+            plugin.set_parameter_values(parameters)
+            if not plugin.initialise(channels, step_size, block_size):
+                raise "Failed to initialise plugin"
+
+        timestamp = vampyhost.frame_to_realtime(fi, sample_rate)
+        results = plugin.process_block(f, timestamp)
+        # results is a dict mapping output number -> list of feature dicts
+        if out_index in results:
+            for r in results[out_index]:
+                yield r
+
+        fi = fi + step_size
+
+    if fi > 0:
+        results = plugin.get_remaining_features()
+        if out_index in results:
+            for r in results[out_index]:
+                yield r
+        
     plugin.unload()
     
 
@@ -78,4 +146,3 @@
         yield r
 
     plugin.unload()
-