amine@330
|
1 """
|
amine@330
|
2 @author: Amine Sehili <amine.sehili@gmail.com>
|
amine@330
|
3 September 2015
|
amine@330
|
4
|
amine@330
|
5 """
|
amine@330
|
6
|
amine@330
|
7 import unittest
|
amine@330
|
8 from functools import partial
|
amine@330
|
9 import sys
|
amine@330
|
10 import wave
|
amine@330
|
11 from genty import genty, genty_dataset
|
amine@330
|
12 from auditok import (
|
amine@330
|
13 dataset,
|
amine@330
|
14 ADSFactory,
|
amine@330
|
15 AudioDataSource,
|
amine@330
|
16 AudioReader,
|
amine@330
|
17 Recorder,
|
amine@330
|
18 BufferAudioSource,
|
amine@330
|
19 WaveAudioSource,
|
amine@330
|
20 DuplicateArgument,
|
amine@330
|
21 )
|
amine@330
|
22
|
amine@330
|
23
|
amine@330
|
24 class TestADSFactoryFileAudioSource(unittest.TestCase):
|
amine@330
|
25 def setUp(self):
|
amine@330
|
26 self.audio_source = WaveAudioSource(
|
amine@330
|
27 filename=dataset.one_to_six_arabic_16000_mono_bc_noise
|
amine@330
|
28 )
|
amine@330
|
29
|
amine@330
|
30 def test_ADS_type(self):
|
amine@330
|
31
|
amine@330
|
32 ads = ADSFactory.ads(audio_source=self.audio_source)
|
amine@330
|
33
|
amine@330
|
34 err_msg = "wrong type for ads object, expected: 'AudioDataSource', "
|
amine@330
|
35 err_msg += "found: {0}"
|
amine@330
|
36 self.assertIsInstance(
|
amine@330
|
37 ads, AudioDataSource, err_msg.format(type(ads)),
|
amine@330
|
38 )
|
amine@330
|
39
|
amine@330
|
40 def test_default_block_size(self):
|
amine@330
|
41 ads = ADSFactory.ads(audio_source=self.audio_source)
|
amine@330
|
42 size = ads.block_size
|
amine@330
|
43 self.assertEqual(
|
amine@330
|
44 size,
|
amine@330
|
45 160,
|
amine@330
|
46 "Wrong default block_size, expected: 160, found: {0}".format(size),
|
amine@330
|
47 )
|
amine@330
|
48
|
amine@330
|
49 def test_block_size(self):
|
amine@330
|
50 ads = ADSFactory.ads(audio_source=self.audio_source, block_size=512)
|
amine@330
|
51 size = ads.block_size
|
amine@330
|
52 self.assertEqual(
|
amine@330
|
53 size,
|
amine@330
|
54 512,
|
amine@330
|
55 "Wrong block_size, expected: 512, found: {0}".format(size),
|
amine@330
|
56 )
|
amine@330
|
57
|
amine@330
|
58 # with alias keyword
|
amine@330
|
59 ads = ADSFactory.ads(audio_source=self.audio_source, bs=160)
|
amine@330
|
60 size = ads.block_size
|
amine@330
|
61 self.assertEqual(
|
amine@330
|
62 size,
|
amine@330
|
63 160,
|
amine@330
|
64 "Wrong block_size, expected: 160, found: {0}".format(size),
|
amine@330
|
65 )
|
amine@330
|
66
|
amine@330
|
67 def test_block_duration(self):
|
amine@330
|
68
|
amine@330
|
69 ads = ADSFactory.ads(
|
amine@330
|
70 audio_source=self.audio_source, block_dur=0.01
|
amine@330
|
71 ) # 10 ms
|
amine@330
|
72 size = ads.block_size
|
amine@330
|
73 self.assertEqual(
|
amine@330
|
74 size,
|
amine@330
|
75 160,
|
amine@330
|
76 "Wrong block_size, expected: 160, found: {0}".format(size),
|
amine@330
|
77 )
|
amine@330
|
78
|
amine@330
|
79 # with alias keyword
|
amine@330
|
80 ads = ADSFactory.ads(audio_source=self.audio_source, bd=0.025) # 25 ms
|
amine@330
|
81 size = ads.block_size
|
amine@330
|
82 self.assertEqual(
|
amine@330
|
83 size,
|
amine@330
|
84 400,
|
amine@330
|
85 "Wrong block_size, expected: 400, found: {0}".format(size),
|
amine@330
|
86 )
|
amine@330
|
87
|
amine@330
|
88 def test_hop_duration(self):
|
amine@330
|
89
|
amine@330
|
90 ads = ADSFactory.ads(
|
amine@330
|
91 audio_source=self.audio_source, block_dur=0.02, hop_dur=0.01
|
amine@330
|
92 ) # 10 ms
|
amine@330
|
93 size = ads.hop_size
|
amine@330
|
94 self.assertEqual(
|
amine@330
|
95 size, 160, "Wrong hop_size, expected: 160, found: {0}".format(size)
|
amine@330
|
96 )
|
amine@330
|
97
|
amine@330
|
98 # with alias keyword
|
amine@330
|
99 ads = ADSFactory.ads(
|
amine@330
|
100 audio_source=self.audio_source, bd=0.025, hop_dur=0.015
|
amine@330
|
101 ) # 15 ms
|
amine@330
|
102 size = ads.hop_size
|
amine@330
|
103 self.assertEqual(
|
amine@330
|
104 size,
|
amine@330
|
105 240,
|
amine@330
|
106 "Wrong block_size, expected: 240, found: {0}".format(size),
|
amine@330
|
107 )
|
amine@330
|
108
|
amine@330
|
109 def test_sampling_rate(self):
|
amine@330
|
110 ads = ADSFactory.ads(audio_source=self.audio_source)
|
amine@330
|
111
|
amine@330
|
112 srate = ads.sampling_rate
|
amine@330
|
113 self.assertEqual(
|
amine@330
|
114 srate,
|
amine@330
|
115 16000,
|
amine@330
|
116 "Wrong sampling rate, expected: 16000, found: {0}".format(srate),
|
amine@330
|
117 )
|
amine@330
|
118
|
amine@330
|
119 def test_sample_width(self):
|
amine@330
|
120 ads = ADSFactory.ads(audio_source=self.audio_source)
|
amine@330
|
121
|
amine@330
|
122 swidth = ads.sample_width
|
amine@330
|
123 self.assertEqual(
|
amine@330
|
124 swidth,
|
amine@330
|
125 2,
|
amine@330
|
126 "Wrong sample width, expected: 2, found: {0}".format(swidth),
|
amine@330
|
127 )
|
amine@330
|
128
|
amine@330
|
129 def test_channels(self):
|
amine@330
|
130 ads = ADSFactory.ads(audio_source=self.audio_source)
|
amine@330
|
131
|
amine@330
|
132 channels = ads.channels
|
amine@330
|
133 self.assertEqual(
|
amine@330
|
134 channels,
|
amine@330
|
135 1,
|
amine@330
|
136 "Wrong number of channels, expected: 1, found: {0}".format(
|
amine@330
|
137 channels
|
amine@330
|
138 ),
|
amine@330
|
139 )
|
amine@330
|
140
|
amine@330
|
141 def test_read(self):
|
amine@330
|
142 ads = ADSFactory.ads(audio_source=self.audio_source, block_size=256)
|
amine@330
|
143
|
amine@330
|
144 ads.open()
|
amine@330
|
145 ads_data = ads.read()
|
amine@330
|
146 ads.close()
|
amine@330
|
147
|
amine@330
|
148 audio_source = WaveAudioSource(
|
amine@330
|
149 filename=dataset.one_to_six_arabic_16000_mono_bc_noise
|
amine@330
|
150 )
|
amine@330
|
151 audio_source.open()
|
amine@330
|
152 audio_source_data = audio_source.read(256)
|
amine@330
|
153 audio_source.close()
|
amine@330
|
154
|
amine@330
|
155 self.assertEqual(
|
amine@330
|
156 ads_data, audio_source_data, "Unexpected data read from ads"
|
amine@330
|
157 )
|
amine@330
|
158
|
amine@330
|
159 def test_Limiter_Deco_read(self):
|
amine@330
|
160 # read a maximum of 0.75 seconds from audio source
|
amine@330
|
161 ads = ADSFactory.ads(audio_source=self.audio_source, max_time=0.75)
|
amine@330
|
162
|
amine@330
|
163 ads_data = []
|
amine@330
|
164 ads.open()
|
amine@330
|
165 while True:
|
amine@330
|
166 block = ads.read()
|
amine@330
|
167 if block is None:
|
amine@330
|
168 break
|
amine@330
|
169 ads_data.append(block)
|
amine@330
|
170 ads.close()
|
amine@330
|
171 ads_data = b"".join(ads_data)
|
amine@330
|
172
|
amine@330
|
173 audio_source = WaveAudioSource(
|
amine@330
|
174 filename=dataset.one_to_six_arabic_16000_mono_bc_noise
|
amine@330
|
175 )
|
amine@330
|
176 audio_source.open()
|
amine@330
|
177 audio_source_data = audio_source.read(int(16000 * 0.75))
|
amine@330
|
178 audio_source.close()
|
amine@330
|
179
|
amine@330
|
180 self.assertEqual(
|
amine@330
|
181 ads_data, audio_source_data, "Unexpected data read from LimiterADS"
|
amine@330
|
182 )
|
amine@330
|
183
|
amine@330
|
184 def test_Limiter_Deco_read_limit(self):
|
amine@330
|
185 # read a maximum of 1.191 seconds from audio source
|
amine@330
|
186 ads = ADSFactory.ads(audio_source=self.audio_source, max_time=1.191)
|
amine@330
|
187 total_samples = round(ads.sampling_rate * 1.191)
|
amine@330
|
188 nb_full_blocks, last_block_size = divmod(total_samples, ads.block_size)
|
amine@330
|
189 total_samples_with_overlap = (
|
amine@330
|
190 nb_full_blocks * ads.block_size + last_block_size
|
amine@330
|
191 )
|
amine@330
|
192 expected_read_bytes = (
|
amine@330
|
193 total_samples_with_overlap * ads.sw * ads.channels
|
amine@330
|
194 )
|
amine@330
|
195
|
amine@330
|
196 total_read = 0
|
amine@330
|
197 ads.open()
|
amine@330
|
198 i = 0
|
amine@330
|
199 while True:
|
amine@330
|
200 block = ads.read()
|
amine@330
|
201 if block is None:
|
amine@330
|
202 break
|
amine@330
|
203 i += 1
|
amine@330
|
204 total_read += len(block)
|
amine@330
|
205
|
amine@330
|
206 ads.close()
|
amine@330
|
207 err_msg = "Wrong data length read from LimiterADS, expected: {0}, "
|
amine@330
|
208 err_msg += "found: {1}"
|
amine@330
|
209 self.assertEqual(
|
amine@330
|
210 total_read,
|
amine@330
|
211 expected_read_bytes,
|
amine@330
|
212 err_msg.format(expected_read_bytes, total_read),
|
amine@330
|
213 )
|
amine@330
|
214
|
amine@330
|
215 def test_Recorder_Deco_read(self):
|
amine@330
|
216 ads = ADSFactory.ads(
|
amine@330
|
217 audio_source=self.audio_source, record=True, block_size=500
|
amine@330
|
218 )
|
amine@330
|
219
|
amine@330
|
220 ads_data = []
|
amine@330
|
221 ads.open()
|
amine@330
|
222 for i in range(10):
|
amine@330
|
223 block = ads.read()
|
amine@330
|
224 if block is None:
|
amine@330
|
225 break
|
amine@330
|
226 ads_data.append(block)
|
amine@330
|
227 ads.close()
|
amine@330
|
228 ads_data = b"".join(ads_data)
|
amine@330
|
229
|
amine@330
|
230 audio_source = WaveAudioSource(
|
amine@330
|
231 filename=dataset.one_to_six_arabic_16000_mono_bc_noise
|
amine@330
|
232 )
|
amine@330
|
233 audio_source.open()
|
amine@330
|
234 audio_source_data = audio_source.read(500 * 10)
|
amine@330
|
235 audio_source.close()
|
amine@330
|
236
|
amine@330
|
237 self.assertEqual(
|
amine@330
|
238 ads_data,
|
amine@330
|
239 audio_source_data,
|
amine@330
|
240 "Unexpected data read from RecorderADS",
|
amine@330
|
241 )
|
amine@330
|
242
|
amine@330
|
243 def test_Recorder_Deco_is_rewindable(self):
|
amine@330
|
244 ads = ADSFactory.ads(audio_source=self.audio_source, record=True)
|
amine@330
|
245
|
amine@330
|
246 self.assertTrue(
|
amine@330
|
247 ads.rewindable, "RecorderADS.is_rewindable should return True"
|
amine@330
|
248 )
|
amine@330
|
249
|
amine@330
|
250 def test_Recorder_Deco_rewind_and_read(self):
|
amine@330
|
251 ads = ADSFactory.ads(
|
amine@330
|
252 audio_source=self.audio_source, record=True, block_size=320
|
amine@330
|
253 )
|
amine@330
|
254
|
amine@330
|
255 ads.open()
|
amine@330
|
256 for i in range(10):
|
amine@330
|
257 ads.read()
|
amine@330
|
258
|
amine@330
|
259 ads.rewind()
|
amine@330
|
260
|
amine@330
|
261 # read all available data after rewind
|
amine@330
|
262 ads_data = []
|
amine@330
|
263 while True:
|
amine@330
|
264 block = ads.read()
|
amine@330
|
265 if block is None:
|
amine@330
|
266 break
|
amine@330
|
267 ads_data.append(block)
|
amine@330
|
268 ads.close()
|
amine@330
|
269 ads_data = b"".join(ads_data)
|
amine@330
|
270
|
amine@330
|
271 audio_source = WaveAudioSource(
|
amine@330
|
272 filename=dataset.one_to_six_arabic_16000_mono_bc_noise
|
amine@330
|
273 )
|
amine@330
|
274 audio_source.open()
|
amine@330
|
275 audio_source_data = audio_source.read(320 * 10)
|
amine@330
|
276 audio_source.close()
|
amine@330
|
277
|
amine@330
|
278 self.assertEqual(
|
amine@330
|
279 ads_data,
|
amine@330
|
280 audio_source_data,
|
amine@330
|
281 "Unexpected data read from RecorderADS",
|
amine@330
|
282 )
|
amine@330
|
283
|
amine@330
|
284 def test_Overlap_Deco_read(self):
|
amine@330
|
285
|
amine@330
|
286 # Use arbitrary valid block_size and hop_size
|
amine@330
|
287 block_size = 1714
|
amine@330
|
288 hop_size = 313
|
amine@330
|
289
|
amine@330
|
290 ads = ADSFactory.ads(
|
amine@330
|
291 audio_source=self.audio_source,
|
amine@330
|
292 block_size=block_size,
|
amine@330
|
293 hop_size=hop_size,
|
amine@330
|
294 )
|
amine@330
|
295
|
amine@330
|
296 # Read all available data overlapping blocks
|
amine@330
|
297 ads.open()
|
amine@330
|
298 ads_data = []
|
amine@330
|
299 while True:
|
amine@330
|
300 block = ads.read()
|
amine@330
|
301 if block is None:
|
amine@330
|
302 break
|
amine@330
|
303 ads_data.append(block)
|
amine@330
|
304 ads.close()
|
amine@330
|
305
|
amine@330
|
306 # Read all data from file and build a BufferAudioSource
|
amine@330
|
307 fp = wave.open(dataset.one_to_six_arabic_16000_mono_bc_noise, "r")
|
amine@330
|
308 wave_data = fp.readframes(fp.getnframes())
|
amine@330
|
309 fp.close()
|
amine@330
|
310 audio_source = BufferAudioSource(
|
amine@330
|
311 wave_data, ads.sampling_rate, ads.sample_width, ads.channels
|
amine@330
|
312 )
|
amine@330
|
313 audio_source.open()
|
amine@330
|
314
|
amine@330
|
315 # Compare all blocks read from OverlapADS to those read
|
amine@330
|
316 # from an audio source with a manual position setting
|
amine@330
|
317 for i, block in enumerate(ads_data):
|
amine@330
|
318
|
amine@330
|
319 tmp = audio_source.read(block_size)
|
amine@330
|
320
|
amine@330
|
321 self.assertEqual(
|
amine@330
|
322 block,
|
amine@330
|
323 tmp,
|
amine@330
|
324 "Unexpected block (N={0}) read from OverlapADS".format(i),
|
amine@330
|
325 )
|
amine@330
|
326
|
amine@330
|
327 audio_source.position = (i + 1) * hop_size
|
amine@330
|
328
|
amine@330
|
329 audio_source.close()
|
amine@330
|
330
|
amine@330
|
331 def test_Limiter_Overlap_Deco_read(self):
|
amine@330
|
332
|
amine@330
|
333 block_size = 256
|
amine@330
|
334 hop_size = 200
|
amine@330
|
335
|
amine@330
|
336 ads = ADSFactory.ads(
|
amine@330
|
337 audio_source=self.audio_source,
|
amine@330
|
338 max_time=0.50,
|
amine@330
|
339 block_size=block_size,
|
amine@330
|
340 hop_size=hop_size,
|
amine@330
|
341 )
|
amine@330
|
342
|
amine@330
|
343 # Read all available data overlapping blocks
|
amine@330
|
344 ads.open()
|
amine@330
|
345 ads_data = []
|
amine@330
|
346 while True:
|
amine@330
|
347 block = ads.read()
|
amine@330
|
348 if block is None:
|
amine@330
|
349 break
|
amine@330
|
350 ads_data.append(block)
|
amine@330
|
351 ads.close()
|
amine@330
|
352
|
amine@330
|
353 # Read all data from file and build a BufferAudioSource
|
amine@330
|
354 fp = wave.open(dataset.one_to_six_arabic_16000_mono_bc_noise, "r")
|
amine@330
|
355 wave_data = fp.readframes(fp.getnframes())
|
amine@330
|
356 fp.close()
|
amine@330
|
357 audio_source = BufferAudioSource(
|
amine@330
|
358 wave_data, ads.sampling_rate, ads.sample_width, ads.channels
|
amine@330
|
359 )
|
amine@330
|
360 audio_source.open()
|
amine@330
|
361
|
amine@330
|
362 # Compare all blocks read from OverlapADS to those read
|
amine@330
|
363 # from an audio source with a manual position setting
|
amine@330
|
364 for i, block in enumerate(ads_data):
|
amine@330
|
365 tmp = audio_source.read(len(block) // (ads.sw * ads.ch))
|
amine@330
|
366 self.assertEqual(
|
amine@330
|
367 len(block),
|
amine@330
|
368 len(tmp),
|
amine@330
|
369 "Unexpected block (N={0}) read from OverlapADS".format(i),
|
amine@330
|
370 )
|
amine@330
|
371 audio_source.position = (i + 1) * hop_size
|
amine@330
|
372
|
amine@330
|
373 audio_source.close()
|
amine@330
|
374
|
amine@330
|
375 def test_Limiter_Overlap_Deco_read_limit(self):
|
amine@330
|
376
|
amine@330
|
377 block_size = 313
|
amine@330
|
378 hop_size = 207
|
amine@330
|
379 ads = ADSFactory.ads(
|
amine@330
|
380 audio_source=self.audio_source,
|
amine@330
|
381 max_time=1.932,
|
amine@330
|
382 block_size=block_size,
|
amine@330
|
383 hop_size=hop_size,
|
amine@330
|
384 )
|
amine@330
|
385
|
amine@330
|
386 total_samples = round(ads.sampling_rate * 1.932)
|
amine@330
|
387 first_read_size = block_size
|
amine@330
|
388 next_read_size = block_size - hop_size
|
amine@330
|
389 nb_next_blocks, last_block_size = divmod(
|
amine@330
|
390 (total_samples - first_read_size), next_read_size
|
amine@330
|
391 )
|
amine@330
|
392 total_samples_with_overlap = (
|
amine@330
|
393 first_read_size + next_read_size * nb_next_blocks + last_block_size
|
amine@330
|
394 )
|
amine@330
|
395 expected_read_bytes = (
|
amine@330
|
396 total_samples_with_overlap * ads.sw * ads.channels
|
amine@330
|
397 )
|
amine@330
|
398
|
amine@330
|
399 cache_size = (block_size - hop_size) * ads.sample_width * ads.channels
|
amine@330
|
400 total_read = cache_size
|
amine@330
|
401
|
amine@330
|
402 ads.open()
|
amine@330
|
403 i = 0
|
amine@330
|
404 while True:
|
amine@330
|
405 block = ads.read()
|
amine@330
|
406 if block is None:
|
amine@330
|
407 break
|
amine@330
|
408 i += 1
|
amine@330
|
409 total_read += len(block) - cache_size
|
amine@330
|
410
|
amine@330
|
411 ads.close()
|
amine@330
|
412 err_msg = "Wrong data length read from LimiterADS, expected: {0}, "
|
amine@330
|
413 err_msg += "found: {1}"
|
amine@330
|
414 self.assertEqual(
|
amine@330
|
415 total_read,
|
amine@330
|
416 expected_read_bytes,
|
amine@330
|
417 err_msg.format(expected_read_bytes, total_read),
|
amine@330
|
418 )
|
amine@330
|
419
|
amine@330
|
420 def test_Recorder_Overlap_Deco_is_rewindable(self):
|
amine@330
|
421 ads = ADSFactory.ads(
|
amine@330
|
422 audio_source=self.audio_source,
|
amine@330
|
423 block_size=320,
|
amine@330
|
424 hop_size=160,
|
amine@330
|
425 record=True,
|
amine@330
|
426 )
|
amine@330
|
427 self.assertTrue(
|
amine@330
|
428 ads.rewindable, "RecorderADS.is_rewindable should return True"
|
amine@330
|
429 )
|
amine@330
|
430
|
amine@330
|
431 def test_Recorder_Overlap_Deco_rewind_and_read(self):
|
amine@330
|
432
|
amine@330
|
433 # Use arbitrary valid block_size and hop_size
|
amine@330
|
434 block_size = 1600
|
amine@330
|
435 hop_size = 400
|
amine@330
|
436
|
amine@330
|
437 ads = ADSFactory.ads(
|
amine@330
|
438 audio_source=self.audio_source,
|
amine@330
|
439 block_size=block_size,
|
amine@330
|
440 hop_size=hop_size,
|
amine@330
|
441 record=True,
|
amine@330
|
442 )
|
amine@330
|
443
|
amine@330
|
444 # Read all available data overlapping blocks
|
amine@330
|
445 ads.open()
|
amine@330
|
446 i = 0
|
amine@330
|
447 while True:
|
amine@330
|
448 block = ads.read()
|
amine@330
|
449 if block is None:
|
amine@330
|
450 break
|
amine@330
|
451 i += 1
|
amine@330
|
452
|
amine@330
|
453 ads.rewind()
|
amine@330
|
454
|
amine@330
|
455 # Read all data from file and build a BufferAudioSource
|
amine@330
|
456 fp = wave.open(dataset.one_to_six_arabic_16000_mono_bc_noise, "r")
|
amine@330
|
457 wave_data = fp.readframes(fp.getnframes())
|
amine@330
|
458 fp.close()
|
amine@330
|
459 audio_source = BufferAudioSource(
|
amine@330
|
460 wave_data, ads.sampling_rate, ads.sample_width, ads.channels
|
amine@330
|
461 )
|
amine@330
|
462 audio_source.open()
|
amine@330
|
463
|
amine@330
|
464 # Compare all blocks read from OverlapADS to those read
|
amine@330
|
465 # from an audio source with a manual position setting
|
amine@330
|
466 for j in range(i):
|
amine@330
|
467
|
amine@330
|
468 tmp = audio_source.read(block_size)
|
amine@330
|
469
|
amine@330
|
470 self.assertEqual(
|
amine@330
|
471 ads.read(),
|
amine@330
|
472 tmp,
|
amine@330
|
473 "Unexpected block (N={0}) read from OverlapADS".format(i),
|
amine@330
|
474 )
|
amine@330
|
475 audio_source.position = (j + 1) * hop_size
|
amine@330
|
476
|
amine@330
|
477 ads.close()
|
amine@330
|
478 audio_source.close()
|
amine@330
|
479
|
amine@330
|
480 def test_Limiter_Recorder_Overlap_Deco_rewind_and_read(self):
|
amine@330
|
481
|
amine@330
|
482 # Use arbitrary valid block_size and hop_size
|
amine@330
|
483 block_size = 1600
|
amine@330
|
484 hop_size = 400
|
amine@330
|
485
|
amine@330
|
486 ads = ADSFactory.ads(
|
amine@330
|
487 audio_source=self.audio_source,
|
amine@330
|
488 max_time=1.50,
|
amine@330
|
489 block_size=block_size,
|
amine@330
|
490 hop_size=hop_size,
|
amine@330
|
491 record=True,
|
amine@330
|
492 )
|
amine@330
|
493
|
amine@330
|
494 # Read all available data overlapping blocks
|
amine@330
|
495 ads.open()
|
amine@330
|
496 i = 0
|
amine@330
|
497 while True:
|
amine@330
|
498 block = ads.read()
|
amine@330
|
499 if block is None:
|
amine@330
|
500 break
|
amine@330
|
501 i += 1
|
amine@330
|
502
|
amine@330
|
503 ads.rewind()
|
amine@330
|
504
|
amine@330
|
505 # Read all data from file and build a BufferAudioSource
|
amine@330
|
506 fp = wave.open(dataset.one_to_six_arabic_16000_mono_bc_noise, "r")
|
amine@330
|
507 wave_data = fp.readframes(fp.getnframes())
|
amine@330
|
508 fp.close()
|
amine@330
|
509 audio_source = BufferAudioSource(
|
amine@330
|
510 wave_data, ads.sampling_rate, ads.sample_width, ads.channels
|
amine@330
|
511 )
|
amine@330
|
512 audio_source.open()
|
amine@330
|
513
|
amine@330
|
514 # Compare all blocks read from OverlapADS to those read
|
amine@330
|
515 # from an audio source with a manual position setting
|
amine@330
|
516 for j in range(i):
|
amine@330
|
517
|
amine@330
|
518 tmp = audio_source.read(block_size)
|
amine@330
|
519
|
amine@330
|
520 self.assertEqual(
|
amine@330
|
521 ads.read(),
|
amine@330
|
522 tmp,
|
amine@330
|
523 "Unexpected block (N={0}) read from OverlapADS".format(i),
|
amine@330
|
524 )
|
amine@330
|
525 audio_source.position = (j + 1) * hop_size
|
amine@330
|
526
|
amine@330
|
527 ads.close()
|
amine@330
|
528 audio_source.close()
|
amine@330
|
529
|
amine@330
|
530 def test_Limiter_Recorder_Overlap_Deco_rewind_and_read_limit(self):
|
amine@330
|
531
|
amine@330
|
532 # Use arbitrary valid block_size and hop_size
|
amine@330
|
533 block_size = 1000
|
amine@330
|
534 hop_size = 200
|
amine@330
|
535
|
amine@330
|
536 ads = ADSFactory.ads(
|
amine@330
|
537 audio_source=self.audio_source,
|
amine@330
|
538 max_time=1.317,
|
amine@330
|
539 block_size=block_size,
|
amine@330
|
540 hop_size=hop_size,
|
amine@330
|
541 record=True,
|
amine@330
|
542 )
|
amine@330
|
543 total_samples = round(ads.sampling_rate * 1.317)
|
amine@330
|
544 first_read_size = block_size
|
amine@330
|
545 next_read_size = block_size - hop_size
|
amine@330
|
546 nb_next_blocks, last_block_size = divmod(
|
amine@330
|
547 (total_samples - first_read_size), next_read_size
|
amine@330
|
548 )
|
amine@330
|
549 total_samples_with_overlap = (
|
amine@330
|
550 first_read_size + next_read_size * nb_next_blocks + last_block_size
|
amine@330
|
551 )
|
amine@330
|
552 expected_read_bytes = (
|
amine@330
|
553 total_samples_with_overlap * ads.sw * ads.channels
|
amine@330
|
554 )
|
amine@330
|
555
|
amine@330
|
556 cache_size = (block_size - hop_size) * ads.sample_width * ads.channels
|
amine@330
|
557 total_read = cache_size
|
amine@330
|
558
|
amine@330
|
559 ads.open()
|
amine@330
|
560 i = 0
|
amine@330
|
561 while True:
|
amine@330
|
562 block = ads.read()
|
amine@330
|
563 if block is None:
|
amine@330
|
564 break
|
amine@330
|
565 i += 1
|
amine@330
|
566 total_read += len(block) - cache_size
|
amine@330
|
567
|
amine@330
|
568 ads.close()
|
amine@330
|
569 err_msg = "Wrong data length read from LimiterADS, expected: {0}, "
|
amine@330
|
570 err_msg += "found: {1}"
|
amine@330
|
571 self.assertEqual(
|
amine@330
|
572 total_read,
|
amine@330
|
573 expected_read_bytes,
|
amine@330
|
574 err_msg.format(expected_read_bytes, total_read),
|
amine@330
|
575 )
|
amine@330
|
576
|
amine@330
|
577
|
amine@330
|
578 class TestADSFactoryBufferAudioSource(unittest.TestCase):
|
amine@330
|
579 def setUp(self):
|
amine@330
|
580 self.signal = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"
|
amine@330
|
581 self.ads = ADSFactory.ads(
|
amine@330
|
582 data_buffer=self.signal,
|
amine@330
|
583 sampling_rate=16,
|
amine@330
|
584 sample_width=2,
|
amine@330
|
585 channels=1,
|
amine@330
|
586 block_size=4,
|
amine@330
|
587 )
|
amine@330
|
588
|
amine@330
|
589 def test_ADS_BAS_sampling_rate(self):
|
amine@330
|
590 srate = self.ads.sampling_rate
|
amine@330
|
591 self.assertEqual(
|
amine@330
|
592 srate,
|
amine@330
|
593 16,
|
amine@330
|
594 "Wrong sampling rate, expected: 16000, found: {0}".format(srate),
|
amine@330
|
595 )
|
amine@330
|
596
|
amine@335
|
597 def test_ADS_BAS_sample_width(self):
|
amine@330
|
598 swidth = self.ads.sample_width
|
amine@330
|
599 self.assertEqual(
|
amine@330
|
600 swidth,
|
amine@330
|
601 2,
|
amine@330
|
602 "Wrong sample width, expected: 2, found: {0}".format(swidth),
|
amine@330
|
603 )
|
amine@330
|
604
|
amine@335
|
605 def test_ADS_BAS_channels(self):
|
amine@330
|
606 channels = self.ads.channels
|
amine@330
|
607 self.assertEqual(
|
amine@330
|
608 channels,
|
amine@330
|
609 1,
|
amine@330
|
610 "Wrong number of channels, expected: 1, found: {0}".format(
|
amine@330
|
611 channels
|
amine@330
|
612 ),
|
amine@330
|
613 )
|
amine@330
|
614
|
amine@330
|
615 def test_Limiter_Recorder_Overlap_Deco_rewind_and_read(self):
|
amine@330
|
616
|
amine@330
|
617 # Use arbitrary valid block_size and hop_size
|
amine@330
|
618 block_size = 5
|
amine@330
|
619 hop_size = 4
|
amine@330
|
620
|
amine@330
|
621 ads = ADSFactory.ads(
|
amine@330
|
622 data_buffer=self.signal,
|
amine@330
|
623 sampling_rate=16,
|
amine@330
|
624 sample_width=2,
|
amine@330
|
625 channels=1,
|
amine@330
|
626 max_time=0.80,
|
amine@330
|
627 block_size=block_size,
|
amine@330
|
628 hop_size=hop_size,
|
amine@330
|
629 record=True,
|
amine@330
|
630 )
|
amine@330
|
631
|
amine@330
|
632 # Read all available data overlapping blocks
|
amine@330
|
633 ads.open()
|
amine@330
|
634 i = 0
|
amine@330
|
635 while True:
|
amine@330
|
636 block = ads.read()
|
amine@330
|
637 if block is None:
|
amine@330
|
638 break
|
amine@330
|
639 i += 1
|
amine@330
|
640
|
amine@330
|
641 ads.rewind()
|
amine@330
|
642
|
amine@330
|
643 # Build a BufferAudioSource
|
amine@330
|
644 audio_source = BufferAudioSource(
|
amine@330
|
645 self.signal, ads.sampling_rate, ads.sample_width, ads.channels
|
amine@330
|
646 )
|
amine@330
|
647 audio_source.open()
|
amine@330
|
648
|
amine@330
|
649 # Compare all blocks read from OverlapADS to those read
|
amine@330
|
650 # from an audio source with a manual position setting
|
amine@330
|
651 for j in range(i):
|
amine@330
|
652
|
amine@330
|
653 tmp = audio_source.read(block_size)
|
amine@330
|
654
|
amine@330
|
655 block = ads.read()
|
amine@330
|
656
|
amine@330
|
657 self.assertEqual(
|
amine@330
|
658 block,
|
amine@330
|
659 tmp,
|
amine@330
|
660 "Unexpected block '{}' (N={}) read from OverlapADS".format(
|
amine@330
|
661 block, i
|
amine@330
|
662 ),
|
amine@330
|
663 )
|
amine@330
|
664 audio_source.position = (j + 1) * hop_size
|
amine@330
|
665
|
amine@330
|
666 ads.close()
|
amine@330
|
667 audio_source.close()
|
amine@330
|
668
|
amine@330
|
669
|
amine@330
|
670 class TestADSFactoryAlias(unittest.TestCase):
|
amine@330
|
671 def setUp(self):
|
amine@330
|
672 self.signal = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"
|
amine@330
|
673
|
amine@330
|
674 def test_sampling_rate_alias(self):
|
amine@330
|
675 ads = ADSFactory.ads(
|
amine@330
|
676 data_buffer=self.signal,
|
amine@330
|
677 sr=16,
|
amine@330
|
678 sample_width=2,
|
amine@330
|
679 channels=1,
|
amine@330
|
680 block_dur=0.5,
|
amine@330
|
681 )
|
amine@330
|
682 srate = ads.sampling_rate
|
amine@330
|
683 self.assertEqual(
|
amine@330
|
684 srate,
|
amine@330
|
685 16,
|
amine@330
|
686 "Wrong sampling rate, expected: 16000, found: {0}".format(srate),
|
amine@330
|
687 )
|
amine@330
|
688
|
amine@330
|
689 def test_sampling_rate_duplicate(self):
|
amine@330
|
690 func = partial(
|
amine@330
|
691 ADSFactory.ads,
|
amine@330
|
692 data_buffer=self.signal,
|
amine@330
|
693 sr=16,
|
amine@330
|
694 sampling_rate=16,
|
amine@330
|
695 sample_width=2,
|
amine@330
|
696 channels=1,
|
amine@330
|
697 )
|
amine@330
|
698 self.assertRaises(DuplicateArgument, func)
|
amine@330
|
699
|
amine@330
|
700 def test_sample_width_alias(self):
|
amine@330
|
701 ads = ADSFactory.ads(
|
amine@330
|
702 data_buffer=self.signal,
|
amine@330
|
703 sampling_rate=16,
|
amine@330
|
704 sw=2,
|
amine@330
|
705 channels=1,
|
amine@330
|
706 block_dur=0.5,
|
amine@330
|
707 )
|
amine@330
|
708 swidth = ads.sample_width
|
amine@330
|
709 self.assertEqual(
|
amine@330
|
710 swidth,
|
amine@330
|
711 2,
|
amine@330
|
712 "Wrong sample width, expected: 2, found: {0}".format(swidth),
|
amine@330
|
713 )
|
amine@330
|
714
|
amine@330
|
715 def test_sample_width_duplicate(self):
|
amine@330
|
716 func = partial(
|
amine@330
|
717 ADSFactory.ads,
|
amine@330
|
718 data_buffer=self.signal,
|
amine@330
|
719 sampling_rate=16,
|
amine@330
|
720 sw=2,
|
amine@330
|
721 sample_width=2,
|
amine@330
|
722 channels=1,
|
amine@330
|
723 )
|
amine@330
|
724 self.assertRaises(DuplicateArgument, func)
|
amine@330
|
725
|
amine@330
|
726 def test_channels_alias(self):
|
amine@330
|
727 ads = ADSFactory.ads(
|
amine@330
|
728 data_buffer=self.signal,
|
amine@330
|
729 sampling_rate=16,
|
amine@330
|
730 sample_width=2,
|
amine@330
|
731 ch=1,
|
amine@330
|
732 block_dur=4,
|
amine@330
|
733 )
|
amine@330
|
734 channels = ads.channels
|
amine@330
|
735 self.assertEqual(
|
amine@330
|
736 channels,
|
amine@330
|
737 1,
|
amine@330
|
738 "Wrong number of channels, expected: 1, found: {0}".format(
|
amine@330
|
739 channels
|
amine@330
|
740 ),
|
amine@330
|
741 )
|
amine@330
|
742
|
amine@330
|
743 def test_channels_duplicate(self):
|
amine@330
|
744 func = partial(
|
amine@330
|
745 ADSFactory.ads,
|
amine@330
|
746 data_buffer=self.signal,
|
amine@330
|
747 sampling_rate=16,
|
amine@330
|
748 sample_width=2,
|
amine@330
|
749 ch=1,
|
amine@330
|
750 channels=1,
|
amine@330
|
751 )
|
amine@330
|
752 self.assertRaises(DuplicateArgument, func)
|
amine@330
|
753
|
amine@330
|
754 def test_block_size_alias(self):
|
amine@330
|
755 ads = ADSFactory.ads(
|
amine@330
|
756 data_buffer=self.signal,
|
amine@330
|
757 sampling_rate=16,
|
amine@330
|
758 sample_width=2,
|
amine@330
|
759 channels=1,
|
amine@330
|
760 bs=8,
|
amine@330
|
761 )
|
amine@330
|
762 size = ads.block_size
|
amine@330
|
763 self.assertEqual(
|
amine@330
|
764 size,
|
amine@330
|
765 8,
|
amine@330
|
766 "Wrong block_size using bs alias, expected: 8, found: {0}".format(
|
amine@330
|
767 size
|
amine@330
|
768 ),
|
amine@330
|
769 )
|
amine@330
|
770
|
amine@330
|
771 def test_block_size_duplicate(self):
|
amine@330
|
772 func = partial(
|
amine@330
|
773 ADSFactory.ads,
|
amine@330
|
774 data_buffer=self.signal,
|
amine@330
|
775 sampling_rate=16,
|
amine@330
|
776 sample_width=2,
|
amine@330
|
777 channels=1,
|
amine@330
|
778 bs=4,
|
amine@330
|
779 block_size=4,
|
amine@330
|
780 )
|
amine@330
|
781 self.assertRaises(DuplicateArgument, func)
|
amine@330
|
782
|
amine@330
|
783 def test_block_duration_alias(self):
|
amine@330
|
784 ads = ADSFactory.ads(
|
amine@330
|
785 data_buffer=self.signal,
|
amine@330
|
786 sampling_rate=16,
|
amine@330
|
787 sample_width=2,
|
amine@330
|
788 channels=1,
|
amine@330
|
789 bd=0.75,
|
amine@330
|
790 )
|
amine@330
|
791 # 0.75 ms = 0.75 * 16 = 12
|
amine@330
|
792 size = ads.block_size
|
amine@330
|
793 err_msg = "Wrong block_size set with a block_dur alias 'bd', "
|
amine@330
|
794 err_msg += "expected: 8, found: {0}"
|
amine@330
|
795 self.assertEqual(
|
amine@330
|
796 size, 12, err_msg.format(size),
|
amine@330
|
797 )
|
amine@330
|
798
|
amine@330
|
799 def test_block_duration_duplicate(self):
|
amine@330
|
800 func = partial(
|
amine@330
|
801 ADSFactory.ads,
|
amine@330
|
802 data_buffer=self.signal,
|
amine@330
|
803 sampling_rate=16,
|
amine@330
|
804 sample_width=2,
|
amine@330
|
805 channels=1,
|
amine@330
|
806 bd=4,
|
amine@330
|
807 block_dur=4,
|
amine@330
|
808 )
|
amine@330
|
809 self.assertRaises(DuplicateArgument, func)
|
amine@330
|
810
|
amine@330
|
811 def test_block_size_duration_duplicate(self):
|
amine@330
|
812 func = partial(
|
amine@330
|
813 ADSFactory.ads,
|
amine@330
|
814 data_buffer=self.signal,
|
amine@330
|
815 sampling_rate=16,
|
amine@330
|
816 sample_width=2,
|
amine@330
|
817 channels=1,
|
amine@330
|
818 bd=4,
|
amine@330
|
819 bs=12,
|
amine@330
|
820 )
|
amine@330
|
821 self.assertRaises(DuplicateArgument, func)
|
amine@330
|
822
|
amine@330
|
823 def test_hop_duration_alias(self):
|
amine@330
|
824
|
amine@330
|
825 ads = ADSFactory.ads(
|
amine@330
|
826 data_buffer=self.signal,
|
amine@330
|
827 sampling_rate=16,
|
amine@330
|
828 sample_width=2,
|
amine@330
|
829 channels=1,
|
amine@330
|
830 bd=0.75,
|
amine@330
|
831 hd=0.5,
|
amine@330
|
832 )
|
amine@330
|
833 size = ads.hop_size
|
amine@330
|
834 self.assertEqual(
|
amine@330
|
835 size,
|
amine@330
|
836 8,
|
amine@330
|
837 "Wrong block_size using bs alias, expected: 8, found: {0}".format(
|
amine@330
|
838 size
|
amine@330
|
839 ),
|
amine@330
|
840 )
|
amine@330
|
841
|
amine@330
|
842 def test_hop_duration_duplicate(self):
|
amine@330
|
843
|
amine@330
|
844 func = partial(
|
amine@330
|
845 ADSFactory.ads,
|
amine@330
|
846 data_buffer=self.signal,
|
amine@330
|
847 sampling_rate=16,
|
amine@330
|
848 sample_width=2,
|
amine@330
|
849 channels=1,
|
amine@330
|
850 bd=0.75,
|
amine@330
|
851 hd=0.5,
|
amine@330
|
852 hop_dur=0.5,
|
amine@330
|
853 )
|
amine@330
|
854 self.assertRaises(DuplicateArgument, func)
|
amine@330
|
855
|
amine@330
|
856 def test_hop_size_duration_duplicate(self):
|
amine@330
|
857 func = partial(
|
amine@330
|
858 ADSFactory.ads,
|
amine@330
|
859 data_buffer=self.signal,
|
amine@330
|
860 sampling_rate=16,
|
amine@330
|
861 sample_width=2,
|
amine@330
|
862 channels=1,
|
amine@330
|
863 bs=8,
|
amine@330
|
864 hs=4,
|
amine@330
|
865 hd=1,
|
amine@330
|
866 )
|
amine@330
|
867 self.assertRaises(DuplicateArgument, func)
|
amine@330
|
868
|
amine@330
|
869 def test_hop_size_greater_than_block_size(self):
|
amine@330
|
870 func = partial(
|
amine@330
|
871 ADSFactory.ads,
|
amine@330
|
872 data_buffer=self.signal,
|
amine@330
|
873 sampling_rate=16,
|
amine@330
|
874 sample_width=2,
|
amine@330
|
875 channels=1,
|
amine@330
|
876 bs=4,
|
amine@330
|
877 hs=8,
|
amine@330
|
878 )
|
amine@330
|
879 self.assertRaises(ValueError, func)
|
amine@330
|
880
|
amine@330
|
881 def test_filename_duplicate(self):
|
amine@330
|
882
|
amine@330
|
883 func = partial(
|
amine@330
|
884 ADSFactory.ads,
|
amine@330
|
885 fn=dataset.one_to_six_arabic_16000_mono_bc_noise,
|
amine@330
|
886 filename=dataset.one_to_six_arabic_16000_mono_bc_noise,
|
amine@330
|
887 )
|
amine@330
|
888 self.assertRaises(DuplicateArgument, func)
|
amine@330
|
889
|
amine@330
|
890 def test_data_buffer_duplicate(self):
|
amine@330
|
891 func = partial(
|
amine@330
|
892 ADSFactory.ads,
|
amine@330
|
893 data_buffer=self.signal,
|
amine@330
|
894 db=self.signal,
|
amine@330
|
895 sampling_rate=16,
|
amine@330
|
896 sample_width=2,
|
amine@330
|
897 channels=1,
|
amine@330
|
898 )
|
amine@330
|
899 self.assertRaises(DuplicateArgument, func)
|
amine@330
|
900
|
amine@330
|
901 def test_max_time_alias(self):
|
amine@330
|
902 ads = ADSFactory.ads(
|
amine@330
|
903 data_buffer=self.signal,
|
amine@330
|
904 sampling_rate=16,
|
amine@330
|
905 sample_width=2,
|
amine@330
|
906 channels=1,
|
amine@330
|
907 mt=10,
|
amine@330
|
908 block_dur=0.5,
|
amine@330
|
909 )
|
amine@330
|
910 self.assertEqual(
|
amine@330
|
911 ads.max_read,
|
amine@330
|
912 10,
|
amine@330
|
913 "Wrong AudioDataSource.max_read, expected: 10, found: {}".format(
|
amine@330
|
914 ads.max_read
|
amine@330
|
915 ),
|
amine@330
|
916 )
|
amine@330
|
917
|
amine@330
|
918 def test_max_time_duplicate(self):
|
amine@330
|
919 func = partial(
|
amine@330
|
920 ADSFactory.ads,
|
amine@330
|
921 data_buffer=self.signal,
|
amine@330
|
922 sampling_rate=16,
|
amine@330
|
923 sample_width=2,
|
amine@330
|
924 channels=1,
|
amine@330
|
925 mt=True,
|
amine@330
|
926 max_time=True,
|
amine@330
|
927 )
|
amine@330
|
928
|
amine@330
|
929 self.assertRaises(DuplicateArgument, func)
|
amine@330
|
930
|
amine@330
|
931 def test_record_alias(self):
|
amine@330
|
932 ads = ADSFactory.ads(
|
amine@330
|
933 data_buffer=self.signal,
|
amine@330
|
934 sampling_rate=16,
|
amine@330
|
935 sample_width=2,
|
amine@330
|
936 channels=1,
|
amine@330
|
937 rec=True,
|
amine@330
|
938 block_dur=0.5,
|
amine@330
|
939 )
|
amine@330
|
940 self.assertTrue(
|
amine@330
|
941 ads.rewindable, "AudioDataSource.rewindable expected to be True"
|
amine@330
|
942 )
|
amine@330
|
943
|
amine@330
|
944 def test_record_duplicate(self):
|
amine@330
|
945 func = partial(
|
amine@330
|
946 ADSFactory.ads,
|
amine@330
|
947 data_buffer=self.signal,
|
amine@330
|
948 sampling_rate=16,
|
amine@330
|
949 sample_width=2,
|
amine@330
|
950 channels=1,
|
amine@330
|
951 rec=True,
|
amine@330
|
952 record=True,
|
amine@330
|
953 )
|
amine@330
|
954 self.assertRaises(DuplicateArgument, func)
|
amine@330
|
955
|
amine@330
|
956 def test_Limiter_Recorder_Overlap_Deco_rewind_and_read_alias(self):
|
amine@330
|
957
|
amine@330
|
958 # Use arbitrary valid block_size and hop_size
|
amine@330
|
959 block_size = 5
|
amine@330
|
960 hop_size = 4
|
amine@330
|
961
|
amine@330
|
962 ads = ADSFactory.ads(
|
amine@330
|
963 db=self.signal,
|
amine@330
|
964 sr=16,
|
amine@330
|
965 sw=2,
|
amine@330
|
966 ch=1,
|
amine@330
|
967 mt=0.80,
|
amine@330
|
968 bs=block_size,
|
amine@330
|
969 hs=hop_size,
|
amine@330
|
970 rec=True,
|
amine@330
|
971 )
|
amine@330
|
972
|
amine@330
|
973 # Read all available data overlapping blocks
|
amine@330
|
974 ads.open()
|
amine@330
|
975 i = 0
|
amine@330
|
976 while True:
|
amine@330
|
977 block = ads.read()
|
amine@330
|
978 if block is None:
|
amine@330
|
979 break
|
amine@330
|
980 i += 1
|
amine@330
|
981
|
amine@330
|
982 ads.rewind()
|
amine@330
|
983
|
amine@330
|
984 # Build a BufferAudioSource
|
amine@330
|
985 audio_source = BufferAudioSource(
|
amine@330
|
986 self.signal, ads.sampling_rate, ads.sample_width, ads.channels
|
amine@330
|
987 )
|
amine@330
|
988 audio_source.open()
|
amine@330
|
989
|
amine@330
|
990 # Compare all blocks read from AudioDataSource to those read
|
amine@330
|
991 # from an audio source with manual position definition
|
amine@330
|
992 for j in range(i):
|
amine@330
|
993 tmp = audio_source.read(block_size)
|
amine@330
|
994 block = ads.read()
|
amine@330
|
995 self.assertEqual(
|
amine@330
|
996 block,
|
amine@330
|
997 tmp,
|
amine@330
|
998 "Unexpected block (N={0}) read from OverlapADS".format(i),
|
amine@330
|
999 )
|
amine@330
|
1000 audio_source.position = (j + 1) * hop_size
|
amine@330
|
1001 ads.close()
|
amine@330
|
1002 audio_source.close()
|
amine@330
|
1003
|
amine@330
|
1004
|
amine@330
|
1005 def _read_all_data(reader):
|
amine@330
|
1006 blocks = []
|
amine@330
|
1007 while True:
|
amine@330
|
1008 data = reader.read()
|
amine@330
|
1009 if data is None:
|
amine@330
|
1010 break
|
amine@330
|
1011 blocks.append(data)
|
amine@330
|
1012 return b"".join(blocks)
|
amine@330
|
1013
|
amine@330
|
1014
|
amine@330
|
1015 @genty
|
amine@330
|
1016 class TestAudioReader(unittest.TestCase):
|
amine@330
|
1017
|
amine@330
|
1018 # TODO move all tests here when backward compatibility
|
amine@330
|
1019 # with ADSFactory is dropped
|
amine@330
|
1020
|
amine@330
|
1021 @genty_dataset(
|
amine@330
|
1022 mono=("mono_400", 0.5, 16000),
|
amine@330
|
1023 multichannel=("3channel_400-800-1600", 0.5, 16000 * 3),
|
amine@330
|
1024 )
|
amine@330
|
1025 def test_Limiter(self, file_id, max_read, size):
|
amine@330
|
1026 input_wav = "tests/data/test_16KHZ_{}Hz.wav".format(file_id)
|
amine@330
|
1027 input_raw = "tests/data/test_16KHZ_{}Hz.raw".format(file_id)
|
amine@330
|
1028 with open(input_raw, "rb") as fp:
|
amine@330
|
1029 expected = fp.read(size)
|
amine@330
|
1030
|
amine@330
|
1031 reader = AudioReader(input_wav, block_dur=0.1, max_read=max_read)
|
amine@330
|
1032 reader.open()
|
amine@330
|
1033 data = _read_all_data(reader)
|
amine@330
|
1034 reader.close()
|
amine@330
|
1035 self.assertEqual(data, expected)
|
amine@330
|
1036
|
amine@330
|
1037 @genty_dataset(mono=("mono_400",), multichannel=("3channel_400-800-1600",))
|
amine@330
|
1038 def test_Recorder(self, file_id):
|
amine@330
|
1039 input_wav = "tests/data/test_16KHZ_{}Hz.wav".format(file_id)
|
amine@330
|
1040 input_raw = "tests/data/test_16KHZ_{}Hz.raw".format(file_id)
|
amine@330
|
1041 with open(input_raw, "rb") as fp:
|
amine@330
|
1042 expected = fp.read()
|
amine@330
|
1043
|
amine@330
|
1044 reader = AudioReader(input_wav, block_dur=0.1, record=True)
|
amine@330
|
1045 reader.open()
|
amine@330
|
1046 data = _read_all_data(reader)
|
amine@330
|
1047 self.assertEqual(data, expected)
|
amine@330
|
1048
|
amine@330
|
1049 # rewind many times
|
amine@330
|
1050 for _ in range(3):
|
amine@330
|
1051 reader.rewind()
|
amine@330
|
1052 data = _read_all_data(reader)
|
amine@330
|
1053 self.assertEqual(data, expected)
|
amine@330
|
1054 self.assertEqual(data, reader.data)
|
amine@330
|
1055 reader.close()
|
amine@330
|
1056
|
amine@330
|
1057 @genty_dataset(mono=("mono_400",), multichannel=("3channel_400-800-1600",))
|
amine@330
|
1058 def test_Recorder_alias(self, file_id):
|
amine@330
|
1059 input_wav = "tests/data/test_16KHZ_{}Hz.wav".format(file_id)
|
amine@330
|
1060 input_raw = "tests/data/test_16KHZ_{}Hz.raw".format(file_id)
|
amine@330
|
1061 with open(input_raw, "rb") as fp:
|
amine@330
|
1062 expected = fp.read()
|
amine@330
|
1063
|
amine@330
|
1064 reader = Recorder(input_wav, block_dur=0.1)
|
amine@330
|
1065 reader.open()
|
amine@330
|
1066 data = _read_all_data(reader)
|
amine@330
|
1067 self.assertEqual(data, expected)
|
amine@330
|
1068
|
amine@330
|
1069 # rewind many times
|
amine@330
|
1070 for _ in range(3):
|
amine@330
|
1071 reader.rewind()
|
amine@330
|
1072 data = _read_all_data(reader)
|
amine@330
|
1073 self.assertEqual(data, expected)
|
amine@330
|
1074 self.assertEqual(data, reader.data)
|
amine@330
|
1075 reader.close()
|
amine@330
|
1076
|
amine@330
|
1077
|
amine@330
|
1078 if __name__ == "__main__":
|
amine@330
|
1079 unittest.main()
|