changeset 3:4be70944d21b skeleton_v2

Add some basic signal processing methods we need
author Chris Cannam
date Thu, 04 Oct 2012 17:14:05 +0100
parents 32bf6cb28341
children 3df0742b4c82
files signal_processing.py test_signal_processing.py
diffstat 2 files changed, 47 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/signal_processing.py	Thu Oct 04 17:14:05 2012 +0100
@@ -0,0 +1,20 @@
+
+import numpy as np
+
+def rms(samples):
+    """Return the root mean square of the given samples"""
+    return np.sqrt(np.mean(np.array(samples)**2))
+
+def autocorrelation(samples):
+    """Return the autocorrelation of the given samples, as an array with zero lag at the start"""
+    acf = np.correlate(samples, samples, mode='full')
+    return acf[len(acf)/2:]
+
+def bpm_to_lag(bpm, hops_per_sec):
+    """Return the autocorrelation lag corresponding to the duration of a beat at the given tempo in bpm"""
+    return int((60.0 / bpm) * hops_per_sec)
+
+def lag_to_bpm(lag, hops_per_sec):
+    """Return the tempo in bpm whose beat duration corresponds to the given autocorrelation lag"""
+    return (60.0 * hops_per_sec) / lag
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test_signal_processing.py	Thu Oct 04 17:14:05 2012 +0100
@@ -0,0 +1,27 @@
+
+import signal_processing as sp
+import numpy as np
+
+def test_rms():
+    assert sp.rms([1,1,1]) == 1.0
+    assert sp.rms([0.5,-0.5]) == 0.5
+    assert sp.rms([0,0,0,0]) == 0.0
+    assert sp.rms([5]) == 5.0
+    assert abs(sp.rms([1,2,-2]) - np.sqrt(3.0)) < 0.000001
+
+def test_autocorrelation():
+    samples = [1,0,0,1,0,0,1,0,0,1,0,0,1,0,0]
+    acf = sp.autocorrelation(samples)
+    assert len(acf) == len(samples)
+    assert np.argmax(acf) == 0
+    assert acf[3] > acf[2]
+    assert acf[3] > acf[4]
+
+def test_bpm_lag_conversions():
+    assert sp.bpm_to_lag(60, 1) == 1
+    assert sp.bpm_to_lag(60, 120) == 120
+    assert sp.bpm_to_lag(30, 120) == 240
+    assert sp.bpm_to_lag(120, 1) == 0 # should be an integer
+    assert sp.lag_to_bpm(120, 120) == 60.0
+    assert sp.lag_to_bpm(60, 120) == 120.0
+    assert sp.lag_to_bpm(80, 6) == 4.5