adamstark@51: #include adamstark@51: #include adamstark@51: #include "../../src/OnsetDetectionFunction.h" adamstark@51: #include "../../src/BTrack.h" adamstark@51: #include adamstark@51: adamstark@55: //======================================================================= adamstark@61: static PyObject * btrack_trackBeats(PyObject *dummy, PyObject *args) adamstark@61: { adamstark@61: PyObject *arg1=NULL; adamstark@61: PyObject *arr1=NULL; adamstark@61: adamstark@61: if (!PyArg_ParseTuple(args, "O", &arg1)) adamstark@61: { adamstark@61: return NULL; adamstark@61: } adamstark@61: adamstark@61: arr1 = PyArray_FROM_OTF(arg1, NPY_DOUBLE, NPY_IN_ARRAY); adamstark@61: if (arr1 == NULL) adamstark@61: { adamstark@61: return NULL; adamstark@61: } adamstark@61: adamstark@61: adamstark@61: adamstark@61: ////////// GET INPUT DATA /////////////////// adamstark@61: adamstark@61: // get data as array adamstark@61: double* data = (double*) PyArray_DATA(arr1); adamstark@61: adamstark@61: // get array size adamstark@61: long signal_length = PyArray_Size((PyObject*)arr1); adamstark@61: adamstark@61: adamstark@61: ////////// BEGIN PROCESS /////////////////// adamstark@61: int hopSize = 512; adamstark@61: int frameSize = 1024; adamstark@61: adamstark@61: int numframes; adamstark@61: double buffer[hopSize]; // buffer to hold one hopsize worth of audio samples adamstark@61: adamstark@61: adamstark@61: // get number of audio frames, given the hop size and signal length adamstark@61: numframes = (int) floor(((double) signal_length) / ((double) hopSize)); adamstark@61: adamstark@61: adamstark@61: BTrack b(hopSize,frameSize); adamstark@61: adamstark@61: adamstark@61: double beats[5000]; adamstark@61: int beatnum = 0; adamstark@61: adamstark@61: /////////////////////////////////////////// adamstark@61: //////// Begin Processing Loop //////////// adamstark@61: adamstark@61: for (int i=0;i < numframes;i++) adamstark@61: { adamstark@61: // add new samples to frame adamstark@61: for (int n = 0;n < hopSize;n++) adamstark@61: { adamstark@61: buffer[n] = data[(i*hopSize)+n]; adamstark@61: } adamstark@61: adamstark@61: // process the current audio frame adamstark@61: b.processAudioFrame(buffer); adamstark@61: adamstark@61: // if a beat is currently scheduled adamstark@61: if (b.beatDueInCurrentFrame()) adamstark@61: { adamstark@61: beats[beatnum] = BTrack::getBeatTimeInSeconds(i,hopSize,44100); adamstark@61: beatnum = beatnum + 1; adamstark@61: } adamstark@61: adamstark@61: } adamstark@61: adamstark@61: ///////// End Processing Loop ///////////// adamstark@61: /////////////////////////////////////////// adamstark@61: adamstark@61: adamstark@61: ////////// END PROCESS /////////////////// adamstark@61: adamstark@61: double beats_out[beatnum]; // create output array adamstark@61: adamstark@61: // copy beats into output array adamstark@61: for (int i = 0;i < beatnum;i++) adamstark@61: { adamstark@61: beats_out[i] = beats[i]; adamstark@61: } adamstark@61: adamstark@61: adamstark@61: adamstark@61: ////////// CREATE ARRAY AND RETURN IT /////////////////// adamstark@61: int nd=1; adamstark@61: npy_intp m= beatnum; adamstark@61: //double fArray[5] = {0,1,2,3,4}; adamstark@61: adamstark@61: PyObject* c=PyArray_SimpleNew(nd, &m, NPY_DOUBLE); adamstark@61: adamstark@61: void *arr_data = PyArray_DATA((PyArrayObject*)c); adamstark@61: adamstark@61: memcpy(arr_data, beats_out, PyArray_ITEMSIZE((PyArrayObject*) c) * m); adamstark@61: adamstark@61: adamstark@61: Py_DECREF(arr1); adamstark@61: Py_INCREF(Py_None); adamstark@61: //return Py_None; adamstark@61: adamstark@61: return (PyObject *)c; adamstark@61: } adamstark@61: adamstark@61: adamstark@61: //======================================================================= adamstark@61: static PyObject * btrack_calculateOnsetDF(PyObject *dummy, PyObject *args) adamstark@51: { adamstark@51: PyObject *arg1=NULL; adamstark@51: PyObject *arr1=NULL; adamstark@51: adamstark@51: if (!PyArg_ParseTuple(args, "O", &arg1)) adamstark@51: { adamstark@51: return NULL; adamstark@51: } adamstark@51: adamstark@51: arr1 = PyArray_FROM_OTF(arg1, NPY_DOUBLE, NPY_IN_ARRAY); adamstark@51: if (arr1 == NULL) adamstark@51: { adamstark@51: return NULL; adamstark@51: } adamstark@51: adamstark@51: adamstark@51: adamstark@51: ////////// GET INPUT DATA /////////////////// adamstark@51: adamstark@51: // get data as array adamstark@51: double* data = (double*) PyArray_DATA(arr1); adamstark@51: adamstark@51: // get array size adamstark@52: long signal_length = PyArray_Size((PyObject*)arr1); adamstark@51: adamstark@51: ////////// BEGIN PROCESS /////////////////// adamstark@55: int hopSize = 512; adamstark@55: int frameSize = 1024; adamstark@51: int df_type = 6; adamstark@51: int numframes; adamstark@55: double buffer[hopSize]; // buffer to hold one hopsize worth of audio samples adamstark@51: adamstark@51: adamstark@51: // get number of audio frames, given the hop size and signal length adamstark@55: numframes = (int) floor(((double) signal_length) / ((double) hopSize)); adamstark@51: adamstark@55: OnsetDetectionFunction onset(hopSize,frameSize,df_type,1); adamstark@51: adamstark@51: double df[numframes]; adamstark@51: adamstark@51: adamstark@51: adamstark@51: /////////////////////////////////////////// adamstark@51: //////// Begin Processing Loop //////////// adamstark@51: adamstark@51: for (int i=0;i < numframes;i++) adamstark@51: { adamstark@51: // add new samples to frame adamstark@55: for (int n = 0;n < hopSize;n++) adamstark@51: { adamstark@55: buffer[n] = data[(i*hopSize)+n]; adamstark@51: } adamstark@51: adamstark@59: df[i] = onset.calculateOnsetDetectionFunctionSample(buffer); adamstark@51: adamstark@51: } adamstark@51: adamstark@51: ///////// End Processing Loop ///////////// adamstark@51: /////////////////////////////////////////// adamstark@51: adamstark@51: adamstark@61: adamstark@51: adamstark@51: ////////// CREATE ARRAY AND RETURN IT /////////////////// adamstark@51: int nd=1; adamstark@51: npy_intp m= numframes; adamstark@61: adamstark@51: adamstark@51: PyObject* c=PyArray_SimpleNew(nd, &m, NPY_DOUBLE); adamstark@51: adamstark@51: void *arr_data = PyArray_DATA((PyArrayObject*)c); adamstark@51: adamstark@51: memcpy(arr_data, df, PyArray_ITEMSIZE((PyArrayObject*) c) * m); adamstark@51: adamstark@51: adamstark@51: Py_DECREF(arr1); adamstark@51: Py_INCREF(Py_None); adamstark@51: //return Py_None; adamstark@51: adamstark@51: return (PyObject *)c; adamstark@51: } adamstark@51: adamstark@51: adamstark@55: //======================================================================= adamstark@61: static PyObject * btrack_trackBeatsFromOnsetDF(PyObject *dummy, PyObject *args) adamstark@51: { adamstark@51: PyObject *arg1=NULL; adamstark@51: PyObject *arr1=NULL; adamstark@51: adamstark@51: if (!PyArg_ParseTuple(args, "O", &arg1)) adamstark@51: { adamstark@51: return NULL; adamstark@51: } adamstark@51: adamstark@51: arr1 = PyArray_FROM_OTF(arg1, NPY_DOUBLE, NPY_IN_ARRAY); adamstark@51: if (arr1 == NULL) adamstark@51: { adamstark@51: return NULL; adamstark@51: } adamstark@51: adamstark@51: adamstark@51: adamstark@51: ////////// GET INPUT DATA /////////////////// adamstark@51: adamstark@51: // get data as array adamstark@51: double* data = (double*) PyArray_DATA(arr1); adamstark@51: adamstark@51: // get array size adamstark@52: long numframes = PyArray_Size((PyObject*)arr1); adamstark@55: adamstark@51: ////////// BEGIN PROCESS /////////////////// adamstark@55: int hopSize = 512; adamstark@55: int frameSize = 2*hopSize; adamstark@51: adamstark@55: BTrack b(hopSize,frameSize); adamstark@51: adamstark@51: double beats[5000]; adamstark@51: int beatnum = 0; adamstark@54: double df_val; adamstark@51: adamstark@51: /////////////////////////////////////////// adamstark@51: //////// Begin Processing Loop //////////// adamstark@51: adamstark@52: for (long i=0;i < numframes;i++) adamstark@51: { adamstark@54: df_val = data[i] + 0.0001; adamstark@51: adamstark@55: b.processOnsetDetectionFunctionSample(df_val); // process df sample in beat tracker adamstark@51: adamstark@57: if (b.beatDueInCurrentFrame()) adamstark@51: { adamstark@55: beats[beatnum] = BTrack::getBeatTimeInSeconds(i,hopSize,44100); adamstark@51: beatnum = beatnum + 1; adamstark@51: } adamstark@51: adamstark@51: } adamstark@51: adamstark@51: ///////// End Processing Loop ///////////// adamstark@51: /////////////////////////////////////////// adamstark@51: adamstark@51: adamstark@51: ////////// END PROCESS /////////////////// adamstark@51: adamstark@51: double beats_out[beatnum]; // create output array adamstark@51: adamstark@51: adamstark@51: // copy beats into output array adamstark@51: for (int i = 0;i < beatnum;i++) adamstark@51: { adamstark@51: beats_out[i] = beats[i]; adamstark@51: } adamstark@51: adamstark@51: adamstark@51: ////////// CREATE ARRAY AND RETURN IT /////////////////// adamstark@51: int nd=1; adamstark@51: npy_intp m= beatnum; adamstark@51: //double fArray[5] = {0,1,2,3,4}; adamstark@51: adamstark@51: PyObject* c=PyArray_SimpleNew(nd, &m, NPY_DOUBLE); adamstark@51: adamstark@51: void *arr_data = PyArray_DATA((PyArrayObject*)c); adamstark@51: adamstark@51: memcpy(arr_data, beats_out, PyArray_ITEMSIZE((PyArrayObject*) c) * m); adamstark@51: adamstark@51: adamstark@51: Py_DECREF(arr1); adamstark@51: Py_INCREF(Py_None); adamstark@51: //return Py_None; adamstark@51: adamstark@51: return (PyObject *)c; adamstark@51: } adamstark@51: adamstark@55: //======================================================================= adamstark@51: static PyMethodDef btrack_methods[] = { adamstark@61: { "calculateOnsetDF",btrack_calculateOnsetDF,METH_VARARGS,"Calculate the onset detection function"}, adamstark@61: { "trackBeats",btrack_trackBeats,METH_VARARGS,"Track beats from audio"}, adamstark@61: { "trackBeatsFromOnsetDF",btrack_trackBeatsFromOnsetDF,METH_VARARGS,"Track beats from an onset detection function"}, adamstark@51: {NULL, NULL, 0, NULL} /* Sentinel */ adamstark@51: }; adamstark@51: adamstark@55: //======================================================================= adamstark@51: PyMODINIT_FUNC initbtrack(void) adamstark@51: { adamstark@51: (void)Py_InitModule("btrack", btrack_methods); adamstark@51: import_array(); adamstark@51: } adamstark@51: adamstark@55: //======================================================================= adamstark@51: int main(int argc, char *argv[]) adamstark@51: { adamstark@51: /* Pass argv[0] to the Python interpreter */ adamstark@51: Py_SetProgramName(argv[0]); adamstark@51: adamstark@51: /* Initialize the Python interpreter. Required. */ adamstark@51: Py_Initialize(); adamstark@51: adamstark@51: /* Add a static module */ adamstark@51: initbtrack(); adamstark@51: }