annotate test/test_process.py @ 151:5a6b8f4be9b9 tracks tip

Docs
author Chris Cannam
date Fri, 21 Apr 2017 14:33:57 +0100
parents 8b08cbbdfe77
children
rev   line source
Chris@61 1
Chris@61 2 import vamp
Chris@61 3 import numpy as np
Chris@98 4 import vamp.frames as fr
Chris@61 5
Chris@82 6 plugin_key = "vamp-test-plugin:vamp-test-plugin"
Chris@82 7 plugin_key_freq = "vamp-test-plugin:vamp-test-plugin-freq"
Chris@61 8
Chris@61 9 rate = 44100
Chris@61 10
Chris@68 11 # Throughout this file we have the assumption that the plugin gets run with a
Chris@68 12 # blocksize of 1024, and with a step of 1024 for the time-domain version or 512
Chris@68 13 # for the frequency-domain one. That is certainly expected to be the norm for a
Chris@68 14 # plugin like this that declares no preference, and the Python Vamp module is
Chris@76 15 # expected to follow the norm.
Chris@66 16
Chris@68 17 blocksize = 1024
Chris@68 18
Chris@68 19 def input_data(n):
Chris@68 20 # start at 1, not 0 so that all elts are non-zero
Chris@68 21 return np.arange(n) + 1
Chris@68 22
Chris@68 23 def test_process_n():
Chris@68 24 buf = input_data(blocksize)
Chris@112 25 results = list(vamp.process_audio(buf, rate, plugin_key, "input-summary"))
Chris@68 26 assert len(results) == 1
Chris@68 27
Chris@68 28 def test_process_freq_n():
Chris@68 29 buf = input_data(blocksize)
Chris@112 30 results = list(vamp.process_audio(buf, rate, plugin_key_freq, "input-summary", {}))
Chris@68 31 assert len(results) == 2 # one complete block starting at zero, one half-full
Chris@68 32
Chris@74 33 def test_process_default_output():
Chris@74 34 # If no output is specified, we should get the first one (instants)
Chris@74 35 buf = input_data(blocksize)
Chris@112 36 results = list(vamp.process_audio(buf, rate, plugin_key, "", {}))
Chris@74 37 assert len(results) == 10
Chris@74 38 for i in range(len(results)):
Chris@74 39 expectedTime = vamp.vampyhost.RealTime('seconds', i * 1.5)
Chris@76 40 actualTime = results[i]["timestamp"]
Chris@74 41 assert expectedTime == actualTime
Chris@76 42
Chris@68 43 def test_process_summary_param():
Chris@68 44 buf = input_data(blocksize * 10)
Chris@112 45 results = list(vamp.process_audio(buf, rate, plugin_key, "input-summary", { "produce_output": 0 }))
Chris@76 46 assert len(results) == 0
Chris@76 47
Chris@76 48 def test_process_multi_summary_param():
Chris@76 49 buf = input_data(blocksize * 10)
Chris@117 50 results = list(vamp.process_audio_multiple_outputs(buf, rate, plugin_key, [ "input-summary" ], { "produce_output": 0 }))
Chris@68 51 assert len(results) == 0
Chris@68 52
Chris@68 53 def test_process_summary_param_bool():
Chris@68 54 buf = input_data(blocksize * 10)
Chris@112 55 results = list(vamp.process_audio(buf, rate, plugin_key, "input-summary", { "produce_output": False }))
Chris@76 56 assert len(results) == 0
Chris@76 57
Chris@76 58 def test_process_multi_summary_param_bool():
Chris@76 59 buf = input_data(blocksize * 10)
Chris@117 60 results = list(vamp.process_audio_multiple_outputs(buf, rate, plugin_key, [ "input-summary" ], { "produce_output": False }))
Chris@68 61 assert len(results) == 0
Chris@68 62
Chris@68 63 def test_process_summary():
Chris@68 64 buf = input_data(blocksize * 10)
Chris@112 65 results = list(vamp.process_audio(buf, rate, plugin_key, "input-summary", {}))
Chris@76 66 assert len(results) == 10
Chris@76 67 for i in range(len(results)):
Chris@76 68 #
Chris@76 69 # each feature has a single value, equal to the number of non-zero elts
Chris@76 70 # in the input block (which is all of them, i.e. the blocksize) plus
Chris@76 71 # the first elt (which is i * blockSize + 1)
Chris@76 72 #
Chris@76 73 expected = blocksize + i * blocksize + 1
Chris@76 74 actual = results[i]["values"][0]
Chris@76 75 assert actual == expected
Chris@76 76
Chris@101 77 def test_process_frames_summary():
Chris@98 78 buf = input_data(blocksize * 10)
Chris@98 79 ff = fr.frames_from_array(buf, blocksize, blocksize)
Chris@98 80 results = list(vamp.process_frames(ff, rate, blocksize, plugin_key, "input-summary", {}))
Chris@98 81 assert len(results) == 10
Chris@98 82 for i in range(len(results)):
Chris@98 83 #
Chris@98 84 # each feature has a single value, equal to the number of non-zero elts
Chris@98 85 # in the input block (which is all of them, i.e. the blocksize) plus
Chris@98 86 # the first elt (which is i * blockSize + 1)
Chris@98 87 #
Chris@98 88 expected = blocksize + i * blocksize + 1
Chris@98 89 actual = results[i]["values"][0]
Chris@98 90 assert actual == expected
Chris@98 91
Chris@76 92 def test_process_multi_summary():
Chris@76 93 buf = input_data(blocksize * 10)
Chris@117 94 results = list(vamp.process_audio_multiple_outputs(buf, rate, plugin_key, [ "input-summary" ], {}))
Chris@68 95 assert len(results) == 10
Chris@68 96 for i in range(len(results)):
Chris@69 97 #
Chris@68 98 # each feature has a single value, equal to the number of non-zero elts
Chris@68 99 # in the input block (which is all of them, i.e. the blocksize) plus
Chris@68 100 # the first elt (which is i * blockSize + 1)
Chris@69 101 #
Chris@68 102 expected = blocksize + i * blocksize + 1
Chris@70 103 actual = results[i]["input-summary"]["values"][0]
Chris@68 104 assert actual == expected
Chris@68 105
Chris@101 106 def test_process_frames_multi_summary():
Chris@100 107 buf = input_data(blocksize * 10)
Chris@100 108 ff = fr.frames_from_array(buf, blocksize, blocksize)
Chris@100 109 results = list(vamp.process_frames_multiple_outputs(ff, rate, blocksize, plugin_key, [ "input-summary" ], {}))
Chris@100 110 assert len(results) == 10
Chris@100 111 for i in range(len(results)):
Chris@100 112 #
Chris@100 113 # each feature has a single value, equal to the number of non-zero elts
Chris@100 114 # in the input block (which is all of them, i.e. the blocksize) plus
Chris@100 115 # the first elt (which is i * blockSize + 1)
Chris@100 116 #
Chris@100 117 expected = blocksize + i * blocksize + 1
Chris@100 118 actual = results[i]["input-summary"]["values"][0]
Chris@100 119 assert actual == expected
Chris@100 120
Chris@68 121 def test_process_freq_summary():
Chris@68 122 buf = input_data(blocksize * 10)
Chris@112 123 results = list(vamp.process_audio(buf, rate, plugin_key_freq, "input-summary", {}))
Chris@68 124 assert len(results) == 20
Chris@68 125 for i in range(len(results)):
Chris@68 126 #
Chris@68 127 # sort of as above, but much much subtler:
Chris@68 128 #
Chris@68 129 # * the input block is converted to frequency domain but then converted
Chris@68 130 # back within the plugin, so the values being reported are time-domain
Chris@68 131 # ones but with windowing and FFT shift
Chris@68 132 #
Chris@68 133 # * the effect of FFT shift is that the first element in the
Chris@68 134 # re-converted frame is actually the one that was at the start of the
Chris@68 135 # second half of the original frame
Chris@68 136 #
Chris@68 137 # * and the last block is only half-full, so the "first" elt in that
Chris@68 138 # one, which actually comes from just after the middle of the block,
Chris@68 139 # will be zero
Chris@68 140 #
Chris@68 141 # * windowing does not affect the value of the first elt, because
Chris@68 142 # (before fft shift) it came from the peak of the window shape where
Chris@68 143 # the window value is 1
Chris@68 144 #
Chris@68 145 # * but windowing does affect the number of non-zero elts, because the
Chris@68 146 # asymmetric window used has one value very close to zero in it
Chris@68 147 #
Chris@68 148 # * the step size (the increment in input value from one block to the
Chris@68 149 # next) is only half the block size
Chris@68 150 #
Chris@68 151 expected = i * (blocksize/2) + blocksize/2 + 1 # "first" elt
Chris@68 152 if (i == len(results)-1):
Chris@68 153 expected = 0
Chris@68 154 expected = expected + blocksize - 1 # non-zero elts
Chris@76 155 actual = results[i]["values"][0]
Chris@76 156 eps = 1e-6
Chris@76 157 assert abs(actual - expected) < eps
Chris@76 158
Chris@140 159 def test_process_freq_summary_shift():
Chris@140 160 buf = input_data(blocksize * 10)
Chris@140 161 results = list(vamp.process_audio(buf, rate, plugin_key_freq, "input-summary", {}, process_timestamp_method = vamp.vampyhost.SHIFT_DATA))
Chris@140 162 assert len(results) == 20
Chris@140 163 for i in range(len(results)):
Chris@140 164 # as test_process_freq_summary, except that the input is effectively
Chris@140 165 # padded by the adapter with an additional half-blocksize of zeros
Chris@140 166 # before conversion
Chris@140 167 if i == 0:
Chris@140 168 # this block doesn't interact at all well with our test, we get
Chris@140 169 # spurious low values in the block converted back within the plugin
Chris@140 170 # because of the big discontinuity & window ripple after fftshift
Chris@140 171 pass
Chris@140 172 else:
Chris@140 173 expected = (i-1) * (blocksize/2) + blocksize/2 + 1 # for "first" elt
Chris@140 174 expected = expected + blocksize - 1 # non-zero elts
Chris@140 175 actual = results[i]["values"][0]
Chris@140 176 eps = 1e-6
Chris@140 177 assert abs(actual - expected) < eps
Chris@140 178
Chris@76 179 def test_process_multi_freq_summary():
Chris@76 180 buf = input_data(blocksize * 10)
Chris@117 181 results = list(vamp.process_audio_multiple_outputs(buf, rate, plugin_key_freq, [ "input-summary" ], {}))
Chris@76 182 assert len(results) == 20
Chris@76 183 for i in range(len(results)):
Chris@76 184 expected = i * (blocksize/2) + blocksize/2 + 1 # "first" elt
Chris@76 185 if (i == len(results)-1):
Chris@76 186 expected = 0
Chris@76 187 expected = expected + blocksize - 1 # non-zero elts
Chris@70 188 actual = results[i]["input-summary"]["values"][0]
Chris@68 189 eps = 1e-6
Chris@68 190 assert abs(actual - expected) < eps
Chris@68 191
Chris@69 192 def test_process_timestamps():
Chris@69 193 buf = input_data(blocksize * 10)
Chris@112 194 results = list(vamp.process_audio(buf, rate, plugin_key, "input-timestamp", {}))
Chris@76 195 assert len(results) == 10
Chris@76 196 for i in range(len(results)):
Chris@76 197 # The timestamp should be the frame number of the first frame in the
Chris@76 198 # input buffer
Chris@76 199 expected = i * blocksize
Chris@76 200 actual = results[i]["values"][0]
Chris@76 201 assert actual == expected
Chris@76 202
Chris@76 203 def test_process_multi_timestamps():
Chris@76 204 buf = input_data(blocksize * 10)
Chris@117 205 results = list(vamp.process_audio_multiple_outputs(buf, rate, plugin_key, [ "input-timestamp" ]))
Chris@69 206 assert len(results) == 10
Chris@69 207 for i in range(len(results)):
Chris@69 208 # The timestamp should be the frame number of the first frame in the
Chris@69 209 # input buffer
Chris@69 210 expected = i * blocksize
Chris@70 211 actual = results[i]["input-timestamp"]["values"][0]
Chris@69 212 assert actual == expected
Chris@69 213
Chris@69 214 def test_process_freq_timestamps():
Chris@69 215 buf = input_data(blocksize * 10)
Chris@112 216 results = list(vamp.process_audio(buf, rate, plugin_key_freq, "input-timestamp", {}))
Chris@76 217 assert len(results) == 20
Chris@76 218 for i in range(len(results)):
Chris@76 219 # The timestamp should be the frame number of the frame just beyond
Chris@76 220 # half-way through the input buffer
Chris@76 221 expected = i * (blocksize/2) + blocksize/2
Chris@76 222 actual = results[i]["values"][0]
Chris@116 223 if actual == 2047 and expected == 2048:
Chris@116 224 print("This test fails because of a bug in the Vamp plugin SDK. Please update to SDK version 2.6.")
Chris@76 225 assert actual == expected
Chris@76 226
Chris@142 227 def test_process_freq_shift_timestamps():
Chris@142 228 buf = input_data(blocksize * 10)
Chris@142 229 results = list(vamp.process_audio(buf, rate, plugin_key_freq, "input-timestamp", process_timestamp_method = vamp.vampyhost.SHIFT_DATA))
Chris@142 230 assert len(results) == 20
Chris@142 231 for i in range(len(results)):
Chris@142 232 # The timestamp should be the frame number of the frame at the start of
Chris@142 233 # the input buffer
Chris@142 234 expected = i * (blocksize/2)
Chris@142 235 actual = results[i]["values"][0]
Chris@142 236 if actual == 2047 and expected == 2048:
Chris@142 237 print("This test fails because of a bug in the Vamp plugin SDK. Please update to SDK version 2.6.")
Chris@142 238 assert actual == expected
Chris@142 239
Chris@76 240 def test_process_multi_freq_timestamps():
Chris@76 241 buf = input_data(blocksize * 10)
Chris@117 242 results = list(vamp.process_audio_multiple_outputs(buf, rate, plugin_key_freq, [ "input-timestamp" ], {}))
Chris@69 243 assert len(results) == 20
Chris@69 244 for i in range(len(results)):
Chris@69 245 # The timestamp should be the frame number of the frame just beyond
Chris@69 246 # half-way through the input buffer
Chris@69 247 expected = i * (blocksize/2) + blocksize/2
Chris@70 248 actual = results[i]["input-timestamp"]["values"][0]
Chris@116 249 if actual == 2047 and expected == 2048:
Chris@116 250 print("This test fails because of a bug in the Vamp plugin SDK. Please update to SDK version 2.6.")
Chris@69 251 assert actual == expected
Chris@74 252
Chris@142 253 def test_process_blocksize_timestamps():
Chris@142 254 buf = input_data(blocksize * 10)
Chris@142 255 results = list(vamp.process_audio(buf, rate, plugin_key, "input-timestamp", {}, block_size = blocksize * 2)) # step size defaults to block size
Chris@142 256 assert len(results) == 5
Chris@142 257 for i in range(len(results)):
Chris@142 258 # The timestamp should be the frame number of the first frame in the
Chris@142 259 # input buffer
Chris@142 260 expected = i * blocksize * 2
Chris@142 261 actual = results[i]["values"][0]
Chris@142 262 assert actual == expected
Chris@142 263
Chris@142 264 def test_process_stepsize_timestamps():
Chris@142 265 buf = input_data(blocksize * 10)
Chris@147 266 results = list(vamp.process_audio(buf, rate, plugin_key, "input-timestamp", {}, step_size = int(blocksize / 2)))
Chris@142 267 assert len(results) == 20
Chris@142 268 for i in range(len(results)):
Chris@142 269 # The timestamp should be the frame number of the first frame in the
Chris@142 270 # input buffer
Chris@142 271 expected = (i * blocksize) / 2
Chris@142 272 actual = results[i]["values"][0]
Chris@142 273 assert actual == expected
Chris@142 274
Chris@142 275 def test_process_stepsize_blocksize_timestamps():
Chris@142 276 buf = input_data(blocksize * 10)
Chris@147 277 results = list(vamp.process_audio(buf, rate, plugin_key, "input-timestamp", {}, block_size = blocksize * 2, step_size = int(blocksize / 2)))
Chris@142 278 assert len(results) == 20
Chris@142 279 for i in range(len(results)):
Chris@142 280 # The timestamp should be the frame number of the first frame in the
Chris@142 281 # input buffer
Chris@142 282 expected = (i * blocksize) / 2
Chris@142 283 actual = results[i]["values"][0]
Chris@142 284 assert actual == expected
Chris@142 285
Chris@74 286 def test_process_multiple_outputs():
Chris@74 287 buf = input_data(blocksize * 10)
Chris@117 288 results = list(vamp.process_audio_multiple_outputs(buf, rate, plugin_key, [ "input-summary", "input-timestamp" ], {}))
Chris@74 289 assert len(results) == 20
Chris@74 290 si = 0
Chris@74 291 ti = 0
Chris@74 292 for r in results:
Chris@74 293 assert "input-summary" in r or "input-timestamp" in r
Chris@74 294 if "input-summary" in r:
Chris@74 295 expected = blocksize + si * blocksize + 1
Chris@74 296 actual = r["input-summary"]["values"][0]
Chris@74 297 assert actual == expected
Chris@74 298 si = si + 1
Chris@74 299 if "input-timestamp" in r:
Chris@74 300 expected = ti * blocksize
Chris@74 301 actual = r["input-timestamp"]["values"][0]
Chris@74 302 assert actual == expected
Chris@74 303 ti = ti + 1