interfaces/python: added more tests
authorPaul Brossier <piem@piem.org>
Sat, 5 Dec 2009 00:59:06 +0000 (01:59 +0100)
committerPaul Brossier <piem@piem.org>
Sat, 5 Dec 2009 00:59:06 +0000 (01:59 +0100)
interfaces/python/test_fft.py [new file with mode: 0644]
interfaces/python/test_filterbank.py [new file with mode: 0644]
interfaces/python/test_onsetdetection.py [new file with mode: 0644]
interfaces/python/test_phasevoc.py [new file with mode: 0644]

diff --git a/interfaces/python/test_fft.py b/interfaces/python/test_fft.py
new file mode 100644 (file)
index 0000000..a8bebde
--- /dev/null
@@ -0,0 +1,115 @@
+from numpy.testing import TestCase, run_module_suite
+from numpy.testing import assert_equal, assert_almost_equal
+# WARNING: numpy also has an fft object
+from _aubio import fft, fvec, cvec
+from numpy import array, shape
+from math import pi
+
+class aubio_fft_test_case(TestCase):
+
+  def test_members(self):
+    f = fft()
+    assert_equal ([f.win_s, f.channels], [1024, 1])
+    f = fft(2048, 4)
+    assert_equal ([f.win_s, f.channels], [2048, 4])
+
+  def test_output_dimensions(self):
+    """ check the dimensions of output """
+    win_s, chan = 1024, 3
+    timegrain = fvec(win_s, chan)
+    f = fft(win_s, chan)
+    fftgrain = f (timegrain)
+    assert_equal (array(fftgrain), 0)
+    assert_equal (shape(fftgrain), (chan * 2, win_s/2+1))
+    assert_equal (fftgrain.norm, 0)
+    assert_equal (shape(fftgrain.norm), (chan, win_s/2+1))
+    assert_equal (fftgrain.phas, 0)
+    assert_equal (shape(fftgrain.phas), (chan, win_s/2+1))
+
+  def test_zeros(self):
+    """ check the transform of zeros """
+    win_s, chan = 512, 3
+    timegrain = fvec(win_s, chan)
+    f = fft(win_s, chan)
+    fftgrain = f(timegrain)
+    assert_equal ( fftgrain.norm == 0, True )
+    assert_equal ( fftgrain.phas == 0, True )
+
+  def test_impulse(self):
+    """ check the transform of one impulse at a random place """
+    from random import random
+    from math import floor
+    win_s, chan = 256, 1
+    i = floor(random()*win_s)
+    impulse = pi * random() 
+    f = fft(win_s, chan)
+    timegrain = fvec(win_s, chan)
+    timegrain[0][i] = impulse 
+    fftgrain = f ( timegrain )
+    #self.plot_this ( fftgrain.phas[0] )
+    assert_almost_equal ( fftgrain.norm, impulse, decimal = 6 )
+    assert_equal ( fftgrain.phas <= pi, True)
+    assert_equal ( fftgrain.phas >= -pi, True)
+
+  def test_impulse_negative(self):
+    """ check the transform of one impulse at a random place """
+    from random import random
+    from math import floor
+    win_s, chan = 256, 1
+    i = 0 
+    impulse = -10. 
+    f = fft(win_s, chan)
+    timegrain = fvec(win_s, chan)
+    timegrain[0][i] = impulse 
+    fftgrain = f ( timegrain )
+    #self.plot_this ( fftgrain.phas[0] )
+    assert_almost_equal ( fftgrain.norm, abs(impulse), decimal = 6 )
+    if impulse < 0:
+      # phase can be pi or -pi, as it is not unwrapped
+      assert_almost_equal ( abs(fftgrain.phas[0][1:-1]) , pi, decimal = 6 )
+      assert_almost_equal ( fftgrain.phas[0][0], pi, decimal = 6)
+      assert_almost_equal ( fftgrain.phas[0][-1], pi, decimal = 6)
+    else:
+      assert_equal ( fftgrain.phas[0][1:-1] == 0, True)
+      assert_equal ( fftgrain.phas[0][0] == 0, True)
+      assert_equal ( fftgrain.phas[0][-1] == 0, True)
+    # now check the resynthesis
+    synthgrain = f.rdo ( fftgrain )
+    #self.plot_this ( fftgrain.phas.T )
+    assert_equal ( fftgrain.phas <= pi, True)
+    assert_equal ( fftgrain.phas >= -pi, True)
+    #self.plot_this ( synthgrain - timegrain )
+    assert_almost_equal ( synthgrain, timegrain, decimal = 6 )
+
+  def test_impulse_at_zero(self):
+    """ check the transform of one impulse at a index 0 in one channel """
+    win_s, chan = 1024, 2
+    impulse = pi
+    f = fft(win_s, chan)
+    timegrain = fvec(win_s, chan)
+    timegrain[0][0] = impulse 
+    fftgrain = f ( timegrain )
+    #self.plot_this ( fftgrain.phas )
+    assert_equal ( fftgrain.phas[0], 0)
+    assert_equal ( fftgrain.phas[1], 0)
+    assert_almost_equal ( fftgrain.norm[0], impulse, decimal = 6 )
+    assert_equal ( fftgrain.norm[0], impulse)
+
+  def test_rdo_before_do(self):
+    """ check running fft.rdo before fft.do works """
+    win_s, chan = 1024, 2
+    impulse = pi
+    f = fft(win_s, chan)
+    fftgrain = cvec(win_s, chan)
+    t = f.rdo( fftgrain )
+    assert_equal ( t, 0 )
+
+  def plot_this(self, this):
+    from pylab import plot, show
+    plot ( this )
+    show ()
+
+if __name__ == '__main__':
+  from unittest import main
+  main()
+
diff --git a/interfaces/python/test_filterbank.py b/interfaces/python/test_filterbank.py
new file mode 100644 (file)
index 0000000..0a718f5
--- /dev/null
@@ -0,0 +1,39 @@
+from numpy.testing import TestCase, run_module_suite
+from numpy.testing import assert_equal, assert_almost_equal
+from numpy import array, shape
+from _aubio import *
+
+class aubio_filter_test_case(TestCase):
+
+  def test_slaney(self):
+    f = filterbank(40, 512)
+    f.set_mel_coeffs_slaney(16000)
+    a = f.get_coeffs()
+    a.T
+
+  def test_other_slaney(self):
+    f = filterbank(40, 512*2)
+    f.set_mel_coeffs_slaney(44100)
+    a = f.get_coeffs()
+    #print "sum is", sum(sum(a))
+    for win_s in [256, 512, 1024, 2048, 4096]:
+      f = filterbank(40, win_s)
+      f.set_mel_coeffs_slaney(320000)
+      a = f.get_coeffs()
+      #print "sum is", sum(sum(a))
+
+  def test_triangle_freqs(self):
+    f = filterbank(9, 1024)
+    freq_list = [40, 80, 200, 400, 800, 1600, 3200, 6400, 12800, 15000, 24000]
+    freqs = array(freq_list, dtype = 'float32')
+    f.set_triangle_bands(freqs, 48000)
+    f.get_coeffs().T
+    assert_equal ( f(cvec(1024)), [0] * 9)
+    spec = cvec(1024)
+    spec[0][40:100] = 100
+    #print f(spec)
+
+if __name__ == '__main__':
+  from unittest import main
+  main()
+
diff --git a/interfaces/python/test_onsetdetection.py b/interfaces/python/test_onsetdetection.py
new file mode 100644 (file)
index 0000000..35a8af9
--- /dev/null
@@ -0,0 +1,183 @@
+from numpy.testing import TestCase, run_module_suite
+from numpy.testing import assert_equal, assert_almost_equal
+# WARNING: numpy also has an fft object
+from _aubio import cvec, specdesc
+from numpy import array, shape, arange, zeros, log
+from math import pi
+
+class aubio_specdesc(TestCase):
+
+    def test_members(self):
+        o = specdesc()
+        assert_equal ([o.buf_size, o.channels, o.method],
+            [1024, 1, "default"])
+        o = specdesc("complex", 512, 2)
+        assert_equal ([o.buf_size, o.channels, o.method],
+            [512, 2, "complex"])
+
+    def test_hfc(self):
+        o = specdesc("hfc")
+        c = cvec()
+        assert_equal( 0., o(c))
+        a = arange(c.length, dtype='float32')
+        c.norm = a
+        assert_equal (a, c.norm[0])
+        assert_equal ( sum(a*(a+1)), o(c))
+
+    def test_complex(self):
+        o = specdesc("complex")
+        c = cvec()
+        assert_equal( 0., o(c))
+        a = arange(c.length, dtype='float32')
+        c.norm = a
+        assert_equal (a, c.norm[0])
+        # the previous run was on zeros, so previous frames are still 0
+        # so we have sqrt ( abs ( r2 ^ 2) ) == r2
+        assert_equal ( sum(a), o(c))
+        # second time. c.norm = a, so, r1 = r2, and the euclidian distance is 0
+        assert_equal ( 0, o(c))
+
+    def test_phase(self):
+        o = specdesc("phase")
+        c = cvec()
+        assert_equal( 0., o(c))
+
+    def test_kl(self):
+        o = specdesc("kl")
+        c = cvec()
+        assert_equal( 0., o(c))
+        a = arange(c.length, dtype='float32')
+        c.norm = a
+        assert_almost_equal( sum(a * log(1.+ a/1.e-10 ) ) / o(c), 1., decimal=6)
+
+    def test_mkl(self):
+        o = specdesc("mkl")
+        c = cvec()
+        assert_equal( 0., o(c))
+        a = arange(c.length, dtype='float32')
+        c.norm = a
+        assert_almost_equal( sum(log(1.+ a/1.e-10 ) ) / o(c), 1, decimal=6)
+
+    def test_specflux(self):
+        o = specdesc("specflux")
+        c = cvec()
+        assert_equal( 0., o(c))
+        a = arange(c.length, dtype='float32')
+        c.norm = a
+        assert_equal( sum(a), o(c))
+        assert_equal( 0, o(c))
+        c.norm = zeros(c.length, dtype='float32')
+        assert_equal( 0, o(c))
+
+    def test_centroid(self):
+        o = specdesc("centroid")
+        c = cvec()
+        # make sure centroid of zeros is zero
+        assert_equal( 0., o(c))
+        a = arange(c.length, dtype='float32')
+        c.norm = a
+        centroid = sum(a*a) / sum(a)
+        assert_almost_equal (centroid, o(c), decimal = 2)
+
+        c.norm = a * .5 
+        assert_almost_equal (centroid, o(c), decimal = 2)
+
+    def test_spread(self):
+        o = specdesc("spread")
+        c = cvec()
+        assert_equal( 0., o(c))
+        a = arange(c.length, dtype='float32')
+        c.norm = a
+        centroid = sum(a*a) / sum(a)
+        spread = sum( (a - centroid)**2 *a) / sum(a)
+        assert_almost_equal (spread, o(c), decimal = 2)
+
+        c.norm = a * 3
+        assert_almost_equal (spread, o(c), decimal = 2)
+
+    def test_skewness(self):
+        o = specdesc("skewness")
+        c = cvec()
+        assert_equal( 0., o(c))
+        a = arange(c.length, dtype='float32')
+        c.norm = a
+        centroid = sum(a*a) / sum(a)
+        spread = sum( (a - centroid)**2 *a) / sum(a)
+        skewness = sum( (a - centroid)**3 *a) / sum(a) / spread **1.5
+        assert_almost_equal (skewness, o(c), decimal = 2)
+
+        c.norm = a * 3
+        assert_almost_equal (skewness, o(c), decimal = 2)
+
+    def test_kurtosis(self):
+        o = specdesc("kurtosis")
+        c = cvec()
+        assert_equal( 0., o(c))
+        a = arange(c.length, dtype='float32')
+        c.norm = a
+        centroid = sum(a*a) / sum(a)
+        spread = sum( (a - centroid)**2 *a) / sum(a)
+        kurtosis = sum( (a - centroid)**4 *a) / sum(a) / spread **2
+        assert_almost_equal (kurtosis, o(c), decimal = 2)
+
+    def test_slope(self):
+        o = specdesc("slope")
+        c = cvec()
+        assert_equal( 0., o(c))
+        a = arange(c.length * 2, 0, -2, dtype='float32')
+        k = arange(c.length, dtype='float32')
+        c.norm = a
+        num = len(a) * sum(k*a) - sum(k)*sum(a)
+        den = (len(a) * sum(k**2) - sum(k)**2)
+        slope = num/den/sum(a)
+        assert_almost_equal (slope, o(c), decimal = 5)
+
+        a = arange(0, c.length * 2, +2, dtype='float32')
+        c.norm = a
+        num = len(a) * sum(k*a) - sum(k)*sum(a)
+        den = (len(a) * sum(k**2) - sum(k)**2)
+        slope = num/den/sum(a)
+        assert_almost_equal (slope, o(c), decimal = 5)
+
+        a = arange(0, c.length * 2, +2, dtype='float32')
+        c.norm = a * 2
+        assert_almost_equal (slope, o(c), decimal = 5)
+
+    def test_decrease(self):
+        o = specdesc("decrease")
+        c = cvec()
+        assert_equal( 0., o(c))
+        a = arange(c.length * 2, 0, -2, dtype='float32')
+        k = arange(c.length, dtype='float32')
+        c.norm = a
+        decrease = sum((a[1:] - a [0]) / k[1:]) / sum(a[1:]) 
+        assert_almost_equal (decrease, o(c), decimal = 5)
+
+        a = arange(0, c.length * 2, +2, dtype='float32')
+        c.norm = a
+        decrease = sum((a[1:] - a [0]) / k[1:]) / sum(a[1:]) 
+        assert_almost_equal (decrease, o(c), decimal = 5)
+
+        a = arange(0, c.length * 2, +2, dtype='float32')
+        c.norm = a * 2
+        decrease = sum((a[1:] - a [0]) / k[1:]) / sum(a[1:]) 
+        assert_almost_equal (decrease, o(c), decimal = 5)
+
+    def test_rolloff(self):
+        o = specdesc("rolloff")
+        c = cvec()
+        assert_equal( 0., o(c))
+        a = arange(c.length * 2, 0, -2, dtype='float32')
+        k = arange(c.length, dtype='float32')
+        c.norm = a
+        cumsum = .95*sum(a*a)
+        i = 0; rollsum = 0
+        while rollsum < cumsum:
+          rollsum += a[i]*a[i]
+          i+=1
+        rolloff = i 
+        assert_equal (rolloff, o(c))
+
+if __name__ == '__main__':
+    from unittest import main
+    main()
diff --git a/interfaces/python/test_phasevoc.py b/interfaces/python/test_phasevoc.py
new file mode 100644 (file)
index 0000000..c1fc714
--- /dev/null
@@ -0,0 +1,64 @@
+from numpy.testing import TestCase, run_module_suite
+from numpy.testing import assert_equal, assert_almost_equal
+from _aubio import *
+from numpy import array, shape
+
+class aubio_pvoc_test_case(TestCase):
+
+  def test_members(self):
+    f = pvoc()
+    assert_equal ([f.win_s, f.hop_s], [1024, 512])
+    f = pvoc(2048, 128)
+    assert_equal ([f.win_s, f.hop_s], [2048, 128])
+
+  def test_zeros(self):
+    win_s, hop_s = 1024, 256
+    f = pvoc (win_s, hop_s)
+    t = fvec (hop_s)
+    for time in range( 4 * win_s / hop_s ):
+      s = f(t)
+      r = f.rdo(s)
+      assert_equal ( array(t), 0)
+      assert_equal ( s.norm, 0)
+      assert_equal ( s.phas, 0)
+      assert_equal ( r, 0)
+
+  def test_steps_two_channels(self):
+    """ check the resynthesis of steps is correct """
+    f = pvoc(1024, 512, 2)
+    t1 = fvec(512, 2)
+    t2 = fvec(512, 2)
+    # positive step in first channel
+    t1[0][100:200] = .1
+    # positive step in second channel
+    t1[1][20:50] = -.1
+    s1 = f(t1)
+    r1 = f.rdo(s1)
+    s2 = f(t2)
+    r2 = f.rdo(s2)
+    #self.plot_this ( s1.norm.T )
+    assert_almost_equal ( t1, r2, decimal = 6 )
+    
+  def test_steps_three_random_channels(self):
+    from random import random
+    f = pvoc(64, 16, 3)
+    t0 = fvec(16, 3)
+    t1 = fvec(16, 3)
+    for i in xrange(3):
+      for j in xrange(16):
+        t1[i][j] = random() * 2. - 1.
+    t2 = f.rdo(f(t1))
+    t2 = f.rdo(f(t0))
+    t2 = f.rdo(f(t0))
+    t2 = f.rdo(f(t0))
+    assert_almost_equal( t1, t2, decimal = 6 )
+    
+  def plot_this( self, this ):
+    from pylab import semilogy, show
+    semilogy ( this )
+    show ()
+
+if __name__ == '__main__':
+  from unittest import main
+  main()
+