annotate tests/test_util.py @ 346:979343fe59e0

Install pydub and matplotlib Remove tests for python 3.2 and 3.3
author Amine SEHILI <amsehili@users.noreply.github.com>
date Sun, 10 Nov 2019 21:16:16 +0100
parents 5732edbfae30
children 96adb05e3a07
rev   line source
amine@337 1 import unittest
amine@317 2 from unittest import TestCase
amine@157 3 import math
amine@157 4 from array import array
amine@317 5 from genty import genty, genty_dataset
amine@345 6 from auditok.util import AudioEnergyValidator, make_duration_formatter
amine@321 7 from auditok.signal import FORMAT
amine@345 8 from auditok.exceptions import TimeFormatError
amine@157 9
amine@157 10
amine@157 11 def _sample_generator(*data_buffers):
amine@157 12 """
amine@157 13 Takes a list of many mono audio data buffers and makes a sample generator
amine@157 14 of interleaved audio samples, one sample from each channel. The resulting
amine@157 15 generator can be used to build a multichannel audio buffer.
amine@157 16 >>> gen = _sample_generator("abcd", "ABCD")
amine@157 17 >>> list(gen)
amine@157 18 ["a", "A", "b", "B", "c", "C", "d", "D"]
amine@157 19 """
amine@157 20 frame_gen = zip(*data_buffers)
amine@157 21 return (sample for frame in frame_gen for sample in frame)
amine@157 22
amine@157 23
amine@157 24 def _generate_pure_tone(
amine@157 25 frequency, duration_sec=1, sampling_rate=16000, sample_width=2, volume=1e4
amine@157 26 ):
amine@157 27 """
amine@157 28 Generates a pure tone with the given frequency.
amine@157 29 """
amine@157 30 assert frequency <= sampling_rate / 2
amine@157 31 max_value = (2 ** (sample_width * 8) // 2) - 1
amine@157 32 if volume > max_value:
amine@157 33 volume = max_value
amine@321 34 fmt = FORMAT[sample_width]
amine@157 35 total_samples = int(sampling_rate * duration_sec)
amine@157 36 step = frequency / sampling_rate
amine@157 37 two_pi_step = 2 * math.pi * step
amine@157 38 data = array(
amine@157 39 fmt,
amine@157 40 (
amine@157 41 int(math.sin(two_pi_step * i) * volume)
amine@157 42 for i in range(total_samples)
amine@157 43 ),
amine@157 44 )
amine@157 45 return data
amine@157 46
amine@157 47
amine@157 48 PURE_TONE_DICT = {
amine@157 49 freq: _generate_pure_tone(freq, 1, 16000, 2) for freq in (400, 800, 1600)
amine@157 50 }
amine@157 51 PURE_TONE_DICT.update(
amine@157 52 {
amine@157 53 freq: _generate_pure_tone(freq, 0.1, 16000, 2)
amine@157 54 for freq in (600, 1150, 2400, 7220)
amine@157 55 }
amine@157 56 )
amine@317 57
amine@317 58
amine@317 59 @genty
amine@345 60 class TestFunctions(TestCase):
amine@345 61 @genty_dataset(
amine@345 62 only_seconds=("%S", 5400, "5400.000"),
amine@345 63 only_millis=("%I", 5400, "5400000"),
amine@345 64 full=("%h:%m:%s.%i", 3725.365, "01:02:05.365"),
amine@345 65 full_zero_hours=("%h:%m:%s.%i", 1925.075, "00:32:05.075"),
amine@345 66 full_zero_minutes=("%h:%m:%s.%i", 3659.075, "01:00:59.075"),
amine@345 67 full_zero_seconds=("%h:%m:%s.%i", 3720.075, "01:02:00.075"),
amine@345 68 full_zero_millis=("%h:%m:%s.%i", 3725, "01:02:05.000"),
amine@345 69 duplicate_directive=(
amine@345 70 "%h %h:%m:%s.%i %s",
amine@345 71 3725.365,
amine@345 72 "01 01:02:05.365 05",
amine@345 73 ),
amine@345 74 no_millis=("%h:%m:%s", 3725, "01:02:05"),
amine@345 75 no_seconds=("%h:%m", 3725, "01:02"),
amine@345 76 no_minutes=("%h", 3725, "01"),
amine@345 77 no_hours=("%m:%s.%i", 3725, "02:05.000"),
amine@345 78 )
amine@345 79 def test_make_duration_formatter(self, fmt, duration, expected):
amine@345 80 formatter = make_duration_formatter(fmt)
amine@345 81 result = formatter(duration)
amine@345 82 self.assertEqual(result, expected)
amine@345 83
amine@345 84 @genty_dataset(
amine@345 85 duplicate_only_seconds=("%S %S",),
amine@345 86 duplicate_only_millis=("%I %I",),
amine@345 87 unknown_directive=("%x",),
amine@345 88 )
amine@345 89 def test_make_duration_formatter_error(self, fmt):
amine@345 90 with self.assertRaises(TimeFormatError):
amine@345 91 make_duration_formatter(fmt)
amine@345 92
amine@345 93
amine@345 94 @genty
amine@317 95 class TestAudioEnergyValidator(TestCase):
amine@317 96 @genty_dataset(
amine@317 97 mono_valid_uc_None=([350, 400], 1, None, True),
amine@317 98 mono_valid_uc_any=([350, 400], 1, "any", True),
amine@317 99 mono_valid_uc_0=([350, 400], 1, 0, True),
amine@317 100 mono_valid_uc_mix=([350, 400], 1, "mix", True),
amine@317 101 # previous cases are all the same since we have mono audio
amine@317 102 mono_invalid_uc_None=([300, 300], 1, None, False),
amine@317 103 stereo_valid_uc_None=([300, 400, 350, 300], 2, None, True),
amine@317 104 stereo_valid_uc_any=([300, 400, 350, 300], 2, "any", True),
amine@317 105 stereo_valid_uc_mix=([300, 400, 350, 300], 2, "mix", True),
amine@317 106 stereo_valid_uc_avg=([300, 400, 350, 300], 2, "avg", True),
amine@317 107 stereo_valid_uc_average=([300, 400, 300, 300], 2, "average", True),
amine@317 108 stereo_valid_uc_mix_with_null_channel=(
amine@317 109 [634, 0, 634, 0],
amine@317 110 2,
amine@317 111 "mix",
amine@317 112 True,
amine@317 113 ),
amine@317 114 stereo_valid_uc_0=([320, 100, 320, 100], 2, 0, True),
amine@317 115 stereo_valid_uc_1=([100, 320, 100, 320], 2, 1, True),
amine@317 116 stereo_invalid_uc_None=([280, 100, 280, 100], 2, None, False),
amine@317 117 stereo_invalid_uc_any=([280, 100, 280, 100], 2, "any", False),
amine@317 118 stereo_invalid_uc_mix=([400, 200, 400, 200], 2, "mix", False),
amine@317 119 stereo_invalid_uc_0=([300, 400, 300, 400], 2, 0, False),
amine@317 120 stereo_invalid_uc_1=([400, 300, 400, 300], 2, 1, False),
amine@317 121 zeros=([0, 0, 0, 0], 2, None, False),
amine@317 122 )
amine@317 123 def test_audio_energy_validator(
amine@317 124 self, data, channels, use_channel, expected
amine@317 125 ):
amine@317 126
amine@317 127 data = array("h", data)
amine@317 128 sample_width = 2
amine@317 129 energy_threshold = 50
amine@317 130 validator = AudioEnergyValidator(
amine@317 131 energy_threshold, sample_width, channels, use_channel
amine@317 132 )
amine@317 133
amine@317 134 if expected:
amine@317 135 self.assertTrue(validator.is_valid(data))
amine@317 136 else:
amine@317 137 self.assertFalse(validator.is_valid(data))
amine@337 138
amine@337 139
amine@337 140 if __name__ == "__main__":
amine@337 141 unittest.main()