137eb632e3824f735d0f99e61caa37373087310d
[aubio.git] / python / tests / test_source.py
1 #! /usr/bin/env python
2
3 from numpy.testing import TestCase, assert_equal, assert_almost_equal
4 from aubio import fvec, source
5 from numpy import array
6 from utils import list_all_sounds
7 from nose2.tools import params
8
9 list_of_sounds = list_all_sounds('sounds')
10 default_test_sound = None
11 samplerates = [0, 44100, 8000, 32000]
12 hop_sizes = [512, 1024, 64]
13
14 path = None
15
16 all_params = []
17 for soundfile in list_of_sounds:
18     for hop_size in hop_sizes:
19         for samplerate in samplerates:
20             all_params.append((hop_size, samplerate, soundfile))
21
22
23 class aubio_source_test_case_base(TestCase):
24
25     def setUp(self):
26         if not len(list_of_sounds): self.skipTest('add some sound files in \'python/tests/sounds\'')
27         default_test_sound = list_of_sounds[0]
28
29 class aubio_source_test_case(aubio_source_test_case_base):
30
31     def test_close_file(self):
32         samplerate = 0 # use native samplerate
33         hop_size = 256
34         for p in list_of_sounds:
35             f = source(p, samplerate, hop_size)
36             f.close()
37
38     def test_close_file_twice(self):
39         samplerate = 0 # use native samplerate
40         hop_size = 256
41         for p in list_of_sounds:
42             f = source(p, samplerate, hop_size)
43             f.close()
44             f.close()
45
46 class aubio_source_read_test_case(aubio_source_test_case_base):
47
48     def read_from_source(self, f):
49         total_frames = 0
50         while True:
51             vec, read = f()
52             total_frames += read
53             if read < f.hop_size: break
54         result_str = "read {:.2f}s ({:d} frames in {:d} blocks at {:d}Hz) from {:s}"
55         result_params = total_frames / float(f.samplerate), total_frames, total_frames//f.hop_size, f.samplerate, f.uri
56         #print (result_str.format(*result_params))
57         return total_frames
58
59     @params(*all_params)
60     def test_samplerate_hopsize(self, hop_size, samplerate, soundfile):
61         try:
62             f = source(soundfile, samplerate, hop_size)
63         except RuntimeError as e:
64             self.skipTest('failed opening with hop_s = {:d}, samplerate = {:d} ({:s})'.format(hop_size, samplerate, str(e)))
65         assert f.samplerate != 0
66         self.read_from_source(f)
67
68     @params(*list_of_sounds)
69     def test_samplerate_none(self, p):
70         f = source(p)
71         assert f.samplerate != 0
72         self.read_from_source(f)
73
74     @params(*list_of_sounds)
75     def test_samplerate_0(self, p):
76         f = source(p, 0)
77         assert f.samplerate != 0
78         self.read_from_source(f)
79
80     @params(*list_of_sounds)
81     def test_zero_hop_size(self, p):
82         f = source(p, 0, 0)
83         assert f.samplerate != 0
84         assert f.hop_size != 0
85         self.read_from_source(f)
86
87     @params(*list_of_sounds)
88     def test_seek_to_half(self, p):
89         from random import randint
90         f = source(p, 0, 0)
91         assert f.samplerate != 0
92         assert f.hop_size != 0
93         a = self.read_from_source(f)
94         c = randint(0, a)
95         f.seek(c)
96         b = self.read_from_source(f)
97         assert a == b + c
98
99     @params(*list_of_sounds)
100     def test_duration(self, p):
101         total_frames = 0
102         f = source(p)
103         duration = f.duration
104         while True:
105             vec, read = f()
106             total_frames += read
107             if read < f.hop_size: break
108         self.assertEqual(duration, total_frames)
109
110
111 class aubio_source_test_wrong_params(TestCase):
112
113     def test_wrong_file(self):
114         with self.assertRaises(RuntimeError):
115             f = source('path_to/unexisting file.mp3')
116
117 class aubio_source_test_wrong_params(aubio_source_test_case_base):
118
119     def test_wrong_samplerate(self):
120         with self.assertRaises(ValueError):
121             f = source(default_test_sound, -1)
122
123     def test_wrong_hop_size(self):
124         with self.assertRaises(ValueError):
125             f = source(default_test_sound, 0, -1)
126
127     def test_wrong_channels(self):
128         with self.assertRaises(ValueError):
129             f = source(default_test_sound, 0, 0, -1)
130
131     def test_wrong_seek(self):
132         f = source(default_test_sound)
133         with self.assertRaises(ValueError):
134             f.seek(-1)
135
136     def test_wrong_seek_too_large(self):
137         f = source(default_test_sound)
138         try:
139             with self.assertRaises(ValueError):
140                 f.seek(f.duration + f.samplerate * 10)
141         except AssertionError as e:
142             self.skipTest('seeking after end of stream failed raising ValueError')
143
144 class aubio_source_readmulti_test_case(aubio_source_read_test_case):
145
146     def read_from_source(self, f):
147         total_frames = 0
148         while True:
149             vec, read = f.do_multi()
150             total_frames += read
151             if read < f.hop_size: break
152         result_str = "read {:.2f}s ({:d} frames in {:d} channels and {:d} blocks at {:d}Hz) from {:s}"
153         result_params = total_frames / float(f.samplerate), total_frames, f.channels, int(total_frames/f.hop_size), f.samplerate, f.uri
154         #print (result_str.format(*result_params))
155         return total_frames
156
157 if __name__ == '__main__':
158     from nose2 import main
159     main()