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 ):
|
amine@418
|
269 assert isinstance(obs, cls)
|
amine@418
|
270
|
amine@418
|
271
|
amine@418
|
272 def test_initialize_workers_all_plus_audio_event_joiner():
|
amine@418
|
273 with patch("auditok.cmdline_util.player_for") as patched_player_for:
|
amine@418
|
274 with TemporaryDirectory() as tmpdir:
|
amine@418
|
275 export_filename = os.path.join(tmpdir, "output.wav")
|
amine@418
|
276 reader, tokenizer_worker = initialize_workers(
|
amine@418
|
277 input="tests/data/test_16KHZ_mono_400Hz.wav",
|
amine@418
|
278 save_stream=export_filename,
|
amine@418
|
279 export_format="wave",
|
amine@418
|
280 save_detections_as="{id}.wav",
|
amine@418
|
281 join_detections=1,
|
amine@418
|
282 echo=True,
|
amine@418
|
283 progress_bar=False,
|
amine@418
|
284 command="some command",
|
amine@418
|
285 quiet=False,
|
amine@418
|
286 printf="abcd",
|
amine@418
|
287 time_format="%S",
|
amine@418
|
288 timestamp_format="%h:%M:%S",
|
amine@418
|
289 )
|
amine@418
|
290 assert patched_player_for.called
|
amine@418
|
291 assert not isinstance(reader, StreamSaverWorker)
|
amine@418
|
292 for obs, cls in zip(
|
amine@418
|
293 tokenizer_worker._observers,
|
amine@418
|
294 [
|
amine@418
|
295 AudioEventsJoinerWorker,
|
amine@418
|
296 RegionSaverWorker,
|
amine@418
|
297 PlayerWorker,
|
amine@418
|
298 CommandLineWorker,
|
amine@418
|
299 PrintWorker,
|
amine@418
|
300 ],
|
amine@400
|
301 ):
|
amine@400
|
302 assert isinstance(obs, cls)
|
amine@400
|
303
|
amine@400
|
304
|
amine@400
|
305 def test_initialize_workers_no_RegionSaverWorker():
|
amine@400
|
306 with patch("auditok.cmdline_util.player_for") as patched_player_for:
|
amine@400
|
307 with TemporaryDirectory() as tmpdir:
|
amine@400
|
308 export_filename = os.path.join(tmpdir, "output.wav")
|
amine@418
|
309 reader, tokenizer_worker = initialize_workers(
|
amine@400
|
310 input="tests/data/test_16KHZ_mono_400Hz.wav",
|
amine@400
|
311 save_stream=export_filename,
|
amine@271
|
312 export_format="wave",
|
amine@271
|
313 save_detections_as=None,
|
amine@418
|
314 join_detections=None,
|
amine@271
|
315 echo=True,
|
amine@271
|
316 progress_bar=False,
|
amine@400
|
317 command="some command",
|
amine@400
|
318 quiet=False,
|
amine@400
|
319 printf="abcd",
|
amine@400
|
320 time_format="%S",
|
amine@400
|
321 timestamp_format="%h:%M:%S",
|
amine@400
|
322 )
|
amine@400
|
323 reader.stop()
|
amine@400
|
324 assert patched_player_for.called
|
amine@400
|
325 assert isinstance(reader, StreamSaverWorker)
|
amine@400
|
326 for obs, cls in zip(
|
amine@418
|
327 tokenizer_worker._observers,
|
amine@418
|
328 [PlayerWorker, CommandLineWorker, PrintWorker],
|
amine@400
|
329 ):
|
amine@400
|
330 assert isinstance(obs, cls)
|
amine@400
|
331
|
amine@400
|
332
|
amine@400
|
333 def test_initialize_workers_no_PlayerWorker():
|
amine@400
|
334 with patch("auditok.cmdline_util.player_for") as patched_player_for:
|
amine@400
|
335 with TemporaryDirectory() as tmpdir:
|
amine@400
|
336 export_filename = os.path.join(tmpdir, "output.wav")
|
amine@418
|
337 reader, tokenizer_worker = initialize_workers(
|
amine@400
|
338 input="tests/data/test_16KHZ_mono_400Hz.wav",
|
amine@400
|
339 save_stream=export_filename,
|
amine@400
|
340 export_format="wave",
|
amine@400
|
341 save_detections_as="{id}.wav",
|
amine@418
|
342 join_detections=None,
|
amine@400
|
343 echo=False,
|
amine@400
|
344 progress_bar=False,
|
amine@400
|
345 command="some command",
|
amine@400
|
346 quiet=False,
|
amine@400
|
347 printf="abcd",
|
amine@400
|
348 time_format="%S",
|
amine@400
|
349 timestamp_format="%h:%M:%S",
|
amine@400
|
350 )
|
amine@400
|
351 reader.stop()
|
amine@400
|
352 assert not patched_player_for.called
|
amine@400
|
353 assert isinstance(reader, StreamSaverWorker)
|
amine@400
|
354 for obs, cls in zip(
|
amine@418
|
355 tokenizer_worker._observers,
|
amine@400
|
356 [RegionSaverWorker, CommandLineWorker, PrintWorker],
|
amine@400
|
357 ):
|
amine@400
|
358 assert isinstance(obs, cls)
|
amine@400
|
359
|
amine@400
|
360
|
amine@400
|
361 def test_initialize_workers_no_CommandLineWorker():
|
amine@400
|
362 with patch("auditok.cmdline_util.player_for") as patched_player_for:
|
amine@400
|
363 with TemporaryDirectory() as tmpdir:
|
amine@400
|
364 export_filename = os.path.join(tmpdir, "output.wav")
|
amine@418
|
365 reader, tokenizer_worker = initialize_workers(
|
amine@400
|
366 input="tests/data/test_16KHZ_mono_400Hz.wav",
|
amine@400
|
367 save_stream=export_filename,
|
amine@400
|
368 export_format="wave",
|
amine@400
|
369 save_detections_as="{id}.wav",
|
amine@418
|
370 join_detections=None,
|
amine@400
|
371 echo=True,
|
amine@400
|
372 progress_bar=False,
|
amine@271
|
373 command=None,
|
amine@400
|
374 quiet=False,
|
amine@400
|
375 printf="abcd",
|
amine@400
|
376 time_format="%S",
|
amine@400
|
377 timestamp_format="%h:%M:%S",
|
amine@400
|
378 )
|
amine@400
|
379 reader.stop()
|
amine@400
|
380 assert patched_player_for.called
|
amine@400
|
381 assert isinstance(reader, StreamSaverWorker)
|
amine@400
|
382 for obs, cls in zip(
|
amine@418
|
383 tokenizer_worker._observers,
|
amine@418
|
384 [RegionSaverWorker, PlayerWorker, PrintWorker],
|
amine@400
|
385 ):
|
amine@400
|
386 assert isinstance(obs, cls)
|
amine@400
|
387
|
amine@400
|
388
|
amine@400
|
389 def test_initialize_workers_no_PrintWorker():
|
amine@400
|
390 with patch("auditok.cmdline_util.player_for") as patched_player_for:
|
amine@400
|
391 with TemporaryDirectory() as tmpdir:
|
amine@400
|
392 export_filename = os.path.join(tmpdir, "output.wav")
|
amine@418
|
393 reader, tokenizer_worker = initialize_workers(
|
amine@400
|
394 input="tests/data/test_16KHZ_mono_400Hz.wav",
|
amine@400
|
395 save_stream=export_filename,
|
amine@400
|
396 export_format="wave",
|
amine@400
|
397 save_detections_as="{id}.wav",
|
amine@418
|
398 join_detections=None,
|
amine@400
|
399 echo=True,
|
amine@400
|
400 progress_bar=False,
|
amine@400
|
401 command="some command",
|
amine@271
|
402 quiet=True,
|
amine@271
|
403 printf="abcd",
|
amine@271
|
404 time_format="%S",
|
amine@271
|
405 timestamp_format="%h:%M:%S",
|
amine@271
|
406 )
|
amine@400
|
407 reader.stop()
|
amine@400
|
408 assert patched_player_for.called
|
amine@400
|
409 assert isinstance(reader, StreamSaverWorker)
|
amine@400
|
410 for obs, cls in zip(
|
amine@418
|
411 tokenizer_worker._observers,
|
amine@400
|
412 [RegionSaverWorker, PlayerWorker, CommandLineWorker],
|
amine@400
|
413 ):
|
amine@400
|
414 assert isinstance(obs, cls)
|
amine@337
|
415
|
amine@337
|
416
|
amine@400
|
417 def test_initialize_workers_no_observers():
|
amine@400
|
418 with patch("auditok.cmdline_util.player_for") as patched_player_for:
|
amine@418
|
419 reader, tokenizer_worker = initialize_workers(
|
amine@400
|
420 input="tests/data/test_16KHZ_mono_400Hz.wav",
|
amine@400
|
421 save_stream=None,
|
amine@400
|
422 export_format="wave",
|
amine@400
|
423 save_detections_as=None,
|
amine@400
|
424 echo=True,
|
amine@400
|
425 progress_bar=False,
|
amine@400
|
426 command=None,
|
amine@400
|
427 quiet=True,
|
amine@400
|
428 printf="abcd",
|
amine@400
|
429 time_format="%S",
|
amine@400
|
430 timestamp_format="%h:%M:%S",
|
amine@400
|
431 )
|
amine@400
|
432 assert patched_player_for.called
|
amine@400
|
433 assert not isinstance(reader, StreamSaverWorker)
|
amine@418
|
434 assert len(tokenizer_worker._observers) == 1
|