Mercurial > hg > vampy-host
changeset 68:e15e684d2af4
Some tricky tests for returned values from the test plugin
author | Chris Cannam |
---|---|
date | Wed, 14 Jan 2015 14:31:01 +0000 |
parents | 6f6a54963ce8 |
children | b34d3b58da98 |
files | test/test_process.py vamp/__init__.py |
diffstat | 2 files changed, 113 insertions(+), 23 deletions(-) [+] |
line wrap: on
line diff
--- a/test/test_process.py Wed Jan 14 12:43:36 2015 +0000 +++ b/test/test_process.py Wed Jan 14 14:31:01 2015 +0000 @@ -7,14 +7,88 @@ rate = 44100 -def test_process(): - buf = np.zeros(10240) - results = vamp.process(buf, rate, testPluginKey, {}, [ "input-timestamp" ]) - print("results = " + str(list(results))) - return True +# Throughout this file we have the assumption that the plugin gets run with a +# 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 -def test_process_freq(): - buf = np.zeros(10240) - results = vamp.process(buf, rate, testPluginKeyFreq, {}, [ "input-timestamp" ]) - print("results = " + str(list(results))) - return True +blocksize = 1024 + +def input_data(n): + # start at 1, not 0 so that all elts are non-zero + return np.arange(n) + 1 + +def test_process_n(): + buf = input_data(blocksize) + 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" ])) + assert len(results) == 2 # one complete block starting at zero, one half-full + +def test_process_summary_param(): + buf = input_data(blocksize * 10) + results = list(vamp.process(buf, rate, testPluginKey, { "produce_output": 0 }, [ "input-summary" ])) + 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" ])) + assert len(results) == 0 + +def test_process_summary(): + buf = input_data(blocksize * 10) + results = list(vamp.process(buf, rate, testPluginKey, {}, [ "input-summary" ])) + assert len(results) == 10 + # the input-summary output contains, for each process block, the value of + # the first sample in the process block input plus the number of samples + # above some epsilon + 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_freq_summary(): + buf = input_data(blocksize * 10) + results = list(vamp.process(buf, rate, testPluginKeyFreq, {}, [ "input-summary" ])) + assert len(results) == 20 + for i in range(len(results)): + # + # sort of as above, but much much subtler: + # + # * the input block is converted to frequency domain but then converted + # back within the plugin, so the values being reported are time-domain + # ones but with windowing and FFT shift + # + # * the effect of FFT shift is that the first element in the + # re-converted frame is actually the one that was at the start of the + # second half of the original frame + # + # * and the last block is only half-full, so the "first" elt in that + # one, which actually comes from just after the middle of the block, + # will be zero + # + # * windowing does not affect the value of the first elt, because + # (before fft shift) it came from the peak of the window shape where + # the window value is 1 + # + # * but windowing does affect the number of non-zero elts, because the + # asymmetric window used has one value very close to zero in it + # + # * the step size (the increment in input value from one block to the + # next) is only half the block size + # + 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]["values"][0] + eps = 1e-6 + assert abs(actual - expected) < eps +
--- a/vamp/__init__.py Wed Jan 14 12:43:36 2015 +0000 +++ b/vamp/__init__.py Wed Jan 14 14:31:01 2015 +0000 @@ -1,5 +1,7 @@ '''A high-level interface to the vampyhost extension module, for quickly and easily running Vamp audio analysis plugins on audio files and buffers.''' +###!!! todo: move all the real code out of __init__.py + import vampyhost import numpy @@ -24,13 +26,38 @@ yield frame i = i + stepSize -def process(data, samplerate, key, parameters = {}, outputs = []): -#!!! docstring + +def loadAndConfigureFor(data, samplerate, key, parameters): plug = vampyhost.loadPlugin(key, samplerate, vampyhost.AdaptInputDomain + vampyhost.AdaptChannelCount) + plug.setParameterValues(parameters) + + stepSize = plug.getPreferredStepSize() + blockSize = plug.getPreferredBlockSize() + + if blockSize == 0: + blockSize = 1024 + if stepSize == 0: + stepSize = blockSize ##!!! or blockSize/2, but check this with input domain adapter + + channels = 1 + if data.ndim > 1: + channels = data.shape[0] + + plug.initialise(channels, stepSize, blockSize) + return (plug, stepSize, blockSize) + + +def process(data, samplerate, key, parameters = {}, outputs = []): +#!!! docstring + + plug, stepSize, blockSize = 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 @@ -43,17 +70,6 @@ singleOutput = (len(outputs) == 1) - stepSize = plug.getPreferredStepSize() - blockSize = plug.getPreferredBlockSize() - if blockSize == 0: - blockSize = 1024 - if stepSize == 0: - stepSize = blockSize ##!!! or blockSize/2, but check this with input domain adapter - channels = 1 - if data.ndim > 1: - channels = data.shape[0] - - plug.initialise(channels, stepSize, blockSize) ff = framesFromArray(data, stepSize, blockSize) fi = 0