Mercurial > hg > vampy-host
changeset 98:f0c18ba7b54e
Fixes to process_frames, and tests; doc strings
author | Chris Cannam |
---|---|
date | Tue, 03 Feb 2015 14:43:50 +0000 |
parents | 06c4afba4fc5 |
children | 7764eb74a3c6 |
files | test/test_process.py vamp/__init__.py vamp/load.py vamp/process.py |
diffstat | 4 files changed, 137 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/test/test_process.py Tue Feb 03 10:29:21 2015 +0000 +++ b/test/test_process.py Tue Feb 03 14:43:50 2015 +0000 @@ -1,6 +1,7 @@ import vamp import numpy as np +import vamp.frames as fr plugin_key = "vamp-test-plugin:vamp-test-plugin" plugin_key_freq = "vamp-test-plugin:vamp-test-plugin-freq" @@ -73,6 +74,21 @@ actual = results[i]["values"][0] assert actual == expected +def test_process_summary_frames(): + buf = input_data(blocksize * 10) + ff = fr.frames_from_array(buf, blocksize, blocksize) + results = list(vamp.process_frames(ff, rate, blocksize, plugin_key, "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.process_multiple_outputs(buf, rate, plugin_key, [ "input-summary" ], {}))
--- a/vamp/__init__.py Tue Feb 03 10:29:21 2015 +0000 +++ b/vamp/__init__.py Tue Feb 03 14:43:50 2015 +0000 @@ -2,7 +2,7 @@ import vampyhost -from load import list_plugins +from load import list_plugins, get_outputs_of, get_category_of from process import process, process_frames, process_multiple_outputs from collect import collect
--- a/vamp/load.py Tue Feb 03 10:29:21 2015 +0000 +++ b/vamp/load.py Tue Feb 03 14:43:50 2015 +0000 @@ -3,9 +3,45 @@ import vampyhost def list_plugins(): + """Obtain a list of plugin keys for all currently installed Vamp plugins. + + The returned value is a list of strings, each of which is the key + for one plugin. (Note that a plugin may have multiple outputs, if + it computes more than one type of feature.) + + To query the available outputs and category of a plugin, you may + use vamp.get_outputs_of() and vamp.get_category_of(). Further + information may be retrieved by loading the plugin and querying + its info dictionary using the low-level functions in the + vamp.vampyhost extension module. + + To make use of a plugin to extract features from audio data, pass + the plugin key and optionally an output identifier to + vamp.process() or vamp.collect(). + """ return vampyhost.list_plugins() +def get_outputs_of(key): + """Obtain a list of the output identifiers for the given plugin key. + """ + return vampyhost.get_outputs_of(key) + +def get_category_of(key): + """Obtain the category descriptor, if any, for the given plugin key. + + The returned value is a list of descriptor terms, from least + specific to most specific. The list may be empty if no category + information is found for the plugin. + """ + return vampyhost.get_category_of(key) + def load_and_configure(data, sample_rate, key, parameters): + """Load the plugin with the given key at a given sample rate, + configure it with the parameter keys and values in the given + parameter dictionary, and initialise it with its preferred step + and block size. The channel count is taken from the shape of the + data array provided. + """ plug = vampyhost.load_plugin(key, sample_rate, vampyhost.ADAPT_INPUT_DOMAIN + @@ -29,4 +65,3 @@ return (plug, step_size, block_size) else: raise "Failed to initialise plugin" -
--- 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() -