source: python/tests/test_fft.py @ fcef3fd

feature/autosinkfeature/constantqfeature/pitchshiftfeature/pydocstringsfeature/timestretchpitchshiftsamplertimestretchyinfft+
Last change on this file since fcef3fd was fcef3fd, checked in by Paul Brossier <piem@piem.org>, 3 years ago

python/tests/test_fft.py: more tests

  • Property mode set to 100755
File size: 6.1 KB
Line 
1#! /usr/bin/env python
2
3from numpy.testing import TestCase
4from numpy.testing import assert_equal, assert_almost_equal
5from aubio import fvec, fft, cvec
6from math import pi
7
8class aubio_fft_test_case(TestCase):
9
10    def test_members(self):
11        """ check members are set correctly """
12        win_s = 2048
13        f = fft(win_s)
14        assert_equal (f.win_s, win_s)
15
16    def test_output_dimensions(self):
17        """ check the dimensions of output """
18        win_s = 1024
19        timegrain = fvec(win_s)
20        f = fft (win_s)
21        fftgrain = f (timegrain)
22        del f
23        assert_equal (fftgrain.norm.shape, (win_s/2+1,))
24        assert_equal (fftgrain.phas.shape, (win_s/2+1,))
25
26    def test_zeros(self):
27        """ check the transform of zeros is all zeros """
28        win_s = 512
29        timegrain = fvec(win_s)
30        f = fft (win_s)
31        fftgrain = f (timegrain)
32        assert_equal ( fftgrain.norm, 0 )
33        assert_equal ( fftgrain.phas, 0 )
34
35    def test_impulse(self):
36        """ check the transform of one impulse at a random place """
37        from random import random
38        from math import floor
39        win_s = 256
40        i = floor(random()*win_s)
41        impulse = pi * random()
42        f = fft(win_s)
43        timegrain = fvec(win_s)
44        timegrain[i] = impulse
45        fftgrain = f ( timegrain )
46        #self.plot_this ( fftgrain.phas )
47        assert_almost_equal ( fftgrain.norm, impulse, decimal = 6 )
48        assert_equal ( fftgrain.phas <= pi, True)
49        assert_equal ( fftgrain.phas >= -pi, True)
50
51    def test_impulse_negative(self):
52        """ check the transform of one impulse at a random place """
53        from random import random
54        from math import floor
55        win_s = 256
56        i = 0
57        impulse = -10.
58        f = fft(win_s)
59        timegrain = fvec(win_s)
60        timegrain[i] = impulse
61        fftgrain = f ( timegrain )
62        #self.plot_this ( fftgrain.phas )
63        assert_almost_equal ( fftgrain.norm, abs(impulse), decimal = 6 )
64        if impulse < 0:
65            # phase can be pi or -pi, as it is not unwrapped
66            assert_almost_equal ( abs(fftgrain.phas[1:-1]) , pi, decimal = 6 )
67            assert_almost_equal ( fftgrain.phas[0], pi, decimal = 6)
68            assert_almost_equal ( fftgrain.phas[-1], pi, decimal = 6)
69        else:
70            assert_equal ( fftgrain.phas[1:-1] == 0, True)
71            assert_equal ( fftgrain.phas[0] == 0, True)
72            assert_equal ( fftgrain.phas[-1] == 0, True)
73        # now check the resynthesis
74        synthgrain = f.rdo ( fftgrain )
75        #self.plot_this ( fftgrain.phas.T )
76        assert_equal ( fftgrain.phas <= pi, True)
77        assert_equal ( fftgrain.phas >= -pi, True)
78        #self.plot_this ( synthgrain - timegrain )
79        assert_almost_equal ( synthgrain, timegrain, decimal = 6 )
80
81    def test_impulse_at_zero(self):
82        """ check the transform of one impulse at a index 0 """
83        win_s = 1024
84        impulse = pi
85        f = fft(win_s)
86        timegrain = fvec(win_s)
87        timegrain[0] = impulse
88        fftgrain = f ( timegrain )
89        #self.plot_this ( fftgrain.phas )
90        assert_equal ( fftgrain.phas[0], 0)
91        # could be 0 or -0 depending on fft implementation (0 for fftw3, -0 for ooura)
92        assert_almost_equal ( fftgrain.phas[1], 0)
93        assert_almost_equal ( fftgrain.norm[0], impulse, decimal = 6 )
94
95    def test_rdo_before_do(self):
96        """ check running fft.rdo before fft.do works """
97        win_s = 1024
98        impulse = pi
99        f = fft(win_s)
100        fftgrain = cvec(win_s)
101        t = f.rdo( fftgrain )
102        assert_equal ( t, 0 )
103
104    def plot_this(self, this):
105        from pylab import plot, show
106        plot ( this )
107        show ()
108
109    def test_local_fftgrain(self):
110        """ check aubio.fft() result can be accessed after deletion """
111        def compute_grain(impulse):
112            win_s = 1024
113            timegrain = fvec(win_s)
114            timegrain[0] = impulse
115            f = fft(win_s)
116            fftgrain = f ( timegrain )
117            return fftgrain
118        impulse = pi
119        fftgrain = compute_grain(impulse)
120        assert_equal ( fftgrain.phas[0], 0)
121        assert_almost_equal ( fftgrain.phas[1], 0)
122        assert_almost_equal ( fftgrain.norm[0], impulse, decimal = 6 )
123
124    def test_local_reconstruct(self):
125        """ check aubio.fft.rdo() result can be accessed after deletion """
126        def compute_grain(impulse):
127            win_s = 1024
128            timegrain = fvec(win_s)
129            timegrain[0] = impulse
130            f = fft(win_s)
131            fftgrain = f ( timegrain )
132            r = f.rdo(fftgrain)
133            return r
134        impulse = pi
135        r = compute_grain(impulse)
136        assert_almost_equal ( r[0], impulse, decimal = 6)
137        assert_almost_equal ( r[1:], 0)
138
139    def test_large_input_timegrain(self):
140        win_s = 1024
141        f = fft(win_s)
142        t = fvec(win_s + 1)
143        with self.assertRaises(ValueError):
144            f(t)
145
146    def test_small_input_timegrain(self):
147        win_s = 1024
148        f = fft(win_s)
149        t = fvec(1)
150        with self.assertRaises(ValueError):
151            f(t)
152
153    def test_large_input_fftgrain(self):
154        win_s = 1024
155        f = fft(win_s)
156        s = cvec(win_s + 5)
157        with self.assertRaises(ValueError):
158            f.rdo(s)
159
160    def test_small_input_fftgrain(self):
161        win_s = 1024
162        f = fft(win_s)
163        s = cvec(16)
164        with self.assertRaises(ValueError):
165            f.rdo(s)
166
167class aubio_fft_wrong_params(TestCase):
168
169    def test_wrong_buf_size(self):
170        win_s = -1
171        with self.assertRaises(ValueError):
172            fft(win_s)
173
174    def test_buf_size_not_power_of_two(self):
175        # when compiled with fftw3, aubio supports non power of two fft sizes
176        win_s = 320
177        try:
178            with self.assertRaises(RuntimeError):
179                fft(win_s)
180        except AssertionError as e:
181            self.skipTest('creating aubio.fft with size %d did not fail' % win_s)
182
183    def test_buf_size_too_small(self):
184        win_s = 1
185        with self.assertRaises(RuntimeError):
186            fft(win_s)
187
188if __name__ == '__main__':
189    from nose2 import main
190    main()
Note: See TracBrowser for help on using the repository browser.