1#! /usr/bin/env python 2 3from numpy.testing import TestCase, assert_equal, assert_array_less 4from _tools import parametrize 5from aubio import fvec, cvec, pvoc, float_type 6import numpy as np 7 8if float_type == 'float32': 9 max_sq_error = 1.e-12 10else: 11 max_sq_error = 1.e-29 12 13def create_sine(hop_s, freq, samplerate): 14 t = np.arange(hop_s).astype(float_type) 15 return np.sin( 2. * np.pi * freq * t / float(samplerate)) 16 17def create_noise(hop_s): 18 return np.random.rand(hop_s).astype(float_type) * 2. - 1. 19 20class Test_aubio_pvoc_test_case(object): 21 """ pvoc object test case """ 22 23 def test_members_automatic_sizes_default(self): 24 """ check object creation with default parameters """ 25 f = pvoc() 26 assert_equal ([f.win_s, f.hop_s], [1024, 512]) 27 28 def test_members_unnamed_params(self): 29 """ check object creation with unnamed parameters """ 30 f = pvoc(2048, 128) 31 assert_equal ([f.win_s, f.hop_s], [2048, 128]) 32 33 def test_members_named_params(self): 34 """ check object creation with named parameters """ 35 f = pvoc(hop_s = 128, win_s = 2048) 36 assert_equal ([f.win_s, f.hop_s], [2048, 128]) 37 38 def test_zeros(self): 39 """ check the resynthesis of zeros gives zeros """ 40 win_s, hop_s = 1024, 256 41 f = pvoc (win_s, hop_s) 42 t = fvec (hop_s) 43 for _ in range( int ( 4 * win_s / hop_s ) ): 44 s = f(t) 45 r = f.rdo(s) 46 assert_equal ( t, 0.) 47 assert_equal ( s.norm, 0.) 48 try: 49 assert_equal ( s.phas, 0 ) 50 except AssertionError: 51 assert_equal (s.phas[s.phas > 0], +np.pi) 52 assert_equal (s.phas[s.phas < 0], -np.pi) 53 assert_equal (np.abs(s.phas[np.abs(s.phas) != np.pi]), 0) 54 self.skipTest('pvoc(fvec(%d)).phas != +0, ' % win_s \ 55 + 'This is expected when using fftw3 on powerpc.') 56 assert_equal ( r, 0.) 57 58 def test_no_overlap(self): 59 win_s, hop_s = 1024, 1024 60 f = pvoc (win_s, hop_s) 61 t = fvec (hop_s) 62 for _ in range(4): 63 s = f(t) 64 r = f.rdo(s) 65 assert_equal ( t, 0.) 66 67 resynth_noise_args = "hop_s, ratio" 68 resynth_noise_values = [ 69 ( 256, 8), 70 ( 256, 4), 71 ( 256, 2), 72 ( 512, 8), 73 ( 512, 4), 74 ( 512, 2), 75 #( 129, 2), 76 #( 320, 4), 77 #( 13, 8), 78 (1024, 8), 79 (1024, 4), 80 (1024, 2), 81 (2048, 8), 82 (2048, 4), 83 (2048, 2), 84 (4096, 8), 85 (4096, 4), 86 (4096, 2), 87 (8192, 8), 88 (8192, 4), 89 (8192, 2), 90 ] 91 92 @parametrize(resynth_noise_args, resynth_noise_values) 93 def test_resynth_steps_noise(self, hop_s, ratio): 94 """ check the resynthesis of a random signal is correct """ 95 sigin = create_noise(hop_s) 96 self.reconstruction(sigin, hop_s, ratio) 97 98 resynth_sine_args = "samplerate, hop_s, ratio, freq" 99 resynth_sine_values = [ 100 (44100, 256, 8, 441), 101 (44100, 256, 4, 1203), 102 (44100, 256, 2, 3045), 103 (44100, 512, 8, 445), 104 (44100, 512, 4, 445), 105 (44100, 512, 2, 445), 106 (44100, 1024, 8, 445), 107 (44100, 1024, 4, 445), 108 (44100, 1024, 2, 445), 109 ( 8000, 1024, 2, 445), 110 (22050, 1024, 2, 445), 111 (22050, 256, 8, 445), 112 (96000, 1024, 8, 47000), 113 (96000, 1024, 8, 20), 114 ] 115 116 @parametrize(resynth_sine_args, resynth_sine_values) 117 def test_resynth_steps_sine(self, samplerate, hop_s, ratio, freq): 118 """ check the resynthesis of a sine is correct """ 119 sigin = create_sine(hop_s, freq, samplerate) 120 self.reconstruction(sigin, hop_s, ratio) 121 122 def reconstruction(self, sigin, hop_s, ratio): 123 buf_s = hop_s * ratio 124 f = pvoc(buf_s, hop_s) 125 zeros = fvec(hop_s) 126 r2 = f.rdo( f(sigin) ) 127 for _ in range(1, ratio): 128 r2 = f.rdo( f(zeros) ) 129 # compute square errors 130 sq_error = (r2 - sigin)**2 131 # make sure all square errors are less than desired precision 132 assert_array_less(sq_error, max_sq_error) 133 134class aubio_pvoc_strange_params(TestCase): 135 136 def test_win_size_short(self): 137 with self.assertRaises(RuntimeError): 138 pvoc(1, 1) 139 140 def test_hop_size_long(self): 141 with self.assertRaises(RuntimeError): 142 pvoc(1024, 1025) 143 144 def test_large_input_timegrain(self): 145 win_s = 1024 146 f = pvoc(win_s) 147 t = fvec(win_s + 1) 148 with self.assertRaises(ValueError): 149 f(t) 150 151 def test_small_input_timegrain(self): 152 win_s = 1024 153 f = pvoc(win_s) 154 t = fvec(1) 155 with self.assertRaises(ValueError): 156 f(t) 157 158 def test_large_input_fftgrain(self): 159 win_s = 1024 160 f = pvoc(win_s) 161 s = cvec(win_s + 5) 162 with self.assertRaises(ValueError): 163 f.rdo(s) 164 165 def test_small_input_fftgrain(self): 166 win_s = 1024 167 f = pvoc(win_s) 168 s = cvec(16) 169 with self.assertRaises(ValueError): 170 f.rdo(s) 171 172class aubio_pvoc_wrong_params(TestCase): 173 174 def test_wrong_buf_size(self): 175 win_s = -1 176 with self.assertRaises(ValueError): 177 pvoc(win_s) 178 179 def test_buf_size_too_small(self): 180 win_s = 1 181 with self.assertRaises(RuntimeError): 182 pvoc(win_s) 183 184 def test_hop_size_negative(self): 185 win_s = 512 186 hop_s = -2 187 with self.assertRaises(ValueError): 188 pvoc(win_s, hop_s) 189 190 def test_hop_size_too_small(self): 191 win_s = 1 192 hop_s = 1 193 with self.assertRaises(RuntimeError): 194 pvoc(win_s, hop_s) 195 196 def test_buf_size_not_power_of_two(self): 197 win_s = 320 198 hop_s = win_s // 2 199 try: 200 with self.assertRaises(RuntimeError): 201 pvoc(win_s, hop_s) 202 except AssertionError: 203 # when compiled with fftw3, aubio supports non power of two fft sizes 204 self.skipTest('creating aubio.pvoc with size %d did not fail' % win_s) 205 206if __name__ == '__main__': 207 from unittest import main 208 main() 209