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