Mercurial > hg > btrack
view 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 source
#include <iostream> #include <Python.h> #include "../../src/OnsetDetectionFunction.h" #include "../../src/BTrack.h" #include <numpy/arrayobject.h> //======================================================================= static PyObject * btrack_onsetdf(PyObject *dummy, PyObject *args) { PyObject *arg1=NULL; PyObject *arr1=NULL; if (!PyArg_ParseTuple(args, "O", &arg1)) { return NULL; } arr1 = PyArray_FROM_OTF(arg1, NPY_DOUBLE, NPY_IN_ARRAY); if (arr1 == NULL) { return NULL; } ////////// GET INPUT DATA /////////////////// // get data as array double* data = (double*) PyArray_DATA(arr1); // get array size long signal_length = PyArray_Size((PyObject*)arr1); ////////// BEGIN PROCESS /////////////////// int hopSize = 512; int frameSize = 1024; int df_type = 6; int numframes; 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) hopSize)); OnsetDetectionFunction onset(hopSize,frameSize,df_type,1); double df[numframes]; /////////////////////////////////////////// //////// Begin Processing Loop //////////// for (int i=0;i < numframes;i++) { // add new samples to frame for (int n = 0;n < hopSize;n++) { buffer[n] = data[(i*hopSize)+n]; } df[i] = onset.getDFsample(buffer); } ///////// End Processing Loop ///////////// /////////////////////////////////////////// ////////// END PROCESS /////////////////// ////////// CREATE ARRAY AND RETURN IT /////////////////// int nd=1; npy_intp m= numframes; //double fArray[5] = {0,1,2,3,4}; PyObject* c=PyArray_SimpleNew(nd, &m, NPY_DOUBLE); void *arr_data = PyArray_DATA((PyArrayObject*)c); memcpy(arr_data, df, PyArray_ITEMSIZE((PyArrayObject*) c) * m); Py_DECREF(arr1); Py_INCREF(Py_None); //return Py_None; return (PyObject *)c; } //======================================================================= static PyObject * btrack_btrack(PyObject *dummy, PyObject *args) { PyObject *arg1=NULL; PyObject *arr1=NULL; if (!PyArg_ParseTuple(args, "O", &arg1)) { return NULL; } arr1 = PyArray_FROM_OTF(arg1, NPY_DOUBLE, NPY_IN_ARRAY); if (arr1 == NULL) { return NULL; } ////////// GET INPUT DATA /////////////////// // get data as array double* data = (double*) PyArray_DATA(arr1); // get array size long signal_length = PyArray_Size((PyObject*)arr1); ////////// BEGIN PROCESS /////////////////// int hopSize = 512; int frameSize = 1024; int numframes; 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) hopSize)); BTrack b(hopSize,frameSize); double beats[5000]; int beatnum = 0; /////////////////////////////////////////// //////// Begin Processing Loop //////////// for (int i=0;i < numframes;i++) { // add new samples to frame for (int n = 0;n < hopSize;n++) { buffer[n] = data[(i*hopSize)+n]; } // process the current audio frame b.processAudioFrame(buffer); // if a beat is currently scheduled if (b.playbeat == 1) { //beats[beatnum] = (((double) hopSize) / 44100) * ((double) i); beats[beatnum] = BTrack::getBeatTimeInSeconds(i,hopSize,44100); beatnum = beatnum + 1; } } ///////// End Processing Loop ///////////// /////////////////////////////////////////// ////////// END PROCESS /////////////////// double beats_out[beatnum]; // create output array // copy beats into output array for (int i = 0;i < beatnum;i++) { beats_out[i] = beats[i]; } ////////// CREATE ARRAY AND RETURN IT /////////////////// int nd=1; npy_intp m= beatnum; //double fArray[5] = {0,1,2,3,4}; PyObject* c=PyArray_SimpleNew(nd, &m, NPY_DOUBLE); void *arr_data = PyArray_DATA((PyArrayObject*)c); memcpy(arr_data, beats_out, PyArray_ITEMSIZE((PyArrayObject*) c) * m); Py_DECREF(arr1); Py_INCREF(Py_None); //return Py_None; return (PyObject *)c; } //======================================================================= static PyObject * btrack_btrack_df(PyObject *dummy, PyObject *args) { PyObject *arg1=NULL; PyObject *arr1=NULL; if (!PyArg_ParseTuple(args, "O", &arg1)) { return NULL; } arr1 = PyArray_FROM_OTF(arg1, NPY_DOUBLE, NPY_IN_ARRAY); if (arr1 == NULL) { return NULL; } ////////// GET INPUT DATA /////////////////// // get data as array double* data = (double*) PyArray_DATA(arr1); // get array size long numframes = PyArray_Size((PyObject*)arr1); ////////// BEGIN PROCESS /////////////////// int hopSize = 512; int frameSize = 2*hopSize; BTrack b(hopSize,frameSize); double beats[5000]; int beatnum = 0; double df_val; /////////////////////////////////////////// //////// Begin Processing Loop //////////// for (long i=0;i < numframes;i++) { df_val = data[i] + 0.0001; b.processOnsetDetectionFunctionSample(df_val); // process df sample in beat tracker if (b.playbeat == 1) { //beats[beatnum] = (((double) hopSize) / 44100) * ((double) i); beats[beatnum] = BTrack::getBeatTimeInSeconds(i,hopSize,44100); beatnum = beatnum + 1; } } ///////// End Processing Loop ///////////// /////////////////////////////////////////// ////////// END PROCESS /////////////////// double beats_out[beatnum]; // create output array // copy beats into output array for (int i = 0;i < beatnum;i++) { beats_out[i] = beats[i]; } ////////// CREATE ARRAY AND RETURN IT /////////////////// int nd=1; npy_intp m= beatnum; //double fArray[5] = {0,1,2,3,4}; PyObject* c=PyArray_SimpleNew(nd, &m, NPY_DOUBLE); void *arr_data = PyArray_DATA((PyArrayObject*)c); memcpy(arr_data, beats_out, PyArray_ITEMSIZE((PyArrayObject*) c) * m); Py_DECREF(arr1); Py_INCREF(Py_None); //return Py_None; return (PyObject *)c; } //======================================================================= static PyMethodDef btrack_methods[] = { { "onsetdf",btrack_onsetdf,METH_VARARGS,"onset detection function"}, { "btrack",btrack_btrack,METH_VARARGS,"beat tracker"}, { "btrack_df",btrack_btrack_df,METH_VARARGS,"beat tracker with detection function input"}, {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 */ Py_SetProgramName(argv[0]); /* Initialize the Python interpreter. Required. */ Py_Initialize(); /* Add a static module */ initbtrack(); }