annotate modules-and-plug-ins/python-module/btrack_python_module.cpp @ 24:deb49a2590f3 develop

Updated README, commented more code, added a Vamp plug-in
author Adam <adamstark.uk@gmail.com>
date Mon, 27 Jan 2014 23:11:31 +0000
parents a8e3e95d14e4
children 0fdaf082ad1a
rev   line source
adamstark@14 1 #include <iostream>
adamstark@14 2 #include <Python.h>
adamstark@14 3 #include "../../src/OnsetDetectionFunction.h"
adamstark@14 4 #include "../../src/BTrack.h"
adamstark@14 5 #include <numpy/arrayobject.h>
adamstark@14 6
adamstark@18 7 //=======================================================================
adamstark@24 8 static PyObject * btrack_trackBeats(PyObject *dummy, PyObject *args)
adamstark@24 9 {
adamstark@24 10 PyObject *arg1=NULL;
adamstark@24 11 PyObject *arr1=NULL;
adamstark@24 12
adamstark@24 13 if (!PyArg_ParseTuple(args, "O", &arg1))
adamstark@24 14 {
adamstark@24 15 return NULL;
adamstark@24 16 }
adamstark@24 17
adamstark@24 18 arr1 = PyArray_FROM_OTF(arg1, NPY_DOUBLE, NPY_IN_ARRAY);
adamstark@24 19 if (arr1 == NULL)
adamstark@24 20 {
adamstark@24 21 return NULL;
adamstark@24 22 }
adamstark@24 23
adamstark@24 24
adamstark@24 25
adamstark@24 26 ////////// GET INPUT DATA ///////////////////
adamstark@24 27
adamstark@24 28 // get data as array
adamstark@24 29 double* data = (double*) PyArray_DATA(arr1);
adamstark@24 30
adamstark@24 31 // get array size
adamstark@24 32 long signal_length = PyArray_Size((PyObject*)arr1);
adamstark@24 33
adamstark@24 34
adamstark@24 35 ////////// BEGIN PROCESS ///////////////////
adamstark@24 36 int hopSize = 512;
adamstark@24 37 int frameSize = 1024;
adamstark@24 38
adamstark@24 39 int numframes;
adamstark@24 40 double buffer[hopSize]; // buffer to hold one hopsize worth of audio samples
adamstark@24 41
adamstark@24 42
adamstark@24 43 // get number of audio frames, given the hop size and signal length
adamstark@24 44 numframes = (int) floor(((double) signal_length) / ((double) hopSize));
adamstark@24 45
adamstark@24 46
adamstark@24 47 BTrack b(hopSize,frameSize);
adamstark@24 48
adamstark@24 49
adamstark@24 50 double beats[5000];
adamstark@24 51 int beatnum = 0;
adamstark@24 52
adamstark@24 53 ///////////////////////////////////////////
adamstark@24 54 //////// Begin Processing Loop ////////////
adamstark@24 55
adamstark@24 56 for (int i=0;i < numframes;i++)
adamstark@24 57 {
adamstark@24 58 // add new samples to frame
adamstark@24 59 for (int n = 0;n < hopSize;n++)
adamstark@24 60 {
adamstark@24 61 buffer[n] = data[(i*hopSize)+n];
adamstark@24 62 }
adamstark@24 63
adamstark@24 64 // process the current audio frame
adamstark@24 65 b.processAudioFrame(buffer);
adamstark@24 66
adamstark@24 67 // if a beat is currently scheduled
adamstark@24 68 if (b.beatDueInCurrentFrame())
adamstark@24 69 {
adamstark@24 70 beats[beatnum] = BTrack::getBeatTimeInSeconds(i,hopSize,44100);
adamstark@24 71 beatnum = beatnum + 1;
adamstark@24 72 }
adamstark@24 73
adamstark@24 74 }
adamstark@24 75
adamstark@24 76 ///////// End Processing Loop /////////////
adamstark@24 77 ///////////////////////////////////////////
adamstark@24 78
adamstark@24 79
adamstark@24 80 ////////// END PROCESS ///////////////////
adamstark@24 81
adamstark@24 82 double beats_out[beatnum]; // create output array
adamstark@24 83
adamstark@24 84 // copy beats into output array
adamstark@24 85 for (int i = 0;i < beatnum;i++)
adamstark@24 86 {
adamstark@24 87 beats_out[i] = beats[i];
adamstark@24 88 }
adamstark@24 89
adamstark@24 90
adamstark@24 91
adamstark@24 92 ////////// CREATE ARRAY AND RETURN IT ///////////////////
adamstark@24 93 int nd=1;
adamstark@24 94 npy_intp m= beatnum;
adamstark@24 95 //double fArray[5] = {0,1,2,3,4};
adamstark@24 96
adamstark@24 97 PyObject* c=PyArray_SimpleNew(nd, &m, NPY_DOUBLE);
adamstark@24 98
adamstark@24 99 void *arr_data = PyArray_DATA((PyArrayObject*)c);
adamstark@24 100
adamstark@24 101 memcpy(arr_data, beats_out, PyArray_ITEMSIZE((PyArrayObject*) c) * m);
adamstark@24 102
adamstark@24 103
adamstark@24 104 Py_DECREF(arr1);
adamstark@24 105 Py_INCREF(Py_None);
adamstark@24 106 //return Py_None;
adamstark@24 107
adamstark@24 108 return (PyObject *)c;
adamstark@24 109 }
adamstark@24 110
adamstark@24 111
adamstark@24 112 //=======================================================================
adamstark@24 113 static PyObject * btrack_calculateOnsetDF(PyObject *dummy, PyObject *args)
adamstark@14 114 {
adamstark@14 115 PyObject *arg1=NULL;
adamstark@14 116 PyObject *arr1=NULL;
adamstark@14 117
adamstark@14 118 if (!PyArg_ParseTuple(args, "O", &arg1))
adamstark@14 119 {
adamstark@14 120 return NULL;
adamstark@14 121 }
adamstark@14 122
adamstark@14 123 arr1 = PyArray_FROM_OTF(arg1, NPY_DOUBLE, NPY_IN_ARRAY);
adamstark@14 124 if (arr1 == NULL)
adamstark@14 125 {
adamstark@14 126 return NULL;
adamstark@14 127 }
adamstark@14 128
adamstark@14 129
adamstark@14 130
adamstark@14 131 ////////// GET INPUT DATA ///////////////////
adamstark@14 132
adamstark@14 133 // get data as array
adamstark@14 134 double* data = (double*) PyArray_DATA(arr1);
adamstark@14 135
adamstark@14 136 // get array size
adamstark@15 137 long signal_length = PyArray_Size((PyObject*)arr1);
adamstark@14 138
adamstark@14 139 ////////// BEGIN PROCESS ///////////////////
adamstark@18 140 int hopSize = 512;
adamstark@18 141 int frameSize = 1024;
adamstark@14 142 int df_type = 6;
adamstark@14 143 int numframes;
adamstark@18 144 double buffer[hopSize]; // buffer to hold one hopsize worth of audio samples
adamstark@14 145
adamstark@14 146
adamstark@14 147 // get number of audio frames, given the hop size and signal length
adamstark@18 148 numframes = (int) floor(((double) signal_length) / ((double) hopSize));
adamstark@14 149
adamstark@18 150 OnsetDetectionFunction onset(hopSize,frameSize,df_type,1);
adamstark@14 151
adamstark@14 152 double df[numframes];
adamstark@14 153
adamstark@14 154
adamstark@14 155
adamstark@14 156 ///////////////////////////////////////////
adamstark@14 157 //////// Begin Processing Loop ////////////
adamstark@14 158
adamstark@14 159 for (int i=0;i < numframes;i++)
adamstark@14 160 {
adamstark@14 161 // add new samples to frame
adamstark@18 162 for (int n = 0;n < hopSize;n++)
adamstark@14 163 {
adamstark@18 164 buffer[n] = data[(i*hopSize)+n];
adamstark@14 165 }
adamstark@14 166
adamstark@22 167 df[i] = onset.calculateOnsetDetectionFunctionSample(buffer);
adamstark@14 168
adamstark@14 169 }
adamstark@14 170
adamstark@14 171 ///////// End Processing Loop /////////////
adamstark@14 172 ///////////////////////////////////////////
adamstark@14 173
adamstark@14 174
adamstark@24 175
adamstark@14 176
adamstark@14 177 ////////// CREATE ARRAY AND RETURN IT ///////////////////
adamstark@14 178 int nd=1;
adamstark@14 179 npy_intp m= numframes;
adamstark@24 180
adamstark@14 181
adamstark@14 182 PyObject* c=PyArray_SimpleNew(nd, &m, NPY_DOUBLE);
adamstark@14 183
adamstark@14 184 void *arr_data = PyArray_DATA((PyArrayObject*)c);
adamstark@14 185
adamstark@14 186 memcpy(arr_data, df, PyArray_ITEMSIZE((PyArrayObject*) c) * m);
adamstark@14 187
adamstark@14 188
adamstark@14 189 Py_DECREF(arr1);
adamstark@14 190 Py_INCREF(Py_None);
adamstark@14 191 //return Py_None;
adamstark@14 192
adamstark@14 193 return (PyObject *)c;
adamstark@14 194 }
adamstark@14 195
adamstark@14 196
adamstark@18 197 //=======================================================================
adamstark@24 198 static PyObject * btrack_trackBeatsFromOnsetDF(PyObject *dummy, PyObject *args)
adamstark@14 199 {
adamstark@14 200 PyObject *arg1=NULL;
adamstark@14 201 PyObject *arr1=NULL;
adamstark@14 202
adamstark@14 203 if (!PyArg_ParseTuple(args, "O", &arg1))
adamstark@14 204 {
adamstark@14 205 return NULL;
adamstark@14 206 }
adamstark@14 207
adamstark@14 208 arr1 = PyArray_FROM_OTF(arg1, NPY_DOUBLE, NPY_IN_ARRAY);
adamstark@14 209 if (arr1 == NULL)
adamstark@14 210 {
adamstark@14 211 return NULL;
adamstark@14 212 }
adamstark@14 213
adamstark@14 214
adamstark@14 215
adamstark@14 216 ////////// GET INPUT DATA ///////////////////
adamstark@14 217
adamstark@14 218 // get data as array
adamstark@14 219 double* data = (double*) PyArray_DATA(arr1);
adamstark@14 220
adamstark@14 221 // get array size
adamstark@15 222 long numframes = PyArray_Size((PyObject*)arr1);
adamstark@18 223
adamstark@14 224 ////////// BEGIN PROCESS ///////////////////
adamstark@18 225 int hopSize = 512;
adamstark@18 226 int frameSize = 2*hopSize;
adamstark@14 227
adamstark@18 228 BTrack b(hopSize,frameSize);
adamstark@14 229
adamstark@14 230 double beats[5000];
adamstark@14 231 int beatnum = 0;
adamstark@17 232 double df_val;
adamstark@14 233
adamstark@14 234 ///////////////////////////////////////////
adamstark@14 235 //////// Begin Processing Loop ////////////
adamstark@14 236
adamstark@15 237 for (long i=0;i < numframes;i++)
adamstark@14 238 {
adamstark@17 239 df_val = data[i] + 0.0001;
adamstark@14 240
adamstark@18 241 b.processOnsetDetectionFunctionSample(df_val); // process df sample in beat tracker
adamstark@14 242
adamstark@20 243 if (b.beatDueInCurrentFrame())
adamstark@14 244 {
adamstark@18 245 beats[beatnum] = BTrack::getBeatTimeInSeconds(i,hopSize,44100);
adamstark@14 246 beatnum = beatnum + 1;
adamstark@14 247 }
adamstark@14 248
adamstark@14 249 }
adamstark@14 250
adamstark@14 251 ///////// End Processing Loop /////////////
adamstark@14 252 ///////////////////////////////////////////
adamstark@14 253
adamstark@14 254
adamstark@14 255 ////////// END PROCESS ///////////////////
adamstark@14 256
adamstark@14 257 double beats_out[beatnum]; // create output array
adamstark@14 258
adamstark@14 259
adamstark@14 260 // copy beats into output array
adamstark@14 261 for (int i = 0;i < beatnum;i++)
adamstark@14 262 {
adamstark@14 263 beats_out[i] = beats[i];
adamstark@14 264 }
adamstark@14 265
adamstark@14 266
adamstark@14 267 ////////// CREATE ARRAY AND RETURN IT ///////////////////
adamstark@14 268 int nd=1;
adamstark@14 269 npy_intp m= beatnum;
adamstark@14 270 //double fArray[5] = {0,1,2,3,4};
adamstark@14 271
adamstark@14 272 PyObject* c=PyArray_SimpleNew(nd, &m, NPY_DOUBLE);
adamstark@14 273
adamstark@14 274 void *arr_data = PyArray_DATA((PyArrayObject*)c);
adamstark@14 275
adamstark@14 276 memcpy(arr_data, beats_out, PyArray_ITEMSIZE((PyArrayObject*) c) * m);
adamstark@14 277
adamstark@14 278
adamstark@14 279 Py_DECREF(arr1);
adamstark@14 280 Py_INCREF(Py_None);
adamstark@14 281 //return Py_None;
adamstark@14 282
adamstark@14 283 return (PyObject *)c;
adamstark@14 284 }
adamstark@14 285
adamstark@18 286 //=======================================================================
adamstark@14 287 static PyMethodDef btrack_methods[] = {
adamstark@24 288 { "calculateOnsetDF",btrack_calculateOnsetDF,METH_VARARGS,"Calculate the onset detection function"},
adamstark@24 289 { "trackBeats",btrack_trackBeats,METH_VARARGS,"Track beats from audio"},
adamstark@24 290 { "trackBeatsFromOnsetDF",btrack_trackBeatsFromOnsetDF,METH_VARARGS,"Track beats from an onset detection function"},
adamstark@14 291 {NULL, NULL, 0, NULL} /* Sentinel */
adamstark@14 292 };
adamstark@14 293
adamstark@18 294 //=======================================================================
adamstark@14 295 PyMODINIT_FUNC initbtrack(void)
adamstark@14 296 {
adamstark@14 297 (void)Py_InitModule("btrack", btrack_methods);
adamstark@14 298 import_array();
adamstark@14 299 }
adamstark@14 300
adamstark@18 301 //=======================================================================
adamstark@14 302 int main(int argc, char *argv[])
adamstark@14 303 {
adamstark@14 304 /* Pass argv[0] to the Python interpreter */
adamstark@14 305 Py_SetProgramName(argv[0]);
adamstark@14 306
adamstark@14 307 /* Initialize the Python interpreter. Required. */
adamstark@14 308 Py_Initialize();
adamstark@14 309
adamstark@14 310 /* Add a static module */
adamstark@14 311 initbtrack();
adamstark@14 312 }