3 from unittest import main
4 from numpy.testing import TestCase
5 from numpy.testing import assert_equal, assert_almost_equal
7 from aubio import fvec, fft, cvec
8 from math import pi, floor
9 from random import random
11 class aubio_fft_test_case(TestCase):
13 def test_members(self):
14 """ check members are set correctly """
17 assert_equal (f.win_s, win_s)
19 def test_output_dimensions(self):
20 """ check the dimensions of output """
22 timegrain = fvec(win_s)
24 fftgrain = f (timegrain)
26 assert_equal (fftgrain.norm.shape, (win_s/2+1,))
27 assert_equal (fftgrain.phas.shape, (win_s/2+1,))
30 """ check the transform of zeros is all zeros """
32 timegrain = fvec(win_s)
34 fftgrain = f (timegrain)
35 assert_equal ( fftgrain.norm, 0 )
37 assert_equal ( fftgrain.phas, 0 )
38 except AssertionError:
39 assert_equal (fftgrain.phas[fftgrain.phas > 0], +pi)
40 assert_equal (fftgrain.phas[fftgrain.phas < 0], -pi)
41 assert_equal (np.abs(fftgrain.phas[np.abs(fftgrain.phas) != pi]), 0)
42 self.skipTest('fft(fvec(%d)).phas != +0, ' % win_s \
43 + 'This is expected when using fftw3 on powerpc.')
45 def test_impulse(self):
46 """ check the transform of one impulse at a random place """
48 i = int(floor(random()*win_s))
49 impulse = pi * random()
51 timegrain = fvec(win_s)
52 timegrain[i] = impulse
53 fftgrain = f ( timegrain )
54 #self.plot_this ( fftgrain.phas )
55 assert_almost_equal ( fftgrain.norm, impulse, decimal = 6 )
56 assert_equal ( fftgrain.phas <= pi, True)
57 assert_equal ( fftgrain.phas >= -pi, True)
59 def test_impulse_negative(self):
60 """ check the transform of a negative impulse at a random place """
62 i = int(floor(random()*win_s))
65 timegrain = fvec(win_s)
67 timegrain[i] = impulse
68 fftgrain = f ( timegrain )
69 #self.plot_this ( fftgrain.phas )
70 assert_almost_equal ( fftgrain.norm, abs(impulse), decimal = 5 )
72 # phase can be pi or -pi, as it is not unwrapped
73 #assert_almost_equal ( abs(fftgrain.phas[1:-1]) , pi, decimal = 6 )
74 assert_almost_equal ( fftgrain.phas[0], pi, decimal = 6)
75 assert_almost_equal ( np.fmod(fftgrain.phas[-1], pi), 0, decimal = 6)
77 #assert_equal ( fftgrain.phas[1:-1] == 0, True)
78 assert_equal ( fftgrain.phas[0], 0)
79 assert_almost_equal ( np.fmod(fftgrain.phas[-1], pi), 0, decimal = 6)
80 # now check the resynthesis
81 synthgrain = f.rdo ( fftgrain )
82 #self.plot_this ( fftgrain.phas.T )
83 assert_equal ( fftgrain.phas <= pi, True)
84 assert_equal ( fftgrain.phas >= -pi, True)
85 #self.plot_this ( synthgrain - timegrain )
86 assert_almost_equal ( synthgrain, timegrain, decimal = 6 )
88 def test_impulse_at_zero(self):
89 """ check the transform of one impulse at a index 0 """
93 timegrain = fvec(win_s)
94 timegrain[0] = impulse
95 fftgrain = f ( timegrain )
96 #self.plot_this ( fftgrain.phas )
97 assert_equal ( fftgrain.phas[0], 0)
98 # could be 0 or -0 depending on fft implementation (0 for fftw3, -0 for ooura)
99 assert_almost_equal ( fftgrain.phas[1], 0)
100 assert_almost_equal ( fftgrain.norm[0], impulse, decimal = 6 )
102 def test_rdo_before_do(self):
103 """ check running fft.rdo before fft.do works """
106 fftgrain = cvec(win_s)
107 t = f.rdo( fftgrain )
108 assert_equal ( t, 0 )
110 def plot_this(self, this):
111 from pylab import plot, show
115 def test_local_fftgrain(self):
116 """ check aubio.fft() result can be accessed after deletion """
117 def compute_grain(impulse):
119 timegrain = fvec(win_s)
120 timegrain[0] = impulse
122 fftgrain = f ( timegrain )
125 fftgrain = compute_grain(impulse)
126 assert_equal ( fftgrain.phas[0], 0)
127 assert_almost_equal ( fftgrain.phas[1], 0)
128 assert_almost_equal ( fftgrain.norm[0], impulse, decimal = 6 )
130 def test_local_reconstruct(self):
131 """ check aubio.fft.rdo() result can be accessed after deletion """
132 def compute_grain(impulse):
134 timegrain = fvec(win_s)
135 timegrain[0] = impulse
137 fftgrain = f ( timegrain )
141 r = compute_grain(impulse)
142 assert_almost_equal ( r[0], impulse, decimal = 6)
143 assert_almost_equal ( r[1:], 0)
145 class aubio_fft_odd_sizes(TestCase):
147 def test_reconstruct_with_odd_size(self):
149 self.recontruct(win_s, 'odd sizes not supported')
151 def test_reconstruct_with_radix15(self):
153 self.recontruct(win_s, 'radix 15 supported')
155 def test_reconstruct_with_radix5(self):
157 self.recontruct(win_s, 'radix 5 supported')
159 def test_reconstruct_with_radix3(self):
161 self.recontruct(win_s, 'radix 3 supported')
163 def recontruct(self, win_s, skipMessage):
167 self.skipTest(skipMessage)
168 input_signal = fvec(win_s)
169 input_signal[win_s//2] = 1
171 output_signal = f.rdo(c)
172 assert_almost_equal(input_signal, output_signal)
174 class aubio_fft_wrong_params(TestCase):
176 def test_large_input_timegrain(self):
180 with self.assertRaises(ValueError):
183 def test_small_input_timegrain(self):
187 with self.assertRaises(ValueError):
190 def test_large_input_fftgrain(self):
194 with self.assertRaises(ValueError):
197 def test_small_input_fftgrain(self):
201 with self.assertRaises(ValueError):
204 def test_wrong_buf_size(self):
206 with self.assertRaises(ValueError):
209 def test_buf_size_too_small(self):
211 with self.assertRaises(RuntimeError):
214 if __name__ == '__main__':