python/tests: fix most prospect warnings
[aubio.git] / python / tests / test_fft.py
1 #! /usr/bin/env python
2
3 from unittest import main
4 from numpy.testing import TestCase
5 from numpy.testing import assert_equal, assert_almost_equal
6 import numpy as np
7 from aubio import fvec, fft, cvec
8 from math import pi, floor
9 from random import random
10
11 class aubio_fft_test_case(TestCase):
12
13     def test_members(self):
14         """ check members are set correctly """
15         win_s = 2048
16         f = fft(win_s)
17         assert_equal (f.win_s, win_s)
18
19     def test_output_dimensions(self):
20         """ check the dimensions of output """
21         win_s = 1024
22         timegrain = fvec(win_s)
23         f = fft (win_s)
24         fftgrain = f (timegrain)
25         del f
26         assert_equal (fftgrain.norm.shape, (win_s/2+1,))
27         assert_equal (fftgrain.phas.shape, (win_s/2+1,))
28
29     def test_zeros(self):
30         """ check the transform of zeros is all zeros """
31         win_s = 512
32         timegrain = fvec(win_s)
33         f = fft (win_s)
34         fftgrain = f (timegrain)
35         assert_equal ( fftgrain.norm, 0 )
36         assert_equal ( fftgrain.phas, 0 )
37
38     def test_impulse(self):
39         """ check the transform of one impulse at a random place """
40         win_s = 256
41         i = int(floor(random()*win_s))
42         impulse = pi * random()
43         f = fft(win_s)
44         timegrain = fvec(win_s)
45         timegrain[i] = impulse
46         fftgrain = f ( timegrain )
47         #self.plot_this ( fftgrain.phas )
48         assert_almost_equal ( fftgrain.norm, impulse, decimal = 6 )
49         assert_equal ( fftgrain.phas <= pi, True)
50         assert_equal ( fftgrain.phas >= -pi, True)
51
52     def test_impulse_negative(self):
53         """ check the transform of a negative impulse at a random place """
54         win_s = 256
55         i = int(floor(random()*win_s))
56         impulse = -.1
57         f = fft(win_s)
58         timegrain = fvec(win_s)
59         timegrain[0] = 0
60         timegrain[i] = impulse
61         fftgrain = f ( timegrain )
62         #self.plot_this ( fftgrain.phas )
63         assert_almost_equal ( fftgrain.norm, abs(impulse), decimal = 5 )
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 ( np.fmod(fftgrain.phas[-1], pi), 0, decimal = 6)
69         else:
70             #assert_equal ( fftgrain.phas[1:-1] == 0, True)
71             assert_equal ( fftgrain.phas[0], 0)
72             assert_almost_equal ( np.fmod(fftgrain.phas[-1], pi), 0, decimal = 6)
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         f = fft(win_s)
99         fftgrain = cvec(win_s)
100         t = f.rdo( fftgrain )
101         assert_equal ( t, 0 )
102
103     def plot_this(self, this):
104         from pylab import plot, show
105         plot ( this )
106         show ()
107
108     def test_local_fftgrain(self):
109         """ check aubio.fft() result can be accessed after deletion """
110         def compute_grain(impulse):
111             win_s = 1024
112             timegrain = fvec(win_s)
113             timegrain[0] = impulse
114             f = fft(win_s)
115             fftgrain = f ( timegrain )
116             return fftgrain
117         impulse = pi
118         fftgrain = compute_grain(impulse)
119         assert_equal ( fftgrain.phas[0], 0)
120         assert_almost_equal ( fftgrain.phas[1], 0)
121         assert_almost_equal ( fftgrain.norm[0], impulse, decimal = 6 )
122
123     def test_local_reconstruct(self):
124         """ check aubio.fft.rdo() result can be accessed after deletion """
125         def compute_grain(impulse):
126             win_s = 1024
127             timegrain = fvec(win_s)
128             timegrain[0] = impulse
129             f = fft(win_s)
130             fftgrain = f ( timegrain )
131             r = f.rdo(fftgrain)
132             return r
133         impulse = pi
134         r = compute_grain(impulse)
135         assert_almost_equal ( r[0], impulse, decimal = 6)
136         assert_almost_equal ( r[1:], 0)
137
138     def test_large_input_timegrain(self):
139         win_s = 1024
140         f = fft(win_s)
141         t = fvec(win_s + 1)
142         with self.assertRaises(ValueError):
143             f(t)
144
145     def test_small_input_timegrain(self):
146         win_s = 1024
147         f = fft(win_s)
148         t = fvec(1)
149         with self.assertRaises(ValueError):
150             f(t)
151
152     def test_large_input_fftgrain(self):
153         win_s = 1024
154         f = fft(win_s)
155         s = cvec(win_s + 5)
156         with self.assertRaises(ValueError):
157             f.rdo(s)
158
159     def test_small_input_fftgrain(self):
160         win_s = 1024
161         f = fft(win_s)
162         s = cvec(16)
163         with self.assertRaises(ValueError):
164             f.rdo(s)
165
166 class aubio_fft_wrong_params(TestCase):
167
168     def test_wrong_buf_size(self):
169         win_s = -1
170         with self.assertRaises(ValueError):
171             fft(win_s)
172
173     def test_buf_size_not_power_of_two(self):
174         # when compiled with fftw3, aubio supports non power of two fft sizes
175         win_s = 320
176         try:
177             with self.assertRaises(RuntimeError):
178                 fft(win_s)
179         except AssertionError:
180             self.skipTest('creating aubio.fft with size %d did not fail' % win_s)
181
182     def test_buf_size_too_small(self):
183         win_s = 1
184         with self.assertRaises(RuntimeError):
185             fft(win_s)
186
187 if __name__ == '__main__':
188     main()