amine@269
|
1 import os
|
amine@403
|
2 from collections import namedtuple
|
amine@403
|
3 from tempfile import TemporaryDirectory
|
amine@403
|
4 from unittest.mock import patch
|
amine@403
|
5
|
amine@400
|
6 import pytest
|
amine@267
|
7
|
amine@267
|
8 from auditok.cmdline_util import (
|
amine@273
|
9 _AUDITOK_LOGGER,
|
amine@403
|
10 KeywordArguments,
|
amine@403
|
11 initialize_workers,
|
amine@267
|
12 make_kwargs,
|
amine@267
|
13 make_logger,
|
amine@267
|
14 )
|
amine@421
|
15 from auditok.exceptions import ArgumentError
|
amine@271
|
16 from auditok.workers import (
|
amine@418
|
17 AudioEventsJoinerWorker,
|
amine@403
|
18 CommandLineWorker,
|
amine@403
|
19 PlayerWorker,
|
amine@403
|
20 PrintWorker,
|
amine@403
|
21 RegionSaverWorker,
|
amine@271
|
22 StreamSaverWorker,
|
amine@271
|
23 )
|
amine@267
|
24
|
amine@400
|
25 _ArgsNamespace = namedtuple(
|
amine@400
|
26 "_ArgsNamespace",
|
amine@267
|
27 [
|
amine@267
|
28 "input",
|
amine@292
|
29 "max_read",
|
amine@267
|
30 "analysis_window",
|
amine@267
|
31 "sampling_rate",
|
amine@267
|
32 "sample_width",
|
amine@267
|
33 "channels",
|
amine@267
|
34 "use_channel",
|
amine@267
|
35 "input_format",
|
amine@267
|
36 "output_format",
|
amine@267
|
37 "large_file",
|
amine@267
|
38 "frame_per_buffer",
|
amine@267
|
39 "input_device_index",
|
amine@267
|
40 "save_stream",
|
amine@292
|
41 "save_detections_as",
|
amine@418
|
42 "join_detections",
|
amine@267
|
43 "plot",
|
amine@267
|
44 "save_image",
|
amine@267
|
45 "min_duration",
|
amine@267
|
46 "max_duration",
|
amine@267
|
47 "max_silence",
|
amine@267
|
48 "drop_trailing_silence",
|
amine@267
|
49 "strict_min_duration",
|
amine@267
|
50 "energy_threshold",
|
amine@267
|
51 "echo",
|
amine@292
|
52 "progress_bar",
|
amine@267
|
53 "command",
|
amine@267
|
54 "quiet",
|
amine@267
|
55 "printf",
|
amine@267
|
56 "time_format",
|
amine@267
|
57 "timestamp_format",
|
amine@267
|
58 ],
|
amine@267
|
59 )
|
amine@267
|
60
|
amine@267
|
61
|
amine@400
|
62 @pytest.mark.parametrize(
|
amine@418
|
63 "save_stream, save_detections_as, join_detections, plot, save_image, use_channel, exp_use_channel, exp_record", # noqa: B950
|
amine@400
|
64 [
|
amine@418
|
65 # no_record_no_join
|
amine@418
|
66 ("stream.ogg", None, None, False, None, "mix", "mix", False),
|
amine@418
|
67 # no_record_plot_join
|
amine@418
|
68 ("stream.ogg", None, 1.0, True, None, None, None, False),
|
amine@400
|
69 # no_record_save_image
|
amine@418
|
70 ("stream.ogg", None, None, True, "image.png", None, None, False),
|
amine@400
|
71 # record_plot
|
amine@418
|
72 (None, None, None, True, None, None, None, True),
|
amine@400
|
73 # record_save_image
|
amine@418
|
74 (None, None, None, False, "image.png", None, None, True),
|
amine@400
|
75 # int_use_channel
|
amine@418
|
76 ("stream.ogg", None, None, False, None, "1", 1, False),
|
amine@400
|
77 # save_detections_as
|
amine@418
|
78 ("stream.ogg", "{id}.wav", None, False, None, None, None, False),
|
amine@400
|
79 ],
|
amine@400
|
80 ids=[
|
amine@418
|
81 "no_record_no_join",
|
amine@400
|
82 "no_record_plot",
|
amine@400
|
83 "no_record_save_image",
|
amine@400
|
84 "record_plot",
|
amine@400
|
85 "record_save_image",
|
amine@400
|
86 "int_use_channel",
|
amine@400
|
87 "save_detections_as",
|
amine@400
|
88 ],
|
amine@400
|
89 )
|
amine@400
|
90 def test_make_kwargs(
|
amine@400
|
91 save_stream,
|
amine@400
|
92 save_detections_as,
|
amine@418
|
93 join_detections,
|
amine@400
|
94 plot,
|
amine@400
|
95 save_image,
|
amine@400
|
96 use_channel,
|
amine@400
|
97 exp_use_channel,
|
amine@400
|
98 exp_record,
|
amine@400
|
99 ):
|
amine@400
|
100 args = (
|
amine@400
|
101 "file",
|
amine@400
|
102 30,
|
amine@400
|
103 0.01,
|
amine@400
|
104 16000,
|
amine@400
|
105 2,
|
amine@400
|
106 2,
|
amine@400
|
107 use_channel,
|
amine@400
|
108 "raw",
|
amine@400
|
109 "ogg",
|
amine@400
|
110 True,
|
amine@400
|
111 None,
|
amine@400
|
112 1,
|
amine@267
|
113 save_stream,
|
amine@292
|
114 save_detections_as,
|
amine@418
|
115 join_detections,
|
amine@267
|
116 plot,
|
amine@267
|
117 save_image,
|
amine@400
|
118 0.2,
|
amine@400
|
119 10,
|
amine@400
|
120 0.3,
|
amine@400
|
121 False,
|
amine@400
|
122 False,
|
amine@400
|
123 55,
|
amine@400
|
124 )
|
amine@400
|
125 misc = (
|
amine@400
|
126 False,
|
amine@400
|
127 False,
|
amine@400
|
128 None,
|
amine@400
|
129 True,
|
amine@400
|
130 None,
|
amine@400
|
131 "TIME_FORMAT",
|
amine@400
|
132 "TIMESTAMP_FORMAT",
|
amine@400
|
133 )
|
amine@400
|
134 args_ns = _ArgsNamespace(*(args + misc))
|
amine@267
|
135
|
amine@400
|
136 io_kwargs = {
|
amine@400
|
137 "input": "file",
|
amine@400
|
138 "max_read": 30,
|
amine@400
|
139 "block_dur": 0.01,
|
amine@400
|
140 "sampling_rate": 16000,
|
amine@400
|
141 "sample_width": 2,
|
amine@400
|
142 "channels": 2,
|
amine@400
|
143 "use_channel": exp_use_channel,
|
amine@400
|
144 "save_stream": save_stream,
|
amine@400
|
145 "save_detections_as": save_detections_as,
|
amine@418
|
146 "join_detections": join_detections,
|
amine@400
|
147 "audio_format": "raw",
|
amine@400
|
148 "export_format": "ogg",
|
amine@400
|
149 "large_file": True,
|
amine@400
|
150 "frames_per_buffer": None,
|
amine@400
|
151 "input_device_index": 1,
|
amine@400
|
152 "record": exp_record,
|
amine@400
|
153 }
|
amine@267
|
154
|
amine@400
|
155 split_kwargs = {
|
amine@400
|
156 "min_dur": 0.2,
|
amine@400
|
157 "max_dur": 10,
|
amine@400
|
158 "max_silence": 0.3,
|
amine@400
|
159 "drop_trailing_silence": False,
|
amine@400
|
160 "strict_min_dur": False,
|
amine@400
|
161 "energy_threshold": 55,
|
amine@400
|
162 }
|
amine@267
|
163
|
amine@400
|
164 miscellaneous = {
|
amine@400
|
165 "echo": False,
|
amine@400
|
166 "command": None,
|
amine@400
|
167 "progress_bar": False,
|
amine@400
|
168 "quiet": True,
|
amine@400
|
169 "printf": None,
|
amine@400
|
170 "time_format": "TIME_FORMAT",
|
amine@400
|
171 "timestamp_format": "TIMESTAMP_FORMAT",
|
amine@400
|
172 }
|
amine@267
|
173
|
amine@400
|
174 expected = KeywordArguments(io_kwargs, split_kwargs, miscellaneous)
|
amine@400
|
175 kwargs = make_kwargs(args_ns)
|
amine@400
|
176 assert kwargs == expected
|
amine@267
|
177
|
amine@268
|
178
|
amine@421
|
179 def test_make_kwargs_error():
|
amine@421
|
180
|
amine@421
|
181 args = (
|
amine@421
|
182 "file",
|
amine@421
|
183 30,
|
amine@421
|
184 0.01,
|
amine@421
|
185 16000,
|
amine@421
|
186 2,
|
amine@421
|
187 2,
|
amine@421
|
188 1,
|
amine@421
|
189 "raw",
|
amine@421
|
190 "ogg",
|
amine@421
|
191 True,
|
amine@421
|
192 None,
|
amine@421
|
193 1,
|
amine@421
|
194 None, # save_stream
|
amine@421
|
195 None,
|
amine@421
|
196 1.0, # join_detections
|
amine@421
|
197 None,
|
amine@421
|
198 None,
|
amine@421
|
199 0.2,
|
amine@421
|
200 10,
|
amine@421
|
201 0.3,
|
amine@421
|
202 False,
|
amine@421
|
203 False,
|
amine@421
|
204 55,
|
amine@421
|
205 False,
|
amine@421
|
206 False,
|
amine@421
|
207 None,
|
amine@421
|
208 True,
|
amine@421
|
209 None,
|
amine@421
|
210 "TIME_FORMAT",
|
amine@421
|
211 "TIMESTAMP_FORMAT",
|
amine@421
|
212 )
|
amine@421
|
213
|
amine@421
|
214 args_ns = _ArgsNamespace(*args)
|
amine@421
|
215 expected_err_msg = "using --join-detections/-j requires "
|
amine@421
|
216 expected_err_msg += "--save-stream/-O to be specified."
|
amine@421
|
217 with pytest.raises(ArgumentError) as arg_err:
|
amine@421
|
218 make_kwargs(args_ns)
|
amine@421
|
219 assert str(arg_err.value) == expected_err_msg
|
amine@421
|
220
|
amine@421
|
221
|
amine@400
|
222 def test_make_logger_stderr_and_file(capsys):
|
amine@400
|
223 with TemporaryDirectory() as tmpdir:
|
amine@400
|
224 file = os.path.join(tmpdir, "file.log")
|
amine@400
|
225 logger = make_logger(stderr=True, file=file)
|
amine@400
|
226 assert logger.name == _AUDITOK_LOGGER
|
amine@400
|
227 assert len(logger.handlers) == 2
|
amine@400
|
228 assert logger.handlers[1].stream.name == file
|
amine@400
|
229 logger.info("This is a debug message")
|
amine@400
|
230 captured = capsys.readouterr()
|
amine@400
|
231 assert "This is a debug message" in captured.err
|
amine@400
|
232
|
amine@400
|
233
|
amine@400
|
234 def test_make_logger_None():
|
amine@400
|
235 logger = make_logger(stderr=False, file=None)
|
amine@400
|
236 assert logger is None
|
amine@400
|
237
|
amine@400
|
238
|
amine@418
|
239 def test_initialize_workers_all_plus_full_stream_saver():
|
amine@400
|
240 with patch("auditok.cmdline_util.player_for") as patched_player_for:
|
amine@269
|
241 with TemporaryDirectory() as tmpdir:
|
amine@400
|
242 export_filename = os.path.join(tmpdir, "output.wav")
|
amine@418
|
243 reader, tokenizer_worker = initialize_workers(
|
amine@271
|
244 input="tests/data/test_16KHZ_mono_400Hz.wav",
|
amine@400
|
245 save_stream=export_filename,
|
amine@400
|
246 export_format="wave",
|
amine@400
|
247 save_detections_as="{id}.wav",
|
amine@418
|
248 join_detections=None,
|
amine@400
|
249 echo=True,
|
amine@400
|
250 progress_bar=False,
|
amine@400
|
251 command="some command",
|
amine@400
|
252 quiet=False,
|
amine@400
|
253 printf="abcd",
|
amine@400
|
254 time_format="%S",
|
amine@400
|
255 timestamp_format="%h:%M:%S",
|
amine@400
|
256 )
|
amine@400
|
257 reader.stop()
|
amine@400
|
258 assert patched_player_for.called
|
amine@400
|
259 assert isinstance(reader, StreamSaverWorker)
|
amine@400
|
260 for obs, cls in zip(
|
amine@418
|
261 tokenizer_worker._observers,
|
amine@400
|
262 [
|
amine@400
|
263 RegionSaverWorker,
|
amine@400
|
264 PlayerWorker,
|
amine@400
|
265 CommandLineWorker,
|
amine@400
|
266 PrintWorker,
|
amine@400
|
267 ],
|
amine@418
|
268 strict=True,
|
amine@418
|
269 ):
|
amine@418
|
270 assert isinstance(obs, cls)
|
amine@418
|
271
|
amine@418
|
272
|
amine@418
|
273 def test_initialize_workers_all_plus_audio_event_joiner():
|
amine@418
|
274 with patch("auditok.cmdline_util.player_for") as patched_player_for:
|
amine@418
|
275 with TemporaryDirectory() as tmpdir:
|
amine@418
|
276 export_filename = os.path.join(tmpdir, "output.wav")
|
amine@418
|
277 reader, tokenizer_worker = initialize_workers(
|
amine@418
|
278 input="tests/data/test_16KHZ_mono_400Hz.wav",
|
amine@418
|
279 save_stream=export_filename,
|
amine@418
|
280 export_format="wave",
|
amine@418
|
281 save_detections_as="{id}.wav",
|
amine@418
|
282 join_detections=1,
|
amine@418
|
283 echo=True,
|
amine@418
|
284 progress_bar=False,
|
amine@418
|
285 command="some command",
|
amine@418
|
286 quiet=False,
|
amine@418
|
287 printf="abcd",
|
amine@418
|
288 time_format="%S",
|
amine@418
|
289 timestamp_format="%h:%M:%S",
|
amine@418
|
290 )
|
amine@418
|
291 assert patched_player_for.called
|
amine@418
|
292 assert not isinstance(reader, StreamSaverWorker)
|
amine@418
|
293 for obs, cls in zip(
|
amine@418
|
294 tokenizer_worker._observers,
|
amine@418
|
295 [
|
amine@418
|
296 AudioEventsJoinerWorker,
|
amine@418
|
297 RegionSaverWorker,
|
amine@418
|
298 PlayerWorker,
|
amine@418
|
299 CommandLineWorker,
|
amine@418
|
300 PrintWorker,
|
amine@418
|
301 ],
|
amine@418
|
302 strict=True,
|
amine@400
|
303 ):
|
amine@400
|
304 assert isinstance(obs, cls)
|
amine@400
|
305
|
amine@400
|
306
|
amine@400
|
307 def test_initialize_workers_no_RegionSaverWorker():
|
amine@400
|
308 with patch("auditok.cmdline_util.player_for") as patched_player_for:
|
amine@400
|
309 with TemporaryDirectory() as tmpdir:
|
amine@400
|
310 export_filename = os.path.join(tmpdir, "output.wav")
|
amine@418
|
311 reader, tokenizer_worker = initialize_workers(
|
amine@400
|
312 input="tests/data/test_16KHZ_mono_400Hz.wav",
|
amine@400
|
313 save_stream=export_filename,
|
amine@271
|
314 export_format="wave",
|
amine@271
|
315 save_detections_as=None,
|
amine@418
|
316 join_detections=None,
|
amine@271
|
317 echo=True,
|
amine@271
|
318 progress_bar=False,
|
amine@400
|
319 command="some command",
|
amine@400
|
320 quiet=False,
|
amine@400
|
321 printf="abcd",
|
amine@400
|
322 time_format="%S",
|
amine@400
|
323 timestamp_format="%h:%M:%S",
|
amine@400
|
324 )
|
amine@400
|
325 reader.stop()
|
amine@400
|
326 assert patched_player_for.called
|
amine@400
|
327 assert isinstance(reader, StreamSaverWorker)
|
amine@400
|
328 for obs, cls in zip(
|
amine@418
|
329 tokenizer_worker._observers,
|
amine@418
|
330 [PlayerWorker, CommandLineWorker, PrintWorker],
|
amine@418
|
331 strict=True,
|
amine@400
|
332 ):
|
amine@400
|
333 assert isinstance(obs, cls)
|
amine@400
|
334
|
amine@400
|
335
|
amine@400
|
336 def test_initialize_workers_no_PlayerWorker():
|
amine@400
|
337 with patch("auditok.cmdline_util.player_for") as patched_player_for:
|
amine@400
|
338 with TemporaryDirectory() as tmpdir:
|
amine@400
|
339 export_filename = os.path.join(tmpdir, "output.wav")
|
amine@418
|
340 reader, tokenizer_worker = initialize_workers(
|
amine@400
|
341 input="tests/data/test_16KHZ_mono_400Hz.wav",
|
amine@400
|
342 save_stream=export_filename,
|
amine@400
|
343 export_format="wave",
|
amine@400
|
344 save_detections_as="{id}.wav",
|
amine@418
|
345 join_detections=None,
|
amine@400
|
346 echo=False,
|
amine@400
|
347 progress_bar=False,
|
amine@400
|
348 command="some command",
|
amine@400
|
349 quiet=False,
|
amine@400
|
350 printf="abcd",
|
amine@400
|
351 time_format="%S",
|
amine@400
|
352 timestamp_format="%h:%M:%S",
|
amine@400
|
353 )
|
amine@400
|
354 reader.stop()
|
amine@400
|
355 assert not patched_player_for.called
|
amine@400
|
356 assert isinstance(reader, StreamSaverWorker)
|
amine@400
|
357 for obs, cls in zip(
|
amine@418
|
358 tokenizer_worker._observers,
|
amine@400
|
359 [RegionSaverWorker, CommandLineWorker, PrintWorker],
|
amine@418
|
360 strict=True,
|
amine@400
|
361 ):
|
amine@400
|
362 assert isinstance(obs, cls)
|
amine@400
|
363
|
amine@400
|
364
|
amine@400
|
365 def test_initialize_workers_no_CommandLineWorker():
|
amine@400
|
366 with patch("auditok.cmdline_util.player_for") as patched_player_for:
|
amine@400
|
367 with TemporaryDirectory() as tmpdir:
|
amine@400
|
368 export_filename = os.path.join(tmpdir, "output.wav")
|
amine@418
|
369 reader, tokenizer_worker = initialize_workers(
|
amine@400
|
370 input="tests/data/test_16KHZ_mono_400Hz.wav",
|
amine@400
|
371 save_stream=export_filename,
|
amine@400
|
372 export_format="wave",
|
amine@400
|
373 save_detections_as="{id}.wav",
|
amine@418
|
374 join_detections=None,
|
amine@400
|
375 echo=True,
|
amine@400
|
376 progress_bar=False,
|
amine@271
|
377 command=None,
|
amine@400
|
378 quiet=False,
|
amine@400
|
379 printf="abcd",
|
amine@400
|
380 time_format="%S",
|
amine@400
|
381 timestamp_format="%h:%M:%S",
|
amine@400
|
382 )
|
amine@400
|
383 reader.stop()
|
amine@400
|
384 assert patched_player_for.called
|
amine@400
|
385 assert isinstance(reader, StreamSaverWorker)
|
amine@400
|
386 for obs, cls in zip(
|
amine@418
|
387 tokenizer_worker._observers,
|
amine@418
|
388 [RegionSaverWorker, PlayerWorker, PrintWorker],
|
amine@418
|
389 strict=True,
|
amine@400
|
390 ):
|
amine@400
|
391 assert isinstance(obs, cls)
|
amine@400
|
392
|
amine@400
|
393
|
amine@400
|
394 def test_initialize_workers_no_PrintWorker():
|
amine@400
|
395 with patch("auditok.cmdline_util.player_for") as patched_player_for:
|
amine@400
|
396 with TemporaryDirectory() as tmpdir:
|
amine@400
|
397 export_filename = os.path.join(tmpdir, "output.wav")
|
amine@418
|
398 reader, tokenizer_worker = initialize_workers(
|
amine@400
|
399 input="tests/data/test_16KHZ_mono_400Hz.wav",
|
amine@400
|
400 save_stream=export_filename,
|
amine@400
|
401 export_format="wave",
|
amine@400
|
402 save_detections_as="{id}.wav",
|
amine@418
|
403 join_detections=None,
|
amine@400
|
404 echo=True,
|
amine@400
|
405 progress_bar=False,
|
amine@400
|
406 command="some command",
|
amine@271
|
407 quiet=True,
|
amine@271
|
408 printf="abcd",
|
amine@271
|
409 time_format="%S",
|
amine@271
|
410 timestamp_format="%h:%M:%S",
|
amine@271
|
411 )
|
amine@400
|
412 reader.stop()
|
amine@400
|
413 assert patched_player_for.called
|
amine@400
|
414 assert isinstance(reader, StreamSaverWorker)
|
amine@400
|
415 for obs, cls in zip(
|
amine@418
|
416 tokenizer_worker._observers,
|
amine@400
|
417 [RegionSaverWorker, PlayerWorker, CommandLineWorker],
|
amine@418
|
418 strict=True,
|
amine@400
|
419 ):
|
amine@400
|
420 assert isinstance(obs, cls)
|
amine@337
|
421
|
amine@337
|
422
|
amine@400
|
423 def test_initialize_workers_no_observers():
|
amine@400
|
424 with patch("auditok.cmdline_util.player_for") as patched_player_for:
|
amine@418
|
425 reader, tokenizer_worker = initialize_workers(
|
amine@400
|
426 input="tests/data/test_16KHZ_mono_400Hz.wav",
|
amine@400
|
427 save_stream=None,
|
amine@400
|
428 export_format="wave",
|
amine@400
|
429 save_detections_as=None,
|
amine@400
|
430 echo=True,
|
amine@400
|
431 progress_bar=False,
|
amine@400
|
432 command=None,
|
amine@400
|
433 quiet=True,
|
amine@400
|
434 printf="abcd",
|
amine@400
|
435 time_format="%S",
|
amine@400
|
436 timestamp_format="%h:%M:%S",
|
amine@400
|
437 )
|
amine@400
|
438 assert patched_player_for.called
|
amine@400
|
439 assert not isinstance(reader, StreamSaverWorker)
|
amine@418
|
440 assert len(tokenizer_worker._observers) == 1
|