3 from numpy.testing import TestCase
4 from numpy.testing import assert_equal, assert_almost_equal
6 from aubio import fvec, fft, cvec
7 from math import pi, floor
8 from random import random
10 class aubio_fft_test_case(TestCase):
12 def test_members(self):
13 """ check members are set correctly """
16 assert_equal (f.win_s, win_s)
18 def test_output_dimensions(self):
19 """ check the dimensions of output """
21 timegrain = fvec(win_s)
23 fftgrain = f (timegrain)
25 assert_equal (fftgrain.norm.shape, (win_s/2+1,))
26 assert_equal (fftgrain.phas.shape, (win_s/2+1,))
29 """ check the transform of zeros is all zeros """
31 timegrain = fvec(win_s)
33 fftgrain = f (timegrain)
34 assert_equal ( fftgrain.norm, 0 )
36 assert_equal ( fftgrain.phas, 0 )
37 except AssertionError:
38 assert_equal (fftgrain.phas[fftgrain.phas > 0], +pi)
39 assert_equal (fftgrain.phas[fftgrain.phas < 0], -pi)
40 assert_equal (np.abs(fftgrain.phas[np.abs(fftgrain.phas) != pi]), 0)
41 self.skipTest('fft(fvec(%d)).phas != +0, ' % win_s \
42 + 'This is expected when using fftw3 on powerpc.')
44 def test_impulse(self):
45 """ check the transform of one impulse at a random place """
47 i = int(floor(random()*win_s))
48 impulse = pi * random()
50 timegrain = fvec(win_s)
51 timegrain[i] = impulse
52 fftgrain = f ( timegrain )
53 #self.plot_this ( fftgrain.phas )
54 assert_almost_equal ( fftgrain.norm, impulse, decimal = 6 )
55 assert_equal ( fftgrain.phas <= pi, True)
56 assert_equal ( fftgrain.phas >= -pi, True)
58 def test_impulse_negative(self):
59 """ check the transform of a negative impulse at a random place """
61 i = int(floor(random()*win_s))
64 timegrain = fvec(win_s)
66 timegrain[i] = impulse
67 fftgrain = f ( timegrain )
68 #self.plot_this ( fftgrain.phas )
69 assert_almost_equal ( fftgrain.norm, abs(impulse), decimal = 5 )
71 # phase can be pi or -pi, as it is not unwrapped
72 #assert_almost_equal ( abs(fftgrain.phas[1:-1]) , pi, decimal = 6 )
73 assert_almost_equal ( fftgrain.phas[0], pi, decimal = 6)
74 assert_almost_equal ( np.fmod(fftgrain.phas[-1], pi), 0, decimal = 6)
76 #assert_equal ( fftgrain.phas[1:-1] == 0, True)
77 assert_equal ( fftgrain.phas[0], 0)
78 assert_almost_equal ( np.fmod(fftgrain.phas[-1], pi), 0, decimal = 6)
79 # now check the resynthesis
80 synthgrain = f.rdo ( fftgrain )
81 #self.plot_this ( fftgrain.phas.T )
82 assert_equal ( fftgrain.phas <= pi, True)
83 assert_equal ( fftgrain.phas >= -pi, True)
84 #self.plot_this ( synthgrain - timegrain )
85 assert_almost_equal ( synthgrain, timegrain, decimal = 6 )
87 def test_impulse_at_zero(self):
88 """ check the transform of one impulse at a index 0 """
92 timegrain = fvec(win_s)
93 timegrain[0] = impulse
94 fftgrain = f ( timegrain )
95 #self.plot_this ( fftgrain.phas )
96 assert_equal ( fftgrain.phas[0], 0)
97 # could be 0 or -0 depending on fft implementation (0 for fftw3, -0 for ooura)
98 assert_almost_equal ( fftgrain.phas[1], 0)
99 assert_almost_equal ( fftgrain.norm[0], impulse, decimal = 6 )
101 def test_rdo_before_do(self):
102 """ check running fft.rdo before fft.do works """
105 fftgrain = cvec(win_s)
106 t = f.rdo( fftgrain )
107 assert_equal ( t, 0 )
109 def plot_this(self, this):
110 from pylab import plot, show
114 def test_local_fftgrain(self):
115 """ check aubio.fft() result can be accessed after deletion """
116 def compute_grain(impulse):
118 timegrain = fvec(win_s)
119 timegrain[0] = impulse
121 fftgrain = f ( timegrain )
124 fftgrain = compute_grain(impulse)
125 assert_equal ( fftgrain.phas[0], 0)
126 assert_almost_equal ( fftgrain.phas[1], 0)
127 assert_almost_equal ( fftgrain.norm[0], impulse, decimal = 6 )
129 def test_local_reconstruct(self):
130 """ check aubio.fft.rdo() result can be accessed after deletion """
131 def compute_grain(impulse):
133 timegrain = fvec(win_s)
134 timegrain[0] = impulse
136 fftgrain = f ( timegrain )
140 r = compute_grain(impulse)
141 assert_almost_equal ( r[0], impulse, decimal = 6)
142 assert_almost_equal ( r[1:], 0)
144 class aubio_fft_odd_sizes(TestCase):
146 def test_reconstruct_with_odd_size(self):
148 self.recontruct(win_s, 'odd sizes not supported')
150 def test_reconstruct_with_radix15(self):
152 self.recontruct(win_s, 'radix 15 supported')
154 def test_reconstruct_with_radix5(self):
156 self.recontruct(win_s, 'radix 5 supported')
158 def test_reconstruct_with_radix3(self):
160 self.recontruct(win_s, 'radix 3 supported')
162 def recontruct(self, win_s, skipMessage):
166 self.skipTest(skipMessage)
167 input_signal = fvec(win_s)
168 input_signal[win_s//2] = 1
170 output_signal = f.rdo(c)
171 assert_almost_equal(input_signal, output_signal)
173 class aubio_fft_wrong_params(TestCase):
175 def test_large_input_timegrain(self):
179 with self.assertRaises(ValueError):
182 def test_small_input_timegrain(self):
186 with self.assertRaises(ValueError):
189 def test_large_input_fftgrain(self):
193 with self.assertRaises(ValueError):
196 def test_small_input_fftgrain(self):
200 with self.assertRaises(ValueError):
203 def test_wrong_buf_size(self):
205 with self.assertRaises(ValueError):
208 def test_buf_size_too_small(self):
210 with self.assertRaises(RuntimeError):
213 if __name__ == '__main__':
214 from unittest import main