comparison tests/test_core.py @ 405:f56b4d8adfb8

Use numpy instead of audioop everywhere
author Amine Sehili <amine.sehili@gmail.com>
date Mon, 17 Jun 2024 19:45:51 +0200
parents 996948ada980
children 0e938065a2db
comparison
equal deleted inserted replaced
404:08a7af37f2e9 405:f56b4d8adfb8
1 import math 1 import math
2 import os 2 import os
3 from array import array as array_
4 from random import random 3 from random import random
5 from tempfile import TemporaryDirectory 4 from tempfile import TemporaryDirectory
6 from unittest.mock import Mock, patch 5 from unittest.mock import Mock, patch
7 6
7 import numpy as np
8 import pytest 8 import pytest
9 9
10 from auditok import AudioParameterError, AudioRegion, load, split 10 from auditok import AudioParameterError, AudioRegion, load, split
11 from auditok.core import ( 11 from auditok.core import (
12 _duration_to_nb_windows, 12 _duration_to_nb_windows,
13 _make_audio_region, 13 _make_audio_region,
14 _read_chunks_online, 14 _read_chunks_online,
15 _read_offline, 15 _read_offline,
16 ) 16 )
17 from auditok.io import get_audio_source 17 from auditok.io import get_audio_source
18 from auditok.signal import to_array
18 from auditok.util import AudioReader 19 from auditok.util import AudioReader
19 20
20 21
21 def _make_random_length_regions( 22 def _make_random_length_regions(
22 byte_seq, sampling_rate, sample_width, channels 23 byte_seq, sampling_rate, sample_width, channels
31 32
32 33
33 @pytest.mark.parametrize( 34 @pytest.mark.parametrize(
34 "skip, max_read, channels", 35 "skip, max_read, channels",
35 [ 36 [
36 (0, -1, 1), 37 (0, -1, 1), # no_skip_read_all
37 (0, -1, 2), 38 (0, -1, 2), # no_skip_read_all_stereo
38 (2, -1, 1), 39 (2, -1, 1), # skip_2_read_all
39 (2, None, 1), 40 (2, None, 1), # skip_2_read_all_None
40 (2, 3, 1), 41 (2, 3, 1), # skip_2_read_3
41 (2, 3.5, 2), 42 (2, 3.5, 2), # skip_2_read_3_5_stereo
42 (2.4, 3.5, 2), 43 (2.4, 3.5, 2), # skip_2_4_read_3_5_stereo
43 ], 44 ],
44 ids=[ 45 ids=[
45 "no_skip_read_all", 46 "no_skip_read_all",
46 "no_skip_read_all_stereo", 47 "no_skip_read_all_stereo",
47 "skip_2_read_all", 48 "skip_2_read_all",
75 76
76 77
77 @pytest.mark.parametrize( 78 @pytest.mark.parametrize(
78 "duration, analysis_window, round_fn, expected, kwargs", 79 "duration, analysis_window, round_fn, expected, kwargs",
79 [ 80 [
80 (0, 1, None, 0, None), 81 (0, 1, None, 0, None), # zero_duration
81 (0.3, 0.1, round, 3, None), 82 (0.3, 0.1, round, 3, None), # multiple
82 (0.35, 0.1, math.ceil, 4, None), 83 (0.35, 0.1, math.ceil, 4, None), # not_multiple_ceil
83 (0.35, 0.1, math.floor, 3, None), 84 (0.35, 0.1, math.floor, 3, None), # not_multiple_floor
84 (0.05, 0.1, round, 0, None), 85 (0.05, 0.1, round, 0, None), # small_duration
85 (0.05, 0.1, math.ceil, 1, None), 86 (0.05, 0.1, math.ceil, 1, None), # small_duration_ceil
86 (0.3, 0.1, math.floor, 3, {"epsilon": 1e-6}), 87 (0.3, 0.1, math.floor, 3, {"epsilon": 1e-6}), # with_round_error
87 (-0.5, 0.1, math.ceil, ValueError, None), 88 (-0.5, 0.1, math.ceil, ValueError, None), # negative_duration
88 (0.5, -0.1, math.ceil, ValueError, None), 89 (0.5, -0.1, math.ceil, ValueError, None), # negative_analysis_window
89 ], 90 ],
90 ids=[ 91 ids=[
91 "zero_duration", 92 "zero_duration",
92 "multiple", 93 "multiple",
93 "not_multiple_ceil", 94 "not_multiple_ceil",
115 116
116 117
117 @pytest.mark.parametrize( 118 @pytest.mark.parametrize(
118 "channels, skip, max_read", 119 "channels, skip, max_read",
119 [ 120 [
120 (1, 0, None), 121 (1, 0, None), # mono_skip_0_max_read_None
121 (1, 3, None), 122 (1, 3, None), # mono_skip_3_max_read_None
122 (1, 2, -1), 123 (1, 2, -1), # mono_skip_2_max_read_negative
123 (1, 2, 3), 124 (1, 2, 3), # mono_skip_2_max_read_3
124 (2, 0, None), 125 (2, 0, None), # stereo_skip_0_max_read_None
125 (2, 3, None), 126 (2, 3, None), # stereo_skip_3_max_read_None
126 (2, 2, -1), 127 (2, 2, -1), # stereo_skip_2_max_read_negative
127 (2, 2, 3), 128 (2, 2, 3), # stereo_skip_2_max_read_3
128 ], 129 ],
129 ids=[ 130 ids=[
130 "mono_skip_0_max_read_None", 131 "mono_skip_0_max_read_None",
131 "mono_skip_3_max_read_None", 132 "mono_skip_3_max_read_None",
132 "mono_skip_2_max_read_negative", 133 "mono_skip_2_max_read_negative",
163 assert read_data == expected_data 164 assert read_data == expected_data
164 assert tuple(audio_params) == (sampling_rate, sample_width, channels) 165 assert tuple(audio_params) == (sampling_rate, sample_width, channels)
165 166
166 167
167 @pytest.mark.parametrize( 168 @pytest.mark.parametrize(
168 "min_dur, max_dur, max_silence, drop_trailing_silence, strict_min_dur, kwargs, expected", 169 (
169 [ 170 "min_dur, max_dur, max_silence, drop_trailing_silence, "
170 (0.2, 5, 0.2, False, False, {"eth": 50}, [(2, 16), (17, 31), (34, 76)]), 171 + "strict_min_dur, kwargs, expected"
172 ),
173 [
174 (
175 0.2,
176 5,
177 0.2,
178 False,
179 False,
180 {"eth": 50},
181 [(2, 16), (17, 31), (34, 76)],
182 ), # simple
171 ( 183 (
172 0.3, 184 0.3,
173 2, 185 2,
174 0.2, 186 0.2,
175 False, 187 False,
176 False, 188 False,
177 {"eth": 50}, 189 {"eth": 50},
178 [(2, 16), (17, 31), (34, 54), (54, 74), (74, 76)], 190 [(2, 16), (17, 31), (34, 54), (54, 74), (74, 76)],
179 ), 191 ), # short_max_dur
180 (3, 5, 0.2, False, False, {"eth": 50}, [(34, 76)]), 192 (3, 5, 0.2, False, False, {"eth": 50}, [(34, 76)]), # long_min_dur
181 (0.2, 80, 10, False, False, {"eth": 50}, [(2, 76)]), 193 (0.2, 80, 10, False, False, {"eth": 50}, [(2, 76)]), # long_max_silence
182 ( 194 (
183 0.2, 195 0.2,
184 5, 196 5,
185 0.0, 197 0.0,
186 False, 198 False,
187 False, 199 False,
188 {"eth": 50}, 200 {"eth": 50},
189 [(2, 14), (17, 24), (26, 29), (34, 76)], 201 [(2, 14), (17, 24), (26, 29), (34, 76)],
190 ), 202 ), # zero_max_silence
191 ( 203 (
192 0.2, 204 0.2,
193 5, 205 5,
194 0.2, 206 0.2,
195 False, 207 False,
196 False, 208 False,
197 {"energy_threshold": 40}, 209 {"energy_threshold": 40},
198 [(0, 50), (50, 76)], 210 [(0, 50), (50, 76)],
199 ), 211 ), # low_energy_threshold
200 (0.2, 5, 0.2, False, False, {"energy_threshold": 60}, []), 212 (
201 (0.2, 10, 0.5, True, False, {"eth": 50}, [(2, 76)]), 213 0.2,
202 (0.2, 5, 0.2, True, False, {"eth": 50}, [(2, 14), (17, 29), (34, 76)]), 214 5,
203 (1.5, 5, 0.2, True, False, {"eth": 50}, [(34, 76)]), 215 0.2,
216 False,
217 False,
218 {"energy_threshold": 60},
219 [],
220 ), # high_energy_threshold
221 (
222 0.2,
223 10,
224 0.5,
225 True,
226 False,
227 {"eth": 50},
228 [(2, 76)],
229 ), # trim_leading_and_trailing_silence
230 (
231 0.2,
232 5,
233 0.2,
234 True,
235 False,
236 {"eth": 50},
237 [(2, 14), (17, 29), (34, 76)],
238 ), # drop_trailing_silence
239 (
240 1.5,
241 5,
242 0.2,
243 True,
244 False,
245 {"eth": 50},
246 [(34, 76)],
247 ), # drop_trailing_silence_2
204 ( 248 (
205 0.3, 249 0.3,
206 2, 250 2,
207 0.2, 251 0.2,
208 False, 252 False,
209 True, 253 True,
210 {"eth": 50}, 254 {"eth": 50},
211 [(2, 16), (17, 31), (34, 54), (54, 74)], 255 [(2, 16), (17, 31), (34, 54), (54, 74)],
212 ), 256 ), # strict_min_dur
213 ], 257 ],
214 ids=[ 258 ids=[
215 "simple", 259 "simple",
216 "short_max_dur", 260 "short_max_dur",
217 "long_min_dur", 261 "long_min_dur",
270 err_msg = "Wrong number of regions after AudioRegion.split, expected: " 314 err_msg = "Wrong number of regions after AudioRegion.split, expected: "
271 err_msg += "{}, found: {}".format(len(expected), len(regions_ar)) 315 err_msg += "{}, found: {}".format(len(expected), len(regions_ar))
272 assert len(regions_ar) == len(expected), err_msg 316 assert len(regions_ar) == len(expected), err_msg
273 317
274 sample_width = 2 318 sample_width = 2
275 for reg, reg_ar, exp in zip(regions, regions_ar, expected): 319 for reg, reg_ar, exp in zip(regions, regions_ar, expected, strict=True):
276 onset, offset = exp 320 onset, offset = exp
277 exp_data = data[onset * sample_width : offset * sample_width] 321 exp_data = data[onset * sample_width : offset * sample_width]
278 assert bytes(reg) == exp_data 322 assert bytes(reg) == exp_data
279 assert reg == reg_ar 323 assert reg == reg_ar
280 324
281 325
282 @pytest.mark.parametrize( 326 @pytest.mark.parametrize(
283 "channels, kwargs, expected", 327 "channels, kwargs, expected",
284 [ 328 [
285 (2, {}, [(2, 32), (34, 76)]), 329 (2, {}, [(2, 32), (34, 76)]), # stereo_all_default
286 (1, {"max_read": 5}, [(2, 16), (17, 31), (34, 50)]), 330 (1, {"max_read": 5}, [(2, 16), (17, 31), (34, 50)]), # mono_max_read
287 (1, {"mr": 5}, [(2, 16), (17, 31), (34, 50)]), 331 (
288 (1, {"eth": 50, "use_channel": 0}, [(2, 16), (17, 31), (34, 76)]), 332 1,
289 (1, {"eth": 50, "uc": 1}, [(2, 16), (17, 31), (34, 76)]), 333 {"mr": 5},
290 (1, {"eth": 50, "use_channel": None}, [(2, 16), (17, 31), (34, 76)]), 334 [(2, 16), (17, 31), (34, 50)],
291 (2, {"eth": 50, "use_channel": 0}, [(2, 16), (17, 31), (34, 76)]), 335 ), # mono_max_read_short_name
292 (2, {"eth": 50}, [(2, 32), (34, 76)]), 336 (
293 (2, {"eth": 50, "use_channel": -2}, [(2, 16), (17, 31), (34, 76)]), 337 1,
294 (2, {"eth": 50, "uc": 1}, [(10, 32), (36, 76)]), 338 {"eth": 50, "use_channel": 0},
295 (2, {"eth": 50, "uc": -1}, [(10, 32), (36, 76)]), 339 [(2, 16), (17, 31), (34, 76)],
296 (1, {"eth": 50, "uc": "mix"}, [(2, 16), (17, 31), (34, 76)]), 340 ), # mono_use_channel_1
297 (2, {"energy_threshold": 53.5, "use_channel": "mix"}, [(54, 76)]), 341 (1, {"eth": 50, "uc": 1}, [(2, 16), (17, 31), (34, 76)]), # mono_uc_1
298 (2, {"eth": 52, "uc": "mix"}, [(17, 26), (54, 76)]), 342 (
299 (2, {"uc": "mix"}, [(10, 16), (17, 31), (36, 76)]), 343 1,
344 {"eth": 50, "use_channel": None},
345 [(2, 16), (17, 31), (34, 76)],
346 ), # mono_use_channel_None
347 (
348 2,
349 {"eth": 50, "use_channel": 0},
350 [(2, 16), (17, 31), (34, 76)],
351 ), # stereo_use_channel_1
352 (
353 2,
354 {"eth": 50},
355 [(2, 32), (34, 76)],
356 ), # stereo_use_channel_no_use_channel_given
357 (
358 2,
359 {"eth": 50, "use_channel": -2},
360 [(2, 16), (17, 31), (34, 76)],
361 ), # stereo_use_channel_minus_2
362 (2, {"eth": 50, "uc": 1}, [(10, 32), (36, 76)]), # stereo_uc_2
363 (2, {"eth": 50, "uc": -1}, [(10, 32), (36, 76)]), # stereo_uc_minus_1
364 (
365 1,
366 {"eth": 50, "uc": "mix"},
367 [(2, 16), (17, 31), (34, 76)],
368 ), # mono_uc_mix
369 (
370 2,
371 {"energy_threshold": 53.5, "use_channel": "mix"},
372 [(54, 76)],
373 ), # stereo_use_channel_mix
374 (2, {"eth": 52, "uc": "mix"}, [(17, 26), (54, 76)]), # stereo_uc_mix
375 (
376 2,
377 {"uc": "mix"},
378 [(10, 16), (17, 31), (36, 76)],
379 ), # stereo_uc_mix_default_eth
300 ], 380 ],
301 ids=[ 381 ids=[
302 "stereo_all_default", 382 "stereo_all_default",
303 "mono_max_read", 383 "mono_max_read",
304 "mono_max_read_short_name", 384 "mono_max_read_short_name",
363 err_msg += "{}, found: {}".format(len(expected), len(regions_ar)) 443 err_msg += "{}, found: {}".format(len(expected), len(regions_ar))
364 assert len(regions_ar) == len(expected), err_msg 444 assert len(regions_ar) == len(expected), err_msg
365 445
366 sample_width = 2 446 sample_width = 2
367 sample_size_bytes = sample_width * channels 447 sample_size_bytes = sample_width * channels
368 for reg, reg_ar, exp in zip(regions, regions_ar, expected): 448 for reg, reg_ar, exp in zip(regions, regions_ar, expected, strict=True):
369 onset, offset = exp 449 onset, offset = exp
370 exp_data = data[onset * sample_size_bytes : offset * sample_size_bytes] 450 exp_data = data[onset * sample_size_bytes : offset * sample_size_bytes]
371 assert len(bytes(reg)) == len(exp_data) 451 assert len(bytes(reg)) == len(exp_data)
372 assert reg == reg_ar 452 assert reg == reg_ar
373 453
374 454
375 @pytest.mark.parametrize( 455 @pytest.mark.parametrize(
376 "min_dur, max_dur, max_silence, channels, kwargs, expected", 456 "min_dur, max_dur, max_silence, channels, kwargs, expected",
377 [ 457 [
378 (0.2, 5, 0.2, 1, {"aw": 0.2}, [(2, 30), (34, 76)]), 458 (
379 (0.2, 5, 0.3, 1, {"aw": 0.2}, [(2, 30), (34, 76)]), 459 0.2,
380 (0.2, 5, 0.4, 1, {"aw": 0.2}, [(2, 32), (34, 76)]), 460 5,
381 (0.2, 5, 0, 1, {"aw": 0.2}, [(2, 14), (16, 24), (26, 28), (34, 76)]), 461 0.2,
382 (0.2, 5, 0.2, 1, {"aw": 0.2}, [(2, 30), (34, 76)]), 462 1,
383 (0.3, 5, 0, 1, {"aw": 0.3}, [(3, 12), (15, 24), (36, 76)]), 463 {"aw": 0.2},
384 (0.3, 5, 0.3, 1, {"aw": 0.3}, [(3, 27), (36, 76)]), 464 [(2, 30), (34, 76)],
385 (0.3, 5, 0.5, 1, {"aw": 0.3}, [(3, 27), (36, 76)]), 465 ), # mono_aw_0_2_max_silence_0_2
386 (0.3, 5, 0.6, 1, {"aw": 0.3}, [(3, 30), (36, 76)]), 466 (
387 (0.2, 5, 0, 1, {"aw": 0.4}, [(4, 12), (16, 24), (36, 76)]), 467 0.2,
388 (0.2, 5, 0.3, 1, {"aw": 0.4}, [(4, 12), (16, 24), (36, 76)]), 468 5,
389 (0.2, 5, 0.4, 1, {"aw": 0.4}, [(4, 28), (36, 76)]), 469 0.3,
390 (0.2, 5, 0.2, 2, {"analysis_window": 0.2}, [(2, 32), (34, 76)]), 470 1,
471 {"aw": 0.2},
472 [(2, 30), (34, 76)],
473 ), # mono_aw_0_2_max_silence_0_3
474 (
475 0.2,
476 5,
477 0.4,
478 1,
479 {"aw": 0.2},
480 [(2, 32), (34, 76)],
481 ), # mono_aw_0_2_max_silence_0_4
482 (
483 0.2,
484 5,
485 0,
486 1,
487 {"aw": 0.2},
488 [(2, 14), (16, 24), (26, 28), (34, 76)],
489 ), # mono_aw_0_2_max_silence_0
490 (0.2, 5, 0.2, 1, {"aw": 0.2}, [(2, 30), (34, 76)]), # mono_aw_0_2
491 (
492 0.3,
493 5,
494 0,
495 1,
496 {"aw": 0.3},
497 [(3, 12), (15, 24), (36, 76)],
498 ), # mono_aw_0_3_max_silence_0
499 (
500 0.3,
501 5,
502 0.3,
503 1,
504 {"aw": 0.3},
505 [(3, 27), (36, 76)],
506 ), # mono_aw_0_3_max_silence_0_3
507 (
508 0.3,
509 5,
510 0.5,
511 1,
512 {"aw": 0.3},
513 [(3, 27), (36, 76)],
514 ), # mono_aw_0_3_max_silence_0_5
515 (
516 0.3,
517 5,
518 0.6,
519 1,
520 {"aw": 0.3},
521 [(3, 30), (36, 76)],
522 ), # mono_aw_0_3_max_silence_0_6
523 (
524 0.2,
525 5,
526 0,
527 1,
528 {"aw": 0.4},
529 [(4, 12), (16, 24), (36, 76)],
530 ), # mono_aw_0_4_max_silence_0
531 (
532 0.2,
533 5,
534 0.3,
535 1,
536 {"aw": 0.4},
537 [(4, 12), (16, 24), (36, 76)],
538 ), # mono_aw_0_4_max_silence_0_3
539 (
540 0.2,
541 5,
542 0.4,
543 1,
544 {"aw": 0.4},
545 [(4, 28), (36, 76)],
546 ), # mono_aw_0_4_max_silence_0_4
547 (
548 0.2,
549 5,
550 0.2,
551 2,
552 {"analysis_window": 0.2},
553 [(2, 32), (34, 76)],
554 ), # stereo_uc_None_analysis_window_0_2
391 ( 555 (
392 0.2, 556 0.2,
393 5, 557 5,
394 0.2, 558 0.2,
395 2, 559 2,
396 {"uc": None, "analysis_window": 0.2}, 560 {"uc": None, "analysis_window": 0.2},
397 [(2, 32), (34, 76)], 561 [(2, 32), (34, 76)],
398 ), 562 ), # stereo_uc_any_analysis_window_0_2
399 ( 563 (
400 0.2, 564 0.2,
401 5, 565 5,
402 0.2, 566 0.2,
403 2, 567 2,
404 {"use_channel": None, "analysis_window": 0.3}, 568 {"use_channel": None, "analysis_window": 0.3},
405 [(3, 30), (36, 76)], 569 [(3, 30), (36, 76)],
406 ), 570 ), # stereo_use_channel_None_aw_0_3_max_silence_0_2
407 ( 571 (
408 0.2, 572 0.2,
409 5, 573 5,
410 0.3, 574 0.3,
411 2, 575 2,
412 {"use_channel": "any", "analysis_window": 0.3}, 576 {"use_channel": "any", "analysis_window": 0.3},
413 [(3, 33), (36, 76)], 577 [(3, 33), (36, 76)],
414 ), 578 ), # stereo_use_channel_any_aw_0_3_max_silence_0_3
415 ( 579 (
416 0.2, 580 0.2,
417 5, 581 5,
418 0.2, 582 0.2,
419 2, 583 2,
420 {"use_channel": None, "analysis_window": 0.4}, 584 {"use_channel": None, "analysis_window": 0.4},
421 [(4, 28), (36, 76)], 585 [(4, 28), (36, 76)],
422 ), 586 ), # stereo_use_channel_None_aw_0_4_max_silence_0_2
423 ( 587 (
424 0.2, 588 0.2,
425 5, 589 5,
426 0.4, 590 0.4,
427 2, 591 2,
428 {"use_channel": "any", "analysis_window": 0.4}, 592 {"use_channel": "any", "analysis_window": 0.4},
429 [(4, 32), (36, 76)], 593 [(4, 32), (36, 76)],
430 ), 594 ), # stereo_use_channel_any_aw_0_3_max_silence_0_4
431 ( 595 (
432 0.2, 596 0.2,
433 5, 597 5,
434 0.2, 598 0.2,
435 2, 599 2,
436 {"uc": 0, "analysis_window": 0.2}, 600 {"uc": 0, "analysis_window": 0.2},
437 [(2, 30), (34, 76)], 601 [(2, 30), (34, 76)],
438 ), 602 ), # stereo_uc_0_analysis_window_0_2
439 ( 603 (
440 0.2, 604 0.2,
441 5, 605 5,
442 0.2, 606 0.2,
443 2, 607 2,
444 {"uc": 1, "analysis_window": 0.2}, 608 {"uc": 1, "analysis_window": 0.2},
445 [(10, 32), (36, 76)], 609 [(10, 32), (36, 76)],
446 ), 610 ), # stereo_uc_1_analysis_window_0_2
447 ( 611 (
448 0.2, 612 0.2,
449 5, 613 5,
450 0, 614 0,
451 2, 615 2,
452 {"uc": "mix", "analysis_window": 0.1}, 616 {"uc": "mix", "analysis_window": 0.1},
453 [(10, 14), (17, 24), (26, 29), (36, 76)], 617 [(10, 14), (17, 24), (26, 29), (36, 76)],
454 ), 618 ), # stereo_uc_mix_aw_0_1_max_silence_0
455 ( 619 (
456 0.2, 620 0.2,
457 5, 621 5,
458 0.1, 622 0.1,
459 2, 623 2,
460 {"uc": "mix", "analysis_window": 0.1}, 624 {"uc": "mix", "analysis_window": 0.1},
461 [(10, 15), (17, 25), (26, 30), (36, 76)], 625 [(10, 15), (17, 25), (26, 30), (36, 76)],
462 ), 626 ), # stereo_uc_mix_aw_0_1_max_silence_0_1
463 ( 627 (
464 0.2, 628 0.2,
465 5, 629 5,
466 0.2, 630 0.2,
467 2, 631 2,
468 {"uc": "mix", "analysis_window": 0.1}, 632 {"uc": "mix", "analysis_window": 0.1},
469 [(10, 16), (17, 31), (36, 76)], 633 [(10, 16), (17, 31), (36, 76)],
470 ), 634 ), # stereo_uc_mix_aw_0_1_max_silence_0_2
471 ( 635 (
472 0.2, 636 0.2,
473 5, 637 5,
474 0.3, 638 0.3,
475 2, 639 2,
476 {"uc": "mix", "analysis_window": 0.1}, 640 {"uc": "mix", "analysis_window": 0.1},
477 [(10, 32), (36, 76)], 641 [(10, 32), (36, 76)],
478 ), 642 ), # stereo_uc_mix_aw_0_1_max_silence_0_3
479 ( 643 (
480 0.3, 644 0.3,
481 5, 645 5,
482 0, 646 0,
483 2, 647 2,
484 {"uc": "avg", "analysis_window": 0.2}, 648 {"uc": "avg", "analysis_window": 0.2},
485 [(10, 14), (16, 24), (36, 76)], 649 [(10, 14), (16, 24), (36, 76)],
486 ), 650 ), # stereo_uc_avg_aw_0_2_max_silence_0_min_dur_0_3
487 ( 651 (
488 0.41, 652 0.41,
489 5, 653 5,
490 0, 654 0,
491 2, 655 2,
492 {"uc": "average", "analysis_window": 0.2}, 656 {"uc": "average", "analysis_window": 0.2},
493 [(16, 24), (36, 76)], 657 [(16, 24), (36, 76)],
494 ), 658 ), # stereo_uc_average_aw_0_2_max_silence_0_min_dur_0_41
495 ( 659 (
496 0.2, 660 0.2,
497 5, 661 5,
498 0.1, 662 0.1,
499 2, 663 2,
500 {"uc": "mix", "analysis_window": 0.2}, 664 {"uc": "mix", "analysis_window": 0.2},
501 [(10, 14), (16, 24), (26, 28), (36, 76)], 665 [(10, 14), (16, 24), (26, 28), (36, 76)],
502 ), 666 ), # stereo_uc_mix_aw_0_2_max_silence_0_1
503 ( 667 (
504 0.2, 668 0.2,
505 5, 669 5,
506 0.2, 670 0.2,
507 2, 671 2,
508 {"uc": "mix", "analysis_window": 0.2}, 672 {"uc": "mix", "analysis_window": 0.2},
509 [(10, 30), (36, 76)], 673 [(10, 30), (36, 76)],
510 ), 674 ), # stereo_uc_mix_aw_0_2_max_silence_0_2
511 ( 675 (
512 0.2, 676 0.2,
513 5, 677 5,
514 0.4, 678 0.4,
515 2, 679 2,
516 {"uc": "mix", "analysis_window": 0.2}, 680 {"uc": "mix", "analysis_window": 0.2},
517 [(10, 32), (36, 76)], 681 [(10, 32), (36, 76)],
518 ), 682 ), # stereo_uc_mix_aw_0_2_max_silence_0_4
519 ( 683 (
520 0.2, 684 0.2,
521 5, 685 5,
522 0.5, 686 0.5,
523 2, 687 2,
524 {"uc": "mix", "analysis_window": 0.2}, 688 {"uc": "mix", "analysis_window": 0.2},
525 [(10, 32), (36, 76)], 689 [(10, 32), (36, 76)],
526 ), 690 ), # stereo_uc_mix_aw_0_2_max_silence_0_5
527 ( 691 (
528 0.2, 692 0.2,
529 5, 693 5,
530 0.6, 694 0.6,
531 2, 695 2,
532 {"uc": "mix", "analysis_window": 0.2}, 696 {"uc": "mix", "analysis_window": 0.2},
533 [(10, 34), (36, 76)], 697 [(10, 34), (36, 76)],
534 ), 698 ), # stereo_uc_mix_aw_0_2_max_silence_0_6
535 ( 699 (
536 0.2, 700 0.2,
537 5, 701 5,
538 0, 702 0,
539 2, 703 2,
540 {"uc": "mix", "analysis_window": 0.3}, 704 {"uc": "mix", "analysis_window": 0.3},
541 [(9, 24), (27, 30), (36, 76)], 705 [(9, 24), (27, 30), (36, 76)],
542 ), 706 ), # stereo_uc_mix_aw_0_3_max_silence_0
543 ( 707 (
544 0.4, 708 0.4,
545 5, 709 5,
546 0, 710 0,
547 2, 711 2,
548 {"uc": "mix", "analysis_window": 0.3}, 712 {"uc": "mix", "analysis_window": 0.3},
549 [(9, 24), (36, 76)], 713 [(9, 24), (36, 76)],
550 ), 714 ), # stereo_uc_mix_aw_0_3_max_silence_0_min_dur_0_3
551 ( 715 (
552 0.2, 716 0.2,
553 5, 717 5,
554 0.6, 718 0.6,
555 2, 719 2,
556 {"uc": "mix", "analysis_window": 0.3}, 720 {"uc": "mix", "analysis_window": 0.3},
557 [(9, 57), (57, 76)], 721 [(9, 57), (57, 76)],
558 ), 722 ), # stereo_uc_mix_aw_0_3_max_silence_0_6
559 ( 723 (
560 0.2, 724 0.2,
561 5.1, 725 5.1,
562 0.6, 726 0.6,
563 2, 727 2,
564 {"uc": "mix", "analysis_window": 0.3}, 728 {"uc": "mix", "analysis_window": 0.3},
565 [(9, 60), (60, 76)], 729 [(9, 60), (60, 76)],
566 ), 730 ), # stereo_uc_mix_aw_0_3_max_silence_0_6_max_dur_5_1
567 ( 731 (
568 0.2, 732 0.2,
569 5.2, 733 5.2,
570 0.6, 734 0.6,
571 2, 735 2,
572 {"uc": "mix", "analysis_window": 0.3}, 736 {"uc": "mix", "analysis_window": 0.3},
573 [(9, 60), (60, 76)], 737 [(9, 60), (60, 76)],
574 ), 738 ), # stereo_uc_mix_aw_0_3_max_silence_0_6_max_dur_5_2
575 ( 739 (
576 0.2, 740 0.2,
577 5.3, 741 5.3,
578 0.6, 742 0.6,
579 2, 743 2,
580 {"uc": "mix", "analysis_window": 0.3}, 744 {"uc": "mix", "analysis_window": 0.3},
581 [(9, 60), (60, 76)], 745 [(9, 60), (60, 76)],
582 ), 746 ), # stereo_uc_mix_aw_0_3_max_silence_0_6_max_dur_5_3
583 ( 747 (
584 0.2, 748 0.2,
585 5.4, 749 5.4,
586 0.6, 750 0.6,
587 2, 751 2,
588 {"uc": "mix", "analysis_window": 0.3}, 752 {"uc": "mix", "analysis_window": 0.3},
589 [(9, 63), (63, 76)], 753 [(9, 63), (63, 76)],
590 ), 754 ), # stereo_uc_mix_aw_0_3_max_silence_0_6_max_dur_5_4
591 ( 755 (
592 0.2, 756 0.2,
593 5, 757 5,
594 0, 758 0,
595 2, 759 2,
596 {"uc": "mix", "analysis_window": 0.4}, 760 {"uc": "mix", "analysis_window": 0.4},
597 [(16, 24), (36, 76)], 761 [(16, 24), (36, 76)],
598 ), 762 ), # stereo_uc_mix_aw_0_4_max_silence_0
599 ( 763 (
600 0.2, 764 0.2,
601 5, 765 5,
602 0.3, 766 0.3,
603 2, 767 2,
604 {"uc": "mix", "analysis_window": 0.4}, 768 {"uc": "mix", "analysis_window": 0.4},
605 [(16, 24), (36, 76)], 769 [(16, 24), (36, 76)],
606 ), 770 ), # stereo_uc_mix_aw_0_4_max_silence_0_3
607 ( 771 (
608 0.2, 772 0.2,
609 5, 773 5,
610 0.4, 774 0.4,
611 2, 775 2,
612 {"uc": "mix", "analysis_window": 0.4}, 776 {"uc": "mix", "analysis_window": 0.4},
613 [(16, 28), (36, 76)], 777 [(16, 28), (36, 76)],
614 ), 778 ), # stereo_uc_mix_aw_0_4_max_silence_0_4
615 ], 779 ],
616 ids=[ 780 ids=[
617 "mono_aw_0_2_max_silence_0_2", 781 "mono_aw_0_2_max_silence_0_2",
618 "mono_aw_0_2_max_silence_0_3", 782 "mono_aw_0_2_max_silence_0_3",
619 "mono_aw_0_2_max_silence_0_4", 783 "mono_aw_0_2_max_silence_0_4",
700 err_msg += "{}, found: {}".format(len(expected), len(regions_ar)) 864 err_msg += "{}, found: {}".format(len(expected), len(regions_ar))
701 assert len(regions_ar) == len(expected), err_msg 865 assert len(regions_ar) == len(expected), err_msg
702 866
703 sample_width = 2 867 sample_width = 2
704 sample_size_bytes = sample_width * channels 868 sample_size_bytes = sample_width * channels
705 for reg, reg_ar, exp in zip(regions, regions_ar, expected): 869 for reg, reg_ar, exp in zip(regions, regions_ar, expected, strict=True):
706 onset, offset = exp 870 onset, offset = exp
707 exp_data = data[onset * sample_size_bytes : offset * sample_size_bytes] 871 exp_data = data[onset * sample_size_bytes : offset * sample_size_bytes]
708 assert bytes(reg) == exp_data 872 assert bytes(reg) == exp_data
709 assert reg == reg_ar 873 assert reg == reg_ar
710 874
723 strict_min_dur=False, 887 strict_min_dur=False,
724 sr=10, 888 sr=10,
725 sw=2, 889 sw=2,
726 ch=1, 890 ch=1,
727 analysis_window=0.1, 891 analysis_window=0.1,
728 validator=lambda x: array_("h", x)[0] >= 320, 892 validator=lambda x: to_array(x, sample_width=2, channels=1)[0] >= 320,
729 ) 893 )
730 894
731 region = AudioRegion(data, 10, 2, 1) 895 region = AudioRegion(data, 10, 2, 1)
732 regions_ar = region.split( 896 regions_ar = region.split(
733 min_dur=0.2, 897 min_dur=0.2,
734 max_dur=5, 898 max_dur=5,
735 max_silence=0.2, 899 max_silence=0.2,
736 drop_trailing_silence=False, 900 drop_trailing_silence=False,
737 strict_min_dur=False, 901 strict_min_dur=False,
738 analysis_window=0.1, 902 analysis_window=0.1,
739 validator=lambda x: array_("h", x)[0] >= 320, 903 validator=lambda x: to_array(x, sample_width=2, channels=1)[0] >= 320,
740 ) 904 )
741 905
742 expected = [(2, 16), (17, 31), (34, 76)] 906 expected = [(2, 16), (17, 31), (34, 76)]
743 regions = list(regions) 907 regions = list(regions)
744 regions_ar = list(regions_ar) 908 regions_ar = list(regions_ar)
748 err_msg = "Wrong number of regions after AudioRegion.split, expected: " 912 err_msg = "Wrong number of regions after AudioRegion.split, expected: "
749 err_msg += "{}, found: {}".format(len(expected), len(regions_ar)) 913 err_msg += "{}, found: {}".format(len(expected), len(regions_ar))
750 assert len(regions_ar) == len(expected), err_msg 914 assert len(regions_ar) == len(expected), err_msg
751 915
752 sample_size_bytes = 2 916 sample_size_bytes = 2
753 for reg, reg_ar, exp in zip(regions, regions_ar, expected): 917 for reg, reg_ar, exp in zip(regions, regions_ar, expected, strict=True):
754 onset, offset = exp 918 onset, offset = exp
755 exp_data = data[onset * sample_size_bytes : offset * sample_size_bytes] 919 exp_data = data[onset * sample_size_bytes : offset * sample_size_bytes]
756 assert bytes(reg) == exp_data 920 assert bytes(reg) == exp_data
757 assert reg == reg_ar 921 assert reg == reg_ar
758 922
761 "input, kwargs", 925 "input, kwargs",
762 [ 926 [
763 ( 927 (
764 "tests/data/test_split_10HZ_stereo.raw", 928 "tests/data/test_split_10HZ_stereo.raw",
765 {"audio_format": "raw", "sr": 10, "sw": 2, "ch": 2}, 929 {"audio_format": "raw", "sr": 10, "sw": 2, "ch": 2},
766 ), 930 ), # filename_audio_format
767 ( 931 (
768 "tests/data/test_split_10HZ_stereo.raw", 932 "tests/data/test_split_10HZ_stereo.raw",
769 {"fmt": "raw", "sr": 10, "sw": 2, "ch": 2}, 933 {"fmt": "raw", "sr": 10, "sw": 2, "ch": 2},
770 ), 934 ), # filename_audio_format_short_name
771 ("tests/data/test_split_10HZ_stereo.raw", {"sr": 10, "sw": 2, "ch": 2}), 935 (
936 "tests/data/test_split_10HZ_stereo.raw",
937 {"sr": 10, "sw": 2, "ch": 2},
938 ), # filename_no_audio_format
772 ( 939 (
773 "tests/data/test_split_10HZ_stereo.raw", 940 "tests/data/test_split_10HZ_stereo.raw",
774 {"sampling_rate": 10, "sample_width": 2, "channels": 2}, 941 {"sampling_rate": 10, "sample_width": 2, "channels": 2},
775 ), 942 ), # filename_no_long_audio_params
776 ( 943 (
777 open("tests/data/test_split_10HZ_stereo.raw", "rb").read(), 944 open("tests/data/test_split_10HZ_stereo.raw", "rb").read(),
778 {"sr": 10, "sw": 2, "ch": 2}, 945 {"sr": 10, "sw": 2, "ch": 2},
779 ), 946 ), # bytes_
780 ( 947 (
781 AudioReader( 948 AudioReader(
782 "tests/data/test_split_10HZ_stereo.raw", 949 "tests/data/test_split_10HZ_stereo.raw",
783 sr=10, 950 sr=10,
784 sw=2, 951 sw=2,
785 ch=2, 952 ch=2,
786 block_dur=0.1, 953 block_dur=0.1,
787 ), 954 ),
788 {}, 955 {},
789 ), 956 ), # audio_reader
790 ( 957 (
791 AudioRegion( 958 AudioRegion(
792 open("tests/data/test_split_10HZ_stereo.raw", "rb").read(), 959 open("tests/data/test_split_10HZ_stereo.raw", "rb").read(),
793 10, 960 10,
794 2, 961 2,
795 2, 962 2,
796 ), 963 ),
797 {}, 964 {},
798 ), 965 ), # audio_region
799 ( 966 (
800 get_audio_source( 967 get_audio_source(
801 "tests/data/test_split_10HZ_stereo.raw", sr=10, sw=2, ch=2 968 "tests/data/test_split_10HZ_stereo.raw", sr=10, sw=2, ch=2
802 ), 969 ),
803 {}, 970 {},
804 ), 971 ), # audio_source
805 ], 972 ],
806 ids=[ 973 ids=[
807 "filename_audio_format", 974 "filename_audio_format",
808 "filename_audio_format_short_name", 975 "filename_audio_format_short_name",
809 "filename_no_audio_format", 976 "filename_no_audio_format",
833 expected = [(2, 32), (34, 76)] 1000 expected = [(2, 32), (34, 76)]
834 sample_width = 2 1001 sample_width = 2
835 err_msg = "Wrong number of regions after split, expected: " 1002 err_msg = "Wrong number of regions after split, expected: "
836 err_msg += "{}, found: {}".format(expected, regions) 1003 err_msg += "{}, found: {}".format(expected, regions)
837 assert len(regions) == len(expected), err_msg 1004 assert len(regions) == len(expected), err_msg
838 for reg, exp in zip(regions, expected): 1005 for reg, exp in zip(regions, expected, strict=True):
839 onset, offset = exp 1006 onset, offset = exp
840 exp_data = data[onset * sample_width * 2 : offset * sample_width * 2] 1007 exp_data = data[onset * sample_width * 2 : offset * sample_width * 2]
841 assert bytes(reg) == exp_data 1008 assert bytes(reg) == exp_data
842 1009
843 1010
882 1049
883 1050
884 @pytest.mark.parametrize( 1051 @pytest.mark.parametrize(
885 "max_silence, max_dur, analysis_window", 1052 "max_silence, max_dur, analysis_window",
886 [ 1053 [
887 (0.5, 0.5, 0.1), 1054 (0.5, 0.5, 0.1), # max_silence_equals_max_dur
888 (0.5, 0.4, 0.1), 1055 (0.5, 0.4, 0.1), # max_silence_greater_than_max_dur
889 (0.44, 0.49, 0.1), 1056 (0.44, 0.49, 0.1), # durations_OK_but_wrong_number_of_analysis_windows
890 ], 1057 ],
891 ids=[ 1058 ids=[
892 "max_silence_equals_max_dur", 1059 "max_silence_equals_max_dur",
893 "max_silence_greater_than_max_dur", 1060 "max_silence_greater_than_max_dur",
894 "durations_OK_but_wrong_number_of_analysis_windows", 1061 "durations_OK_but_wrong_number_of_analysis_windows",
924 1091
925 1092
926 @pytest.mark.parametrize( 1093 @pytest.mark.parametrize(
927 "wrong_param", 1094 "wrong_param",
928 [ 1095 [
929 {"min_dur": -1}, 1096 {"min_dur": -1}, # negative_min_dur
930 {"min_dur": 0}, 1097 {"min_dur": 0}, # zero_min_dur
931 {"max_dur": -1}, 1098 {"max_dur": -1}, # negative_max_dur
932 {"max_dur": 0}, 1099 {"max_dur": 0}, # zero_max_dur
933 {"max_silence": -1}, 1100 {"max_silence": -1}, # negative_max_silence
934 {"analysis_window": 0}, 1101 {"analysis_window": 0}, # zero_analysis_window
935 {"analysis_window": -1}, 1102 {"analysis_window": -1}, # negative_analysis_window
936 ], 1103 ],
937 ids=[ 1104 ids=[
938 "negative_min_dur", 1105 "negative_min_dur",
939 "zero_min_dur", 1106 "zero_min_dur",
940 "negative_max_dur", 1107 "negative_max_dur",
977 1144
978 with open("tests/data/test_split_10HZ_mono.raw", "rb") as fp: 1145 with open("tests/data/test_split_10HZ_mono.raw", "rb") as fp:
979 data = fp.read() 1146 data = fp.read()
980 1147
981 region = AudioRegion(data, 10, 2, 1) 1148 region = AudioRegion(data, 10, 2, 1)
982 with patch("auditok.plotting.plot") as patch_fn: 1149 with patch("auditok.core.plot") as patch_fn:
983 regions = region.split_and_plot( 1150 regions = region.split_and_plot(
984 min_dur=0.2, 1151 min_dur=0.2,
985 max_dur=5, 1152 max_dur=5,
986 max_silence=0.2, 1153 max_silence=0.2,
987 drop_trailing_silence=False, 1154 drop_trailing_silence=False,
1012 # max_read is not accepted when calling AudioRegion.split 1179 # max_read is not accepted when calling AudioRegion.split
1013 region.split(max_read=2) 1180 region.split(max_read=2)
1014 1181
1015 1182
1016 @pytest.mark.parametrize( 1183 @pytest.mark.parametrize(
1017 "data, start, sampling_rate, sample_width, channels, expected_end, expected_duration_s, expected_duration_ms", 1184 (
1018 [ 1185 "data, start, sampling_rate, sample_width, channels, expected_end, "
1019 (b"\0" * 8000, 0, 8000, 1, 1, 1, 1, 1000), 1186 + "expected_duration_s, expected_duration_ms"
1020 (b"\0" * 7992, 0, 8000, 1, 1, 0.999, 0.999, 999), 1187 ),
1021 (b"\0" * 7994, 0, 8000, 1, 1, 0.99925, 0.99925, 999), 1188 [
1022 (b"\0" * 7996, 0, 8000, 1, 1, 0.9995, 0.9995, 1000), 1189 (b"\0" * 8000, 0, 8000, 1, 1, 1, 1, 1000), # simple
1023 (b"\0" * 7998, 0, 8000, 1, 1, 0.99975, 0.99975, 1000), 1190 (
1024 (b"\0" * 8000 * 2, 0, 8000, 2, 1, 1, 1, 1000), 1191 b"\0" * 7992,
1025 (b"\0" * 8000 * 2, 0, 8000, 1, 2, 1, 1, 1000), 1192 0,
1026 (b"\0" * 8000 * 5, 0, 8000, 1, 5, 1, 1, 1000), 1193 8000,
1027 (b"\0" * 8000 * 2 * 5, 0, 8000, 2, 5, 1, 1, 1000), 1194 1,
1028 (b"\0" * 7992 * 2 * 5, 0, 8000, 2, 5, 0.999, 0.999, 999), 1195 1,
1029 (b"\0" * 7994 * 2 * 5, 0, 8000, 2, 5, 0.99925, 0.99925, 999), 1196 0.999,
1030 (b"\0" * 7996 * 2 * 5, 0, 8000, 2, 5, 0.9995, 0.9995, 1000), 1197 0.999,
1031 (b"\0" * 7998 * 2 * 5, 0, 8000, 2, 5, 0.99975, 0.99975, 1000), 1198 999,
1032 (b"\0" * int(8000 * 1.33), 2.7, 8000, 1, 1, 4.03, 1.33, 1330), 1199 ), # one_ms_less_than_1_sec
1033 (b"\0" * int(8000 * 0.476), 11.568, 8000, 1, 1, 12.044, 0.476, 476), 1200 (
1201 b"\0" * 7994,
1202 0,
1203 8000,
1204 1,
1205 1,
1206 0.99925,
1207 0.99925,
1208 999,
1209 ), # tree_quarter_ms_less_than_1_sec
1210 (
1211 b"\0" * 7996,
1212 0,
1213 8000,
1214 1,
1215 1,
1216 0.9995,
1217 0.9995,
1218 1000,
1219 ), # half_ms_less_than_1_sec
1220 (
1221 b"\0" * 7998,
1222 0,
1223 8000,
1224 1,
1225 1,
1226 0.99975,
1227 0.99975,
1228 1000,
1229 ), # quarter_ms_less_than_1_sec
1230 (b"\0" * 8000 * 2, 0, 8000, 2, 1, 1, 1, 1000), # simple_sample_width_2
1231 (b"\0" * 8000 * 2, 0, 8000, 1, 2, 1, 1, 1000), # simple_stereo
1232 (b"\0" * 8000 * 5, 0, 8000, 1, 5, 1, 1, 1000), # simple_multichannel
1233 (
1234 b"\0" * 8000 * 2 * 5,
1235 0,
1236 8000,
1237 2,
1238 5,
1239 1,
1240 1,
1241 1000,
1242 ), # simple_sample_width_2_multichannel
1243 (
1244 b"\0" * 7992 * 2 * 5,
1245 0,
1246 8000,
1247 2,
1248 5,
1249 0.999,
1250 0.999,
1251 999,
1252 ), # one_ms_less_than_1s_sw_2_multichannel
1253 (
1254 b"\0" * 7994 * 2 * 5,
1255 0,
1256 8000,
1257 2,
1258 5,
1259 0.99925,
1260 0.99925,
1261 999,
1262 ), # tree_qrt_ms_lt_1_s_sw_2_multichannel
1263 (
1264 b"\0" * 7996 * 2 * 5,
1265 0,
1266 8000,
1267 2,
1268 5,
1269 0.9995,
1270 0.9995,
1271 1000,
1272 ), # half_ms_lt_1s_sw_2_multichannel
1273 (
1274 b"\0" * 7998 * 2 * 5,
1275 0,
1276 8000,
1277 2,
1278 5,
1279 0.99975,
1280 0.99975,
1281 1000,
1282 ), # quarter_ms_lt_1s_sw_2_multichannel
1283 (
1284 b"\0" * int(8000 * 1.33),
1285 2.7,
1286 8000,
1287 1,
1288 1,
1289 4.03,
1290 1.33,
1291 1330,
1292 ), # arbitrary_length_1
1293 (
1294 b"\0" * int(8000 * 0.476),
1295 11.568,
1296 8000,
1297 1,
1298 1,
1299 12.044,
1300 0.476,
1301 476,
1302 ), # arbitrary_length_2
1034 ( 1303 (
1035 b"\0" * int(8000 * 1.711) * 2 * 3, 1304 b"\0" * int(8000 * 1.711) * 2 * 3,
1036 9.415, 1305 9.415,
1037 8000, 1306 8000,
1038 2, 1307 2,
1039 3, 1308 3,
1040 11.126, 1309 11.126,
1041 1.711, 1310 1.711,
1042 1711, 1311 1711,
1043 ), 1312 ), # arbitrary_length_sw_2_multichannel
1044 ( 1313 (
1045 b"\0" * int(3172 * 1.318), 1314 b"\0" * int(3172 * 1.318),
1046 17.236, 1315 17.236,
1047 3172, 1316 3172,
1048 1, 1317 1,
1049 1, 1318 1,
1050 17.236 + int(3172 * 1.318) / 3172, 1319 17.236 + int(3172 * 1.318) / 3172,
1051 int(3172 * 1.318) / 3172, 1320 int(3172 * 1.318) / 3172,
1052 1318, 1321 1318,
1053 ), 1322 ), # arbitrary_sampling_rate
1054 ( 1323 (
1055 b"\0" * int(11317 * 0.716) * 2 * 3, 1324 b"\0" * int(11317 * 0.716) * 2 * 3,
1056 18.811, 1325 18.811,
1057 11317, 1326 11317,
1058 2, 1327 2,
1059 3, 1328 3,
1060 18.811 + int(11317 * 0.716) / 11317, 1329 18.811 + int(11317 * 0.716) / 11317,
1061 int(11317 * 0.716) / 11317, 1330 int(11317 * 0.716) / 11317,
1062 716, 1331 716,
1063 ), 1332 ), # arbitrary_sr_sw_2_multichannel
1064 ], 1333 ],
1065 ids=[ 1334 ids=[
1066 "simple", 1335 "simple",
1067 "one_ms_less_than_1_sec", 1336 "one_ms_less_than_1_sec",
1068 "tree_quarter_ms_less_than_1_sec", 1337 "tree_quarter_ms_less_than_1_sec",
1077 "half_ms_lt_1s_sw_2_multichannel", 1346 "half_ms_lt_1s_sw_2_multichannel",
1078 "quarter_ms_lt_1s_sw_2_multichannel", 1347 "quarter_ms_lt_1s_sw_2_multichannel",
1079 "arbitrary_length_1", 1348 "arbitrary_length_1",
1080 "arbitrary_length_2", 1349 "arbitrary_length_2",
1081 "arbitrary_length_sw_2_multichannel", 1350 "arbitrary_length_sw_2_multichannel",
1082 "arbitrary_samplig_rate", 1351 "arbitrary_sampling_rate",
1083 "arbitrary_sr_sw_2_multichannel", 1352 "arbitrary_sr_sw_2_multichannel",
1084 ], 1353 ],
1085 ) 1354 )
1086 def test_creation( 1355 def test_creation(
1087 data, 1356 data,
1120 1389
1121 1390
1122 @pytest.mark.parametrize( 1391 @pytest.mark.parametrize(
1123 "skip, max_read, channels", 1392 "skip, max_read, channels",
1124 [ 1393 [
1125 (0, -1, 1), 1394 (0, -1, 1), # no_skip_read_all
1126 (0, -1, 2), 1395 (0, -1, 2), # no_skip_read_all_stereo
1127 (2, -1, 1), 1396 (2, -1, 1), # skip_2_read_all
1128 (2, None, 1), 1397 (2, None, 1), # skip_2_read_all_None
1129 (2, 3, 1), 1398 (2, 3, 1), # skip_2_read_3
1130 (2, 3.5, 2), 1399 (2, 3.5, 2), # skip_2_read_3_5_stereo
1131 (2.4, 3.5, 2), 1400 (2.4, 3.5, 2), # skip_2_4_read_3_5_stereo
1132 ], 1401 ],
1133 ids=[ 1402 ids=[
1134 "no_skip_read_all", 1403 "no_skip_read_all",
1135 "no_skip_read_all_stereo", 1404 "no_skip_read_all_stereo",
1136 "skip_2_read_all", 1405 "skip_2_read_all",
1178 1447
1179 1448
1180 @pytest.mark.parametrize( 1449 @pytest.mark.parametrize(
1181 "max_read", 1450 "max_read",
1182 [ 1451 [
1183 None, 1452 None, # None
1184 -1, 1453 -1, # negative
1185 ], 1454 ],
1186 ids=[ 1455 ids=[
1187 "none", 1456 "None",
1188 "negative", 1457 "negative",
1189 ], 1458 ],
1190 ) 1459 )
1191 def test_load_from_microphone_without_max_read_exception(max_read): 1460 def test_load_from_microphone_without_max_read_exception(max_read):
1192 with pytest.raises(ValueError) as val_err: 1461 with pytest.raises(ValueError) as val_err:
1205 1474
1206 1475
1207 @pytest.mark.parametrize( 1476 @pytest.mark.parametrize(
1208 "format, start, expected", 1477 "format, start, expected",
1209 [ 1478 [
1210 ("output.wav", 1.230, "output.wav"), 1479 ("output.wav", 1.230, "output.wav"), # simple
1211 ("output_{meta.start:g}.wav", 1.230, "output_1.23.wav"), 1480 ("output_{meta.start:g}.wav", 1.230, "output_1.23.wav"), # start
1212 ("output_{meta.start}.wav", 1.233712, "output_1.233712.wav"), 1481 ("output_{meta.start}.wav", 1.233712, "output_1.233712.wav"), # start_2
1213 ("output_{meta.start:.2f}.wav", 1.2300001, "output_1.23.wav"), 1482 (
1214 ("output_{meta.start:.3f}.wav", 1.233712, "output_1.234.wav"), 1483 "output_{meta.start:.2f}.wav",
1215 ("output_{meta.start:.8f}.wav", 1.233712, "output_1.23371200.wav"), 1484 1.2300001,
1485 "output_1.23.wav",
1486 ), # start_3
1487 (
1488 "output_{meta.start:.3f}.wav",
1489 1.233712,
1490 "output_1.234.wav",
1491 ), # start_4
1492 (
1493 "output_{meta.start:.8f}.wav",
1494 1.233712,
1495 "output_1.23371200.wav",
1496 ), # start_5
1216 ( 1497 (
1217 "output_{meta.start}_{meta.end}_{duration}.wav", 1498 "output_{meta.start}_{meta.end}_{duration}.wav",
1218 1.455, 1499 1.455,
1219 "output_1.455_2.455_1.0.wav", 1500 "output_1.455_2.455_1.0.wav",
1220 ), 1501 ), # start_end_duration
1221 ( 1502 (
1222 "output_{meta.start}_{meta.end}_{duration}.wav", 1503 "output_{meta.start}_{meta.end}_{duration}.wav",
1223 1.455321, 1504 1.455321,
1224 "output_1.455321_2.455321_1.0.wav", 1505 "output_1.455321_2.455321_1.0.wav",
1225 ), 1506 ), # start_end_duration_2
1226 ], 1507 ],
1227 ids=[ 1508 ids=[
1228 "simple", 1509 "simple",
1229 "start", 1510 "start",
1230 "start_2", 1511 "start_2",
1258 "region, slice_, expected_data", 1539 "region, slice_, expected_data",
1259 [ 1540 [
1260 ( 1541 (
1261 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1), 1542 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1),
1262 slice(0, 500), 1543 slice(0, 500),
1263 b"a" * 80, 1544 b"a" * 80, # first_half
1264 ), 1545 ),
1265 ( 1546 (
1266 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1), 1547 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1),
1267 slice(500, None), 1548 slice(500, None),
1268 b"b" * 80, 1549 b"b" * 80, # second_half
1269 ), 1550 ),
1270 ( 1551 (
1271 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1), 1552 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1),
1272 slice(-500, None), 1553 slice(-500, None),
1273 b"b" * 80, 1554 b"b" * 80, # second_half_negative
1274 ), 1555 ),
1275 ( 1556 (
1276 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1), 1557 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1),
1277 slice(200, 750), 1558 slice(200, 750),
1278 b"a" * 48 + b"b" * 40, 1559 b"a" * 48 + b"b" * 40, # middle
1279 ), 1560 ),
1280 ( 1561 (
1281 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1), 1562 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1),
1282 slice(-800, -250), 1563 slice(-800, -250),
1283 b"a" * 48 + b"b" * 40, 1564 b"a" * 48 + b"b" * 40, # middle_negative
1284 ), 1565 ),
1285 ( 1566 (
1286 AudioRegion(b"a" * 160 + b"b" * 160, 160, 2, 1), 1567 AudioRegion(b"a" * 160 + b"b" * 160, 160, 2, 1),
1287 slice(200, 750), 1568 slice(200, 750),
1288 b"a" * 96 + b"b" * 80, 1569 b"a" * 96 + b"b" * 80, # middle_sw2
1289 ), 1570 ),
1290 ( 1571 (
1291 AudioRegion(b"a" * 160 + b"b" * 160, 160, 1, 2), 1572 AudioRegion(b"a" * 160 + b"b" * 160, 160, 1, 2),
1292 slice(200, 750), 1573 slice(200, 750),
1293 b"a" * 96 + b"b" * 80, 1574 b"a" * 96 + b"b" * 80, # middle_ch2
1294 ), 1575 ),
1295 ( 1576 (
1296 AudioRegion(b"a" * 320 + b"b" * 320, 160, 2, 2), 1577 AudioRegion(b"a" * 320 + b"b" * 320, 160, 2, 2),
1297 slice(200, 750), 1578 slice(200, 750),
1298 b"a" * 192 + b"b" * 160, 1579 b"a" * 192 + b"b" * 160, # middle_sw2_ch2
1299 ), 1580 ),
1300 ( 1581 (
1301 AudioRegion(b"a" * 4000 + b"b" * 4000, 8000, 1, 1), 1582 AudioRegion(b"a" * 4000 + b"b" * 4000, 8000, 1, 1),
1302 slice(1, None), 1583 slice(1, None),
1303 b"a" * (4000 - 8) + b"b" * 4000, 1584 b"a" * (4000 - 8) + b"b" * 4000, # but_first_sample
1304 ), 1585 ),
1305 ( 1586 (
1306 AudioRegion(b"a" * 4000 + b"b" * 4000, 8000, 1, 1), 1587 AudioRegion(b"a" * 4000 + b"b" * 4000, 8000, 1, 1),
1307 slice(-999, None), 1588 slice(-999, None),
1308 b"a" * (4000 - 8) + b"b" * 4000, 1589 b"a" * (4000 - 8) + b"b" * 4000, # but_first_sample_negative
1309 ), 1590 ),
1310 ( 1591 (
1311 AudioRegion(b"a" * 4000 + b"b" * 4000, 8000, 1, 1), 1592 AudioRegion(b"a" * 4000 + b"b" * 4000, 8000, 1, 1),
1312 slice(0, 999), 1593 slice(0, 999),
1313 b"a" * 4000 + b"b" * (4000 - 8), 1594 b"a" * 4000 + b"b" * (4000 - 8), # but_last_sample
1314 ), 1595 ),
1315 ( 1596 (
1316 AudioRegion(b"a" * 4000 + b"b" * 4000, 8000, 1, 1), 1597 AudioRegion(b"a" * 4000 + b"b" * 4000, 8000, 1, 1),
1317 slice(0, -1), 1598 slice(0, -1),
1318 b"a" * 4000 + b"b" * (4000 - 8), 1599 b"a" * 4000 + b"b" * (4000 - 8), # but_last_sample_negative
1319 ), 1600 ),
1320 (AudioRegion(b"a" * 160, 160, 1, 1), slice(-5000, None), b"a" * 160), 1601 (
1321 (AudioRegion(b"a" * 160, 160, 1, 1), slice(None, -1500), b""), 1602 AudioRegion(b"a" * 160, 160, 1, 1),
1322 (AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1), slice(0, 0), b""), 1603 slice(-5000, None),
1323 (AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1), slice(200, 100), b""), 1604 b"a" * 160, # big_negative_start
1324 (AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1), slice(2000, 3000), b""), 1605 ),
1325 (AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1), slice(-100, -200), b""), 1606 (
1326 (AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1), slice(0, -2000), b""), 1607 AudioRegion(b"a" * 160, 160, 1, 1),
1608 slice(None, -1500),
1609 b"", # big_negative_stop
1610 ),
1611 (
1612 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1),
1613 slice(0, 0),
1614 b"", # empty
1615 ),
1616 (
1617 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1),
1618 slice(200, 100),
1619 b"", # empty_start_stop_reversed
1620 ),
1621 (
1622 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1),
1623 slice(2000, 3000),
1624 b"", # empty_big_positive_start
1625 ),
1626 (
1627 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1),
1628 slice(-100, -200),
1629 b"", # empty_negative_reversed
1630 ),
1631 (
1632 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1),
1633 slice(0, -2000),
1634 b"", # empty_big_negative_stop
1635 ),
1327 ( 1636 (
1328 AudioRegion(b"a" * 124 + b"b" * 376, 1234, 1, 1), 1637 AudioRegion(b"a" * 124 + b"b" * 376, 1234, 1, 1),
1329 slice(100, 200), 1638 slice(100, 200),
1330 b"a" + b"b" * 123, 1639 b"a" + b"b" * 123, # arbitrary_sampling_rate
1331 ), 1640 ),
1332 ], 1641 ],
1333 ids=[ 1642 ids=[
1334 "first_half", 1643 "first_half",
1335 "second_half", 1644 "second_half",
1367 [ 1676 [
1368 ( 1677 (
1369 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1), 1678 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1),
1370 slice(0, 80), 1679 slice(0, 80),
1371 0, 1680 0,
1372 b"a" * 80, 1681 b"a" * 80, # first_half
1373 ), 1682 ),
1374 ( 1683 (
1375 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1), 1684 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1),
1376 slice(80, None), 1685 slice(80, None),
1377 0.5, 1686 0.5,
1378 b"b" * 80, 1687 b"b" * 80, # second_half
1379 ), 1688 ),
1380 ( 1689 (
1381 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1), 1690 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1),
1382 slice(-80, None), 1691 slice(-80, None),
1383 0.5, 1692 0.5,
1384 b"b" * 80, 1693 b"b" * 80, # second_half_negative
1385 ), 1694 ),
1386 ( 1695 (
1387 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1), 1696 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1),
1388 slice(160 // 5, 160 // 4 * 3), 1697 slice(160 // 5, 160 // 4 * 3),
1389 0.2, 1698 0.2,
1390 b"a" * 48 + b"b" * 40, 1699 b"a" * 48 + b"b" * 40, # middle
1391 ), 1700 ),
1392 ( 1701 (
1393 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1), 1702 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1),
1394 slice(-160 // 5 * 4, -160 // 4), 1703 slice(-160 // 5 * 4, -160 // 4),
1395 0.2, 1704 0.2,
1396 b"a" * 48 + b"b" * 40, 1705 b"a" * 48 + b"b" * 40, # middle_negative
1397 ), 1706 ),
1398 ( 1707 (
1399 AudioRegion(b"a" * 160 + b"b" * 160, 160, 2, 1), 1708 AudioRegion(b"a" * 160 + b"b" * 160, 160, 2, 1),
1400 slice(160 // 5, 160 // 4 * 3), 1709 slice(160 // 5, 160 // 4 * 3),
1401 0.2, 1710 0.2,
1402 b"a" * 96 + b"b" * 80, 1711 b"a" * 96 + b"b" * 80, # middle_sw2
1403 ), 1712 ),
1404 ( 1713 (
1405 AudioRegion(b"a" * 160 + b"b" * 160, 160, 1, 2), 1714 AudioRegion(b"a" * 160 + b"b" * 160, 160, 1, 2),
1406 slice(160 // 5, 160 // 4 * 3), 1715 slice(160 // 5, 160 // 4 * 3),
1407 0.2, 1716 0.2,
1408 b"a" * 96 + b"b" * 80, 1717 b"a" * 96 + b"b" * 80, # middle_ch2
1409 ), 1718 ),
1410 ( 1719 (
1411 AudioRegion(b"a" * 320 + b"b" * 320, 160, 2, 2), 1720 AudioRegion(b"a" * 320 + b"b" * 320, 160, 2, 2),
1412 slice(160 // 5, 160 // 4 * 3), 1721 slice(160 // 5, 160 // 4 * 3),
1413 0.2, 1722 0.2,
1414 b"a" * 192 + b"b" * 160, 1723 b"a" * 192 + b"b" * 160, # middle_sw2_ch2
1415 ), 1724 ),
1416 ( 1725 (
1417 AudioRegion(b"a" * 4000 + b"b" * 4000, 8000, 1, 1), 1726 AudioRegion(b"a" * 4000 + b"b" * 4000, 8000, 1, 1),
1418 slice(1, None), 1727 slice(1, None),
1419 1 / 8000, 1728 1 / 8000,
1420 b"a" * (4000 - 1) + b"b" * 4000, 1729 b"a" * (4000 - 1) + b"b" * 4000, # but_first_sample
1421 ), 1730 ),
1422 ( 1731 (
1423 AudioRegion(b"a" * 4000 + b"b" * 4000, 8000, 1, 1), 1732 AudioRegion(b"a" * 4000 + b"b" * 4000, 8000, 1, 1),
1424 slice(-7999, None), 1733 slice(-7999, None),
1425 1 / 8000, 1734 1 / 8000,
1426 b"a" * (4000 - 1) + b"b" * 4000, 1735 b"a" * (4000 - 1) + b"b" * 4000, # but_first_sample_negative
1427 ), 1736 ),
1428 ( 1737 (
1429 AudioRegion(b"a" * 4000 + b"b" * 4000, 8000, 1, 1), 1738 AudioRegion(b"a" * 4000 + b"b" * 4000, 8000, 1, 1),
1430 slice(0, 7999), 1739 slice(0, 7999),
1431 0, 1740 0,
1432 b"a" * 4000 + b"b" * (4000 - 1), 1741 b"a" * 4000 + b"b" * (4000 - 1), # but_last_sample
1433 ), 1742 ),
1434 ( 1743 (
1435 AudioRegion(b"a" * 4000 + b"b" * 4000, 8000, 1, 1), 1744 AudioRegion(b"a" * 4000 + b"b" * 4000, 8000, 1, 1),
1436 slice(0, -1), 1745 slice(0, -1),
1437 0, 1746 0,
1438 b"a" * 4000 + b"b" * (4000 - 1), 1747 b"a" * 4000 + b"b" * (4000 - 1), # but_last_sample_negative
1439 ), 1748 ),
1440 (AudioRegion(b"a" * 160, 160, 1, 1), slice(-1600, None), 0, b"a" * 160), 1749 (
1441 (AudioRegion(b"a" * 160, 160, 1, 1), slice(None, -1600), 0, b""), 1750 AudioRegion(b"a" * 160, 160, 1, 1),
1442 (AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1), slice(0, 0), 0, b""), 1751 slice(-1600, None),
1752 0,
1753 b"a" * 160, # big_negative_start
1754 ),
1755 (
1756 AudioRegion(b"a" * 160, 160, 1, 1),
1757 slice(None, -1600),
1758 0,
1759 b"", # big_negative_stop
1760 ),
1761 (
1762 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1),
1763 slice(0, 0),
1764 0,
1765 b"", # empty
1766 ),
1443 ( 1767 (
1444 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1), 1768 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1),
1445 slice(80, 40), 1769 slice(80, 40),
1446 0.5, 1770 0.5,
1447 b"", 1771 b"", # empty_start_stop_reversed
1448 ), 1772 ),
1449 ( 1773 (
1450 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1), 1774 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1),
1451 slice(1600, 3000), 1775 slice(1600, 3000),
1452 10, 1776 10,
1453 b"", 1777 b"", # empty_big_positive_start
1454 ), 1778 ),
1455 ( 1779 (
1456 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1), 1780 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1),
1457 slice(-16, -32), 1781 slice(-16, -32),
1458 0.9, 1782 0.9,
1459 b"", 1783 b"", # empty_negative_reversed
1460 ), 1784 ),
1461 ( 1785 (
1462 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1), 1786 AudioRegion(b"a" * 80 + b"b" * 80, 160, 1, 1),
1463 slice(0, -2000), 1787 slice(0, -2000),
1464 0, 1788 0,
1465 b"", 1789 b"", # empty_big_negative_stop
1466 ), 1790 ),
1467 ( 1791 (
1468 AudioRegion(b"a" * 124 + b"b" * 376, 1235, 1, 1), 1792 AudioRegion(b"a" * 124 + b"b" * 376, 1235, 1, 1),
1469 slice(100, 200), 1793 slice(100, 200),
1470 100 / 1235, 1794 100 / 1235,
1471 b"a" * 24 + b"b" * 76, 1795 b"a" * 24 + b"b" * 76, # arbitrary_sampling_rate
1472 ), 1796 ),
1473 ( 1797 (
1474 AudioRegion(b"a" * 124 + b"b" * 376, 1235, 2, 2), 1798 AudioRegion(b"a" * 124 + b"b" * 376, 1235, 2, 2),
1475 slice(25, 50), 1799 slice(25, 50),
1476 25 / 1235, 1800 25 / 1235,
1477 b"a" * 24 + b"b" * 76, 1801 b"a" * 24 + b"b" * 76, # arbitrary_sampling_rate_middle_sw2_ch2
1478 ), 1802 ),
1479 ], 1803 ],
1480 ids=[ 1804 ids=[
1481 "first_half", 1805 "first_half",
1482 "second_half", 1806 "second_half",
1507 1831
1508 1832
1509 @pytest.mark.parametrize( 1833 @pytest.mark.parametrize(
1510 "sampling_rate, sample_width, channels", 1834 "sampling_rate, sample_width, channels",
1511 [ 1835 [
1512 (8000, 1, 1), 1836 (8000, 1, 1), # simple
1513 (8000, 2, 2), 1837 (8000, 2, 2), # stereo_sw_2
1514 (5413, 2, 3), 1838 (5413, 2, 3), # arbitrary_sr_multichannel
1515 ], 1839 ],
1516 ids=[ 1840 ids=[
1517 "simple", 1841 "simple",
1518 "stereo_sw_2", 1842 "stereo_sw_2",
1519 "arbitrary_sr_multichannel", 1843 "arbitrary_sr_multichannel",
1532 1856
1533 1857
1534 @pytest.mark.parametrize( 1858 @pytest.mark.parametrize(
1535 "sampling_rate, sample_width, channels", 1859 "sampling_rate, sample_width, channels",
1536 [ 1860 [
1537 (8000, 1, 1), 1861 (8000, 1, 1), # simple
1538 (8000, 2, 2), 1862 (8000, 2, 2), # stereo_sw_2
1539 (5413, 2, 3), 1863 (5413, 2, 3), # arbitrary_sr_multichannel
1540 ], 1864 ],
1541 ids=[ 1865 ids=[
1542 "simple", 1866 "simple",
1543 "stereo_sw_2", 1867 "stereo_sw_2",
1544 "arbitrary_sr_multichannel", 1868 "arbitrary_sr_multichannel",
1556 assert concat_region.duration == pytest.approx(expected_duration, abs=1e-6) 1880 assert concat_region.duration == pytest.approx(expected_duration, abs=1e-6)
1557 assert bytes(concat_region) == expected_data 1881 assert bytes(concat_region) == expected_data
1558 1882
1559 1883
1560 def test_concatenation_different_sampling_rate_error(): 1884 def test_concatenation_different_sampling_rate_error():
1561
1562 region_1 = AudioRegion(b"a" * 100, 8000, 1, 1) 1885 region_1 = AudioRegion(b"a" * 100, 8000, 1, 1)
1563 region_2 = AudioRegion(b"b" * 100, 3000, 1, 1) 1886 region_2 = AudioRegion(b"b" * 100, 3000, 1, 1)
1564 1887
1565 with pytest.raises(ValueError) as val_err: 1888 with pytest.raises(ValueError) as val_err:
1566 region_1 + region_2 1889 region_1 + region_2
1567 assert str(val_err.value) == ( 1890 assert str(val_err.value) == (
1568 "Can only concatenate AudioRegions of the same " 1891 "Can only concatenate AudioRegions of the same "
1569 "sampling rate (8000 != 3000)" 1892 "sampling rate (8000 != 3000)" # different_sampling_rate
1570 ) 1893 )
1571 1894
1572 1895
1573 def test_concatenation_different_sample_width_error(): 1896 def test_concatenation_different_sample_width_error():
1574
1575 region_1 = AudioRegion(b"a" * 100, 8000, 2, 1) 1897 region_1 = AudioRegion(b"a" * 100, 8000, 2, 1)
1576 region_2 = AudioRegion(b"b" * 100, 8000, 4, 1) 1898 region_2 = AudioRegion(b"b" * 100, 8000, 4, 1)
1577 1899
1578 with pytest.raises(ValueError) as val_err: 1900 with pytest.raises(ValueError) as val_err:
1579 region_1 + region_2 1901 region_1 + region_2
1580 assert str(val_err.value) == ( 1902 assert str(val_err.value) == (
1581 "Can only concatenate AudioRegions of the same " "sample width (2 != 4)" 1903 "Can only concatenate AudioRegions of the same sample width (2 != 4)"
1582 ) 1904 )
1583 1905
1584 1906
1585 def test_concatenation_different_number_of_channels_error(): 1907 def test_concatenation_different_number_of_channels_error():
1586
1587 region_1 = AudioRegion(b"a" * 100, 8000, 1, 1) 1908 region_1 = AudioRegion(b"a" * 100, 8000, 1, 1)
1588 region_2 = AudioRegion(b"b" * 100, 8000, 1, 2) 1909 region_2 = AudioRegion(b"b" * 100, 8000, 1, 2)
1589 1910
1590 with pytest.raises(ValueError) as val_err: 1911 with pytest.raises(ValueError) as val_err:
1591 region_1 + region_2 1912 region_1 + region_2
1592 assert str(val_err.value) == ( 1913 assert str(val_err.value) == (
1593 "Can only concatenate AudioRegions of the same " 1914 "Can only concatenate AudioRegions of the same "
1594 "number of channels (1 != 2)" 1915 "number of channels (1 != 2)" # different_number_of_channels
1595 ) 1916 )
1596 1917
1597 1918
1598 @pytest.mark.parametrize( 1919 @pytest.mark.parametrize(
1599 "duration, expected_duration, expected_len, expected_len_ms", 1920 "duration, expected_duration, expected_len, expected_len_ms",
1600 [ 1921 [
1601 (0.01, 0.03, 240, 30), 1922 (0.01, 0.03, 240, 30), # simple
1602 (0.00575, 0.01725, 138, 17), 1923 (0.00575, 0.01725, 138, 17), # rounded_len_floor
1603 (0.00625, 0.01875, 150, 19), 1924 (0.00625, 0.01875, 150, 19), # rounded_len_ceil
1604 ], 1925 ],
1605 ids=[ 1926 ids=[
1606 "simple", 1927 "simple",
1607 "rounded_len_floor", 1928 "rounded_len_floor",
1608 "rounded_len_ceil", 1929 "rounded_len_ceil",
1628 1949
1629 1950
1630 @pytest.mark.parametrize( 1951 @pytest.mark.parametrize(
1631 "factor, _type", 1952 "factor, _type",
1632 [ 1953 [
1633 ("x", "str"), 1954 ("x", str), # string
1634 (1.4, "float"), 1955 (1.4, float), # float
1635 ], 1956 ],
1636 ids=[ 1957 ids=[
1637 "_str", 1958 "string",
1638 "_float", 1959 "float",
1639 ], 1960 ],
1640 ) 1961 )
1641 def test_multiplication_non_int(factor, _type): 1962 def test_multiplication_non_int(factor, _type):
1642 with pytest.raises(TypeError) as type_err: 1963 with pytest.raises(TypeError) as type_err:
1643 AudioRegion(b"0" * 80, 8000, 1, 1) * factor 1964 AudioRegion(b"0" * 80, 8000, 1, 1) * factor
1644 err_msg = "Can't multiply AudioRegion by a non-int of type '{}'" 1965 err_msg = "Can't multiply AudioRegion by a non-int of type '{}'"
1645 assert err_msg.format(_type) == str(type_err.value) 1966 assert err_msg.format(_type) == str(type_err.value)
1646 1967
1647 1968
1648 @pytest.mark.parametrize( 1969 @pytest.mark.parametrize(
1649 "data", 1970 "data",
1650 [ 1971 [
1651 [b"a" * 80, b"b" * 80], 1972 [b"a" * 80, b"b" * 80], # simple
1652 [b"a" * 31, b"b" * 31, b"c" * 30], 1973 [b"a" * 31, b"b" * 31, b"c" * 30], # extra_samples_1
1653 [b"a" * 31, b"b" * 30, b"c" * 30], 1974 [b"a" * 31, b"b" * 30, b"c" * 30], # extra_samples_2
1654 [b"a" * 11, b"b" * 11, b"c" * 10, b"c" * 10], 1975 [b"a" * 11, b"b" * 11, b"c" * 10, b"c" * 10], # extra_samples_3
1655 ], 1976 ],
1656 ids=[ 1977 ids=[
1657 "simple", 1978 "simple",
1658 "extra_samples_1", 1979 "extra_samples_1",
1659 "extra_samples_2", 1980 "extra_samples_2",
1663 def test_truediv(data): 1984 def test_truediv(data):
1664 1985
1665 region = AudioRegion(b"".join(data), 80, 1, 1) 1986 region = AudioRegion(b"".join(data), 80, 1, 1)
1666 1987
1667 sub_regions = region / len(data) 1988 sub_regions = region / len(data)
1668 for data_i, region in zip(data, sub_regions): 1989 for data_i, region in zip(data, sub_regions, strict=True):
1669 assert len(data_i) == len(bytes(region)) 1990 assert len(data_i) == len(bytes(region))
1670 1991
1671 1992
1672 @pytest.mark.parametrize( 1993 @pytest.mark.parametrize(
1673 "data, sample_width, channels, fmt, expected", 1994 "data, sample_width, channels, expected",
1674 [ 1995 [
1675 (b"a" * 10, 1, 1, "b", [97] * 10), 1996 (b"a" * 10, 1, 1, [97] * 10), # mono_sw_1
1676 (b"a" * 10, 2, 1, "h", [24929] * 5), 1997 (b"a" * 10, 2, 1, [24929] * 5), # mono_sw_2
1677 (b"a" * 8, 4, 1, "i", [1633771873] * 2), 1998 (b"a" * 8, 4, 1, [1633771873] * 2), # mono_sw_4
1678 (b"ab" * 5, 1, 2, "b", [[97] * 5, [98] * 5]), 1999 (b"ab" * 5, 1, 2, [[97] * 5, [98] * 5]), # stereo_sw_1
1679 ], 2000 ],
1680 ids=[ 2001 ids=[
1681 "mono_sw_1", 2002 "mono_sw_1",
1682 "mono_sw_2", 2003 "mono_sw_2",
1683 "mono_sw_4", 2004 "mono_sw_4",
1684 "stereo_sw_1", 2005 "stereo_sw_1",
1685 ], 2006 ],
1686 ) 2007 )
1687 def test_samples(data, sample_width, channels, fmt, expected): 2008 def test_samples(data, sample_width, channels, expected):
1688 2009
1689 region = AudioRegion(data, 10, sample_width, channels) 2010 region = AudioRegion(data, 10, sample_width, channels)
1690 if isinstance(expected[0], list): 2011 expected = np.array(expected)
1691 expected = [array_(fmt, exp) for exp in expected] 2012 assert (region.samples == expected).all()
1692 else: 2013 assert (region.numpy() == expected).all()
1693 expected = array_(fmt, expected) 2014 assert (np.array(region) == expected).all()
1694 samples = region.samples
1695 equal = samples == expected
1696 try:
1697 # for numpy
1698 equal = equal.all()
1699 except AttributeError:
1700 pass
1701 assert equal