diff modules-and-plug-ins/python-module/btrack_python_module.cpp @ 55:5e520f59127f

Changed the interface of the algorithm so that onset detection function samples are calculated internally. This makes the call to the algorithm for most cases much simpler. Also added a static function for calculating beat times in seconds based upon sampling frequency, hop size and the current frame number.
author Adam Stark <adamstark@users.noreply.github.com>
date Wed, 22 Jan 2014 18:47:16 +0000
parents 9699024bb3d0
children baf35f208814
line wrap: on
line diff
--- a/modules-and-plug-ins/python-module/btrack_python_module.cpp	Wed Jan 22 02:49:29 2014 +0000
+++ b/modules-and-plug-ins/python-module/btrack_python_module.cpp	Wed Jan 22 18:47:16 2014 +0000
@@ -4,6 +4,7 @@
 #include "../../src/BTrack.h"
 #include <numpy/arrayobject.h>
 
+//=======================================================================
 static PyObject * btrack_onsetdf(PyObject *dummy, PyObject *args) 
 {
     PyObject *arg1=NULL;
@@ -29,23 +30,19 @@
     
     // get array size
     long signal_length = PyArray_Size((PyObject*)arr1);
-    //int k = (int) theSize;
-    
-    // get data type 
-    //char type = PyArray_DESCR(arr1)->type;
     
     ////////// BEGIN PROCESS ///////////////////
-    int hsize = 512;
-    int fsize = 1024;
+    int hopSize = 512;
+    int frameSize = 1024;
     int df_type = 6;
     int numframes;
-    double buffer[hsize];	// buffer to hold one hopsize worth of audio samples
+    double buffer[hopSize];	// buffer to hold one hopsize worth of audio samples
 
     
     // get number of audio frames, given the hop size and signal length
-	numframes = (int) floor(((double) signal_length) / ((double) hsize));
+	numframes = (int) floor(((double) signal_length) / ((double) hopSize));
     
-    OnsetDetectionFunction onset(hsize,fsize,df_type,1);
+    OnsetDetectionFunction onset(hopSize,frameSize,df_type,1);
 
     double df[numframes];
     
@@ -57,9 +54,9 @@
 	for (int i=0;i < numframes;i++)
 	{		
 		// add new samples to frame
-		for (int n = 0;n < hsize;n++)
+		for (int n = 0;n < hopSize;n++)
 		{
-			buffer[n] = data[(i*hsize)+n];
+			buffer[n] = data[(i*hopSize)+n];
 		}
 		
 		df[i] = onset.getDFsample(buffer);
@@ -91,19 +88,9 @@
     //return Py_None;
     
     return (PyObject *)c;
-    
-    //return Py_BuildValue("c", type);
-    //return Py_BuildValue("d", sum);
-    //return Py_BuildValue("i", k);
-/*    
-fail:
-    Py_XDECREF(arr1); 
-    Py_XDECREF(arr2); 
-    PyArray_XDECREF_ERR(oarr); 
-    return NULL;*/
 }
 
-
+//=======================================================================
 static PyObject * btrack_btrack(PyObject *dummy, PyObject *args) 
 {
     PyObject *arg1=NULL;
@@ -129,35 +116,25 @@
     
     // get array size
     long signal_length = PyArray_Size((PyObject*)arr1);
-    //int k = (int) theSize;
-    
-    // get data type 
-    //char type = PyArray_DESCR(arr1)->type;
+
     
     ////////// BEGIN PROCESS ///////////////////
-    int hsize = 512;
-    int fsize = 1024;
-    int df_type = 6;
+    int hopSize = 512;
+    int frameSize = 1024;
+
     int numframes;
-    double buffer[hsize];	// buffer to hold one hopsize worth of audio samples
+    double buffer[hopSize];	// buffer to hold one hopsize worth of audio samples
     
     
     // get number of audio frames, given the hop size and signal length
-	numframes = (int) floor(((double) signal_length) / ((double) hsize));
+	numframes = (int) floor(((double) signal_length) / ((double) hopSize));
     
-    OnsetDetectionFunction onset(hsize,fsize,df_type,1);
-    BTrack b;
+
+    BTrack b(hopSize,frameSize);
     
-    b.initialise((int) hsize);	// initialise beat tracker
-	
-	// set parameters
-    //b.setparams(0.9,5);
     
-    double df[numframes];
     double beats[5000];
     int beatnum = 0;
-
-    double df_val;
     
     ///////////////////////////////////////////
 	//////// Begin Processing Loop ////////////
@@ -165,21 +142,20 @@
 	for (int i=0;i < numframes;i++)
 	{		
 		// add new samples to frame
-		for (int n = 0;n < hsize;n++)
+		for (int n = 0;n < hopSize;n++)
 		{
-			buffer[n] = data[(i*hsize)+n];
+			buffer[n] = data[(i*hopSize)+n];
 		}
 		
-		df[i] = onset.getDFsample(buffer);
+        // process the current audio frame
+        b.processAudioFrame(buffer);
         
-        df_val = df[i] + 0.0001;
-                
-		b.process(df_val);				// process df sample in beat tracker
-		
+        // if a beat is currently scheduled
 		if (b.playbeat == 1)
 		{
-			beats[beatnum] = (((double) hsize) / 44100) * ((double) i);
-			beatnum = beatnum + 1;	
+			//beats[beatnum] = (((double) hopSize) / 44100) * ((double) i);
+			beats[beatnum] = BTrack::getBeatTimeInSeconds(i,hopSize,44100);
+            beatnum = beatnum + 1;
 		}
 		
 	}
@@ -217,18 +193,9 @@
     //return Py_None;
     
     return (PyObject *)c;
-    
-    //return Py_BuildValue("c", type);
-    //return Py_BuildValue("d", sum);
-    //return Py_BuildValue("i", k);
-    /*    
-     fail:
-     Py_XDECREF(arr1); 
-     Py_XDECREF(arr2); 
-     PyArray_XDECREF_ERR(oarr); 
-     return NULL;*/
 }
 
+//=======================================================================
 static PyObject * btrack_btrack_df(PyObject *dummy, PyObject *args) 
 {
     PyObject *arg1=NULL;
@@ -254,20 +221,12 @@
     
     // get array size
     long numframes = PyArray_Size((PyObject*)arr1);
-    //int k = (int) theSize;
-    
-    // get data type 
-    //char type = PyArray_DESCR(arr1)->type;
-    
+
     ////////// BEGIN PROCESS ///////////////////
-    int hsize = 512;
+    int hopSize = 512;
+    int frameSize = 2*hopSize;
 
-    BTrack b;
-    
-    b.initialise((int) hsize);	// initialise beat tracker
-	
-	// set parameters
-    //b.setparams(0.9,5);
+    BTrack b(hopSize,frameSize);
     
     double beats[5000];
     int beatnum = 0;
@@ -280,11 +239,12 @@
 	{		
         df_val = data[i] + 0.0001;
         
-		b.process(df_val);				// process df sample in beat tracker
+		b.processOnsetDetectionFunctionSample(df_val);				// process df sample in beat tracker
 		
 		if (b.playbeat == 1)
 		{
-			beats[beatnum] = (((double) hsize) / 44100) * ((double) i);
+			//beats[beatnum] = (((double) hopSize) / 44100) * ((double) i);
+            beats[beatnum] = BTrack::getBeatTimeInSeconds(i,hopSize,44100);
 			beatnum = beatnum + 1;	
 		}
 		
@@ -323,20 +283,10 @@
     //return Py_None;
     
     return (PyObject *)c;
-    
-    //return Py_BuildValue("c", type);
-    //return Py_BuildValue("d", sum);
-    //return Py_BuildValue("i", k);
-    /*    
-     fail:
-     Py_XDECREF(arr1); 
-     Py_XDECREF(arr2); 
-     PyArray_XDECREF_ERR(oarr); 
-     return NULL;*/
 }
 
 
-
+//=======================================================================
 static PyMethodDef btrack_methods[] = {
     { "onsetdf",btrack_onsetdf,METH_VARARGS,"onset detection function"},
     { "btrack",btrack_btrack,METH_VARARGS,"beat tracker"},
@@ -344,12 +294,14 @@
     {NULL, NULL, 0, NULL} /* Sentinel */
 };
 
+//=======================================================================
 PyMODINIT_FUNC initbtrack(void)
 {
     (void)Py_InitModule("btrack", btrack_methods);
     import_array();
 }
 
+//=======================================================================
 int main(int argc, char *argv[])
 {
     /* Pass argv[0] to the Python interpreter */