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
|