source: python/tests/test_fft.py @ 8db0930

feature/crepe
Last change on this file since 8db0930 was a95b386, checked in by Paul Brossier <piem@piem.org>, 6 years ago

Merge branch 'master' into feature/pytest

  • Property mode set to 100755
File size: 7.0 KB
RevLine 
[75e715f]1#! /usr/bin/env python
[1ebf8770]2
[ad5eae8]3from numpy.testing import TestCase
[0536612]4from numpy.testing import assert_equal, assert_almost_equal
[0b6d23d]5import numpy as np
[4c01c0f]6from aubio import fvec, fft, cvec
[0b6d23d]7from math import pi, floor
8from random import random
[0536612]9
10class aubio_fft_test_case(TestCase):
11
[0a42239]12    def test_members(self):
13        """ check members are set correctly """
14        win_s = 2048
15        f = fft(win_s)
16        assert_equal (f.win_s, win_s)
[0536612]17
[0a42239]18    def test_output_dimensions(self):
19        """ check the dimensions of output """
20        win_s = 1024
21        timegrain = fvec(win_s)
22        f = fft (win_s)
23        fftgrain = f (timegrain)
[ad5eae8]24        del f
25        assert_equal (fftgrain.norm.shape, (win_s/2+1,))
26        assert_equal (fftgrain.phas.shape, (win_s/2+1,))
[0536612]27
[0a42239]28    def test_zeros(self):
29        """ check the transform of zeros is all zeros """
30        win_s = 512
31        timegrain = fvec(win_s)
32        f = fft (win_s)
33        fftgrain = f (timegrain)
34        assert_equal ( fftgrain.norm, 0 )
[d98f3c0]35        try:
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.')
[0536612]43
[0a42239]44    def test_impulse(self):
45        """ check the transform of one impulse at a random place """
46        win_s = 256
[2f4d9b7]47        i = int(floor(random()*win_s))
[0a42239]48        impulse = pi * random()
49        f = fft(win_s)
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)
[0536612]57
[0a42239]58    def test_impulse_negative(self):
[0b6d23d]59        """ check the transform of a negative impulse at a random place """
[0a42239]60        win_s = 256
[0b6d23d]61        i = int(floor(random()*win_s))
62        impulse = -.1
[0a42239]63        f = fft(win_s)
64        timegrain = fvec(win_s)
[0b6d23d]65        timegrain[0] = 0
[0a42239]66        timegrain[i] = impulse
67        fftgrain = f ( timegrain )
68        #self.plot_this ( fftgrain.phas )
[0b6d23d]69        assert_almost_equal ( fftgrain.norm, abs(impulse), decimal = 5 )
[0a42239]70        if impulse < 0:
71            # phase can be pi or -pi, as it is not unwrapped
[0b6d23d]72            #assert_almost_equal ( abs(fftgrain.phas[1:-1]) , pi, decimal = 6 )
[0a42239]73            assert_almost_equal ( fftgrain.phas[0], pi, decimal = 6)
[0b6d23d]74            assert_almost_equal ( np.fmod(fftgrain.phas[-1], pi), 0, decimal = 6)
[0a42239]75        else:
[0b6d23d]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)
[0a42239]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 )
[0536612]86
[0a42239]87    def test_impulse_at_zero(self):
88        """ check the transform of one impulse at a index 0 """
89        win_s = 1024
90        impulse = pi
91        f = fft(win_s)
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 )
[0536612]100
[0a42239]101    def test_rdo_before_do(self):
102        """ check running fft.rdo before fft.do works """
103        win_s = 1024
104        f = fft(win_s)
105        fftgrain = cvec(win_s)
106        t = f.rdo( fftgrain )
107        assert_equal ( t, 0 )
[0536612]108
[0a42239]109    def plot_this(self, this):
110        from pylab import plot, show
111        plot ( this )
112        show ()
[0536612]113
[ee092a8]114    def test_local_fftgrain(self):
115        """ check aubio.fft() result can be accessed after deletion """
116        def compute_grain(impulse):
117            win_s = 1024
118            timegrain = fvec(win_s)
119            timegrain[0] = impulse
120            f = fft(win_s)
121            fftgrain = f ( timegrain )
122            return fftgrain
123        impulse = pi
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 )
128
129    def test_local_reconstruct(self):
130        """ check aubio.fft.rdo() result can be accessed after deletion """
131        def compute_grain(impulse):
132            win_s = 1024
133            timegrain = fvec(win_s)
134            timegrain[0] = impulse
135            f = fft(win_s)
136            fftgrain = f ( timegrain )
137            r = f.rdo(fftgrain)
138            return r
139        impulse = pi
140        r = compute_grain(impulse)
141        assert_almost_equal ( r[0], impulse, decimal = 6)
142        assert_almost_equal ( r[1:], 0)
143
[01d4d19]144class aubio_fft_odd_sizes(TestCase):
145
146    def test_reconstruct_with_odd_size(self):
147        win_s = 29
148        self.recontruct(win_s, 'odd sizes not supported')
149
150    def test_reconstruct_with_radix15(self):
151        win_s = 2 ** 4 * 15
152        self.recontruct(win_s, 'radix 15 supported')
153
154    def test_reconstruct_with_radix5(self):
155        win_s = 2 ** 4 * 5
156        self.recontruct(win_s, 'radix 5 supported')
157
158    def test_reconstruct_with_radix3(self):
159        win_s = 2 ** 4 * 3
160        self.recontruct(win_s, 'radix 3 supported')
161
162    def recontruct(self, win_s, skipMessage):
163        try:
164            f = fft(win_s)
165        except RuntimeError:
166            self.skipTest(skipMessage)
167        input_signal = fvec(win_s)
168        input_signal[win_s//2] = 1
169        c = f(input_signal)
170        output_signal = f.rdo(c)
171        assert_almost_equal(input_signal, output_signal)
172
173class aubio_fft_wrong_params(TestCase):
174
[d03ee4b]175    def test_large_input_timegrain(self):
176        win_s = 1024
177        f = fft(win_s)
178        t = fvec(win_s + 1)
179        with self.assertRaises(ValueError):
[437ef07]180            f(t)
[d03ee4b]181
182    def test_small_input_timegrain(self):
183        win_s = 1024
184        f = fft(win_s)
185        t = fvec(1)
186        with self.assertRaises(ValueError):
187            f(t)
188
[437ef07]189    def test_large_input_fftgrain(self):
190        win_s = 1024
191        f = fft(win_s)
[7498e48]192        s = cvec(win_s + 5)
[437ef07]193        with self.assertRaises(ValueError):
194            f.rdo(s)
195
[ad5eae8]196    def test_small_input_fftgrain(self):
[437ef07]197        win_s = 1024
198        f = fft(win_s)
199        s = cvec(16)
200        with self.assertRaises(ValueError):
201            f.rdo(s)
202
[fcef3fd]203    def test_wrong_buf_size(self):
204        win_s = -1
205        with self.assertRaises(ValueError):
206            fft(win_s)
207
208    def test_buf_size_too_small(self):
209        win_s = 1
210        with self.assertRaises(RuntimeError):
211            fft(win_s)
212
[0536612]213if __name__ == '__main__':
[319edae]214    from unittest import main
[0a42239]215    main()
Note: See TracBrowser for help on using the repository browser.