Mercurial > hg > btrack
comparison modules-and-plug-ins/python-module/btrack_python_module.cpp @ 51:68d01fea1e8d
Added a unit testing project, and did some commenting. Also moved python-module into a modules-and-plug-ins folder
| author | Adam Stark <adamstark@users.noreply.github.com> |
|---|---|
| date | Tue, 21 Jan 2014 10:24:33 +0000 |
| parents | |
| children | 2b94d3d2fb9d |
comparison
equal
deleted
inserted
replaced
| 50:bb3803edaa17 | 51:68d01fea1e8d |
|---|---|
| 1 #include <iostream> | |
| 2 #include <Python.h> | |
| 3 #include "../../src/OnsetDetectionFunction.h" | |
| 4 #include "../../src/BTrack.h" | |
| 5 #include <numpy/arrayobject.h> | |
| 6 | |
| 7 static PyObject * btrack_onsetdf(PyObject *dummy, PyObject *args) | |
| 8 { | |
| 9 PyObject *arg1=NULL; | |
| 10 PyObject *arr1=NULL; | |
| 11 | |
| 12 if (!PyArg_ParseTuple(args, "O", &arg1)) | |
| 13 { | |
| 14 return NULL; | |
| 15 } | |
| 16 | |
| 17 arr1 = PyArray_FROM_OTF(arg1, NPY_DOUBLE, NPY_IN_ARRAY); | |
| 18 if (arr1 == NULL) | |
| 19 { | |
| 20 return NULL; | |
| 21 } | |
| 22 | |
| 23 | |
| 24 | |
| 25 ////////// GET INPUT DATA /////////////////// | |
| 26 | |
| 27 // get data as array | |
| 28 double* data = (double*) PyArray_DATA(arr1); | |
| 29 | |
| 30 // get array size | |
| 31 int signal_length = PyArray_Size((PyObject*)arr1); | |
| 32 //int k = (int) theSize; | |
| 33 | |
| 34 // get data type | |
| 35 char type = PyArray_DESCR(arr1)->type; | |
| 36 | |
| 37 ////////// BEGIN PROCESS /////////////////// | |
| 38 int hsize = 512; | |
| 39 int fsize = 1024; | |
| 40 int df_type = 6; | |
| 41 int numframes; | |
| 42 double buffer[hsize]; // buffer to hold one hopsize worth of audio samples | |
| 43 | |
| 44 | |
| 45 // get number of audio frames, given the hop size and signal length | |
| 46 numframes = (int) floor(((double) signal_length) / ((double) hsize)); | |
| 47 | |
| 48 OnsetDetectionFunction onset(hsize,fsize,df_type,1); | |
| 49 | |
| 50 double df[numframes]; | |
| 51 | |
| 52 | |
| 53 | |
| 54 /////////////////////////////////////////// | |
| 55 //////// Begin Processing Loop //////////// | |
| 56 | |
| 57 for (int i=0;i < numframes;i++) | |
| 58 { | |
| 59 // add new samples to frame | |
| 60 for (int n = 0;n < hsize;n++) | |
| 61 { | |
| 62 buffer[n] = data[(i*hsize)+n]; | |
| 63 } | |
| 64 | |
| 65 df[i] = onset.getDFsample(buffer); | |
| 66 | |
| 67 } | |
| 68 | |
| 69 ///////// End Processing Loop ///////////// | |
| 70 /////////////////////////////////////////// | |
| 71 | |
| 72 | |
| 73 ////////// END PROCESS /////////////////// | |
| 74 | |
| 75 | |
| 76 | |
| 77 ////////// CREATE ARRAY AND RETURN IT /////////////////// | |
| 78 int nd=1; | |
| 79 npy_intp m= numframes; | |
| 80 //double fArray[5] = {0,1,2,3,4}; | |
| 81 | |
| 82 PyObject* c=PyArray_SimpleNew(nd, &m, NPY_DOUBLE); | |
| 83 | |
| 84 void *arr_data = PyArray_DATA((PyArrayObject*)c); | |
| 85 | |
| 86 memcpy(arr_data, df, PyArray_ITEMSIZE((PyArrayObject*) c) * m); | |
| 87 | |
| 88 | |
| 89 Py_DECREF(arr1); | |
| 90 Py_INCREF(Py_None); | |
| 91 //return Py_None; | |
| 92 | |
| 93 return (PyObject *)c; | |
| 94 | |
| 95 //return Py_BuildValue("c", type); | |
| 96 //return Py_BuildValue("d", sum); | |
| 97 //return Py_BuildValue("i", k); | |
| 98 /* | |
| 99 fail: | |
| 100 Py_XDECREF(arr1); | |
| 101 Py_XDECREF(arr2); | |
| 102 PyArray_XDECREF_ERR(oarr); | |
| 103 return NULL;*/ | |
| 104 } | |
| 105 | |
| 106 | |
| 107 static PyObject * btrack_btrack(PyObject *dummy, PyObject *args) | |
| 108 { | |
| 109 PyObject *arg1=NULL; | |
| 110 PyObject *arr1=NULL; | |
| 111 | |
| 112 if (!PyArg_ParseTuple(args, "O", &arg1)) | |
| 113 { | |
| 114 return NULL; | |
| 115 } | |
| 116 | |
| 117 arr1 = PyArray_FROM_OTF(arg1, NPY_DOUBLE, NPY_IN_ARRAY); | |
| 118 if (arr1 == NULL) | |
| 119 { | |
| 120 return NULL; | |
| 121 } | |
| 122 | |
| 123 | |
| 124 | |
| 125 ////////// GET INPUT DATA /////////////////// | |
| 126 | |
| 127 // get data as array | |
| 128 double* data = (double*) PyArray_DATA(arr1); | |
| 129 | |
| 130 // get array size | |
| 131 int signal_length = PyArray_Size((PyObject*)arr1); | |
| 132 //int k = (int) theSize; | |
| 133 | |
| 134 // get data type | |
| 135 char type = PyArray_DESCR(arr1)->type; | |
| 136 | |
| 137 ////////// BEGIN PROCESS /////////////////// | |
| 138 int hsize = 512; | |
| 139 int fsize = 1024; | |
| 140 int df_type = 6; | |
| 141 int numframes; | |
| 142 double buffer[hsize]; // buffer to hold one hopsize worth of audio samples | |
| 143 | |
| 144 | |
| 145 // get number of audio frames, given the hop size and signal length | |
| 146 numframes = (int) floor(((double) signal_length) / ((double) hsize)); | |
| 147 | |
| 148 OnsetDetectionFunction onset(hsize,fsize,df_type,1); | |
| 149 BTrack b; | |
| 150 | |
| 151 b.initialise((int) hsize); // initialise beat tracker | |
| 152 | |
| 153 // set parameters | |
| 154 //b.setparams(0.9,5); | |
| 155 | |
| 156 double df[numframes]; | |
| 157 double beats[5000]; | |
| 158 int beatnum = 0; | |
| 159 float df_val; | |
| 160 | |
| 161 /////////////////////////////////////////// | |
| 162 //////// Begin Processing Loop //////////// | |
| 163 | |
| 164 for (int i=0;i < numframes;i++) | |
| 165 { | |
| 166 // add new samples to frame | |
| 167 for (int n = 0;n < hsize;n++) | |
| 168 { | |
| 169 buffer[n] = data[(i*hsize)+n]; | |
| 170 } | |
| 171 | |
| 172 df[i] = onset.getDFsample(buffer); | |
| 173 | |
| 174 df_val = (float) (df[i] + 0.0001); | |
| 175 | |
| 176 b.process(df_val); // process df sample in beat tracker | |
| 177 | |
| 178 if (b.playbeat == 1) | |
| 179 { | |
| 180 beats[beatnum] = (((double) hsize) / 44100) * ((double) i); | |
| 181 beatnum = beatnum + 1; | |
| 182 } | |
| 183 | |
| 184 } | |
| 185 | |
| 186 ///////// End Processing Loop ///////////// | |
| 187 /////////////////////////////////////////// | |
| 188 | |
| 189 | |
| 190 ////////// END PROCESS /////////////////// | |
| 191 | |
| 192 double beats_out[beatnum]; // create output array | |
| 193 | |
| 194 // copy beats into output array | |
| 195 for (int i = 0;i < beatnum;i++) | |
| 196 { | |
| 197 beats_out[i] = beats[i]; | |
| 198 } | |
| 199 | |
| 200 | |
| 201 | |
| 202 ////////// CREATE ARRAY AND RETURN IT /////////////////// | |
| 203 int nd=1; | |
| 204 npy_intp m= beatnum; | |
| 205 //double fArray[5] = {0,1,2,3,4}; | |
| 206 | |
| 207 PyObject* c=PyArray_SimpleNew(nd, &m, NPY_DOUBLE); | |
| 208 | |
| 209 void *arr_data = PyArray_DATA((PyArrayObject*)c); | |
| 210 | |
| 211 memcpy(arr_data, beats_out, PyArray_ITEMSIZE((PyArrayObject*) c) * m); | |
| 212 | |
| 213 | |
| 214 Py_DECREF(arr1); | |
| 215 Py_INCREF(Py_None); | |
| 216 //return Py_None; | |
| 217 | |
| 218 return (PyObject *)c; | |
| 219 | |
| 220 //return Py_BuildValue("c", type); | |
| 221 //return Py_BuildValue("d", sum); | |
| 222 //return Py_BuildValue("i", k); | |
| 223 /* | |
| 224 fail: | |
| 225 Py_XDECREF(arr1); | |
| 226 Py_XDECREF(arr2); | |
| 227 PyArray_XDECREF_ERR(oarr); | |
| 228 return NULL;*/ | |
| 229 } | |
| 230 | |
| 231 static PyObject * btrack_btrack_df(PyObject *dummy, PyObject *args) | |
| 232 { | |
| 233 PyObject *arg1=NULL; | |
| 234 PyObject *arr1=NULL; | |
| 235 | |
| 236 if (!PyArg_ParseTuple(args, "O", &arg1)) | |
| 237 { | |
| 238 return NULL; | |
| 239 } | |
| 240 | |
| 241 arr1 = PyArray_FROM_OTF(arg1, NPY_DOUBLE, NPY_IN_ARRAY); | |
| 242 if (arr1 == NULL) | |
| 243 { | |
| 244 return NULL; | |
| 245 } | |
| 246 | |
| 247 | |
| 248 | |
| 249 ////////// GET INPUT DATA /////////////////// | |
| 250 | |
| 251 // get data as array | |
| 252 double* data = (double*) PyArray_DATA(arr1); | |
| 253 | |
| 254 // get array size | |
| 255 int numframes = PyArray_Size((PyObject*)arr1); | |
| 256 //int k = (int) theSize; | |
| 257 | |
| 258 // get data type | |
| 259 char type = PyArray_DESCR(arr1)->type; | |
| 260 | |
| 261 ////////// BEGIN PROCESS /////////////////// | |
| 262 int hsize = 512; | |
| 263 | |
| 264 BTrack b; | |
| 265 | |
| 266 b.initialise((int) hsize); // initialise beat tracker | |
| 267 | |
| 268 // set parameters | |
| 269 //b.setparams(0.9,5); | |
| 270 | |
| 271 double beats[5000]; | |
| 272 int beatnum = 0; | |
| 273 float df_val; | |
| 274 | |
| 275 /////////////////////////////////////////// | |
| 276 //////// Begin Processing Loop //////////// | |
| 277 | |
| 278 for (int i=0;i < numframes;i++) | |
| 279 { | |
| 280 df_val = (float) (data[i] + 0.0001); | |
| 281 | |
| 282 b.process(df_val); // process df sample in beat tracker | |
| 283 | |
| 284 if (b.playbeat == 1) | |
| 285 { | |
| 286 beats[beatnum] = (((double) hsize) / 44100) * ((double) i); | |
| 287 beatnum = beatnum + 1; | |
| 288 } | |
| 289 | |
| 290 } | |
| 291 | |
| 292 ///////// End Processing Loop ///////////// | |
| 293 /////////////////////////////////////////// | |
| 294 | |
| 295 | |
| 296 ////////// END PROCESS /////////////////// | |
| 297 | |
| 298 double beats_out[beatnum]; // create output array | |
| 299 | |
| 300 | |
| 301 // copy beats into output array | |
| 302 for (int i = 0;i < beatnum;i++) | |
| 303 { | |
| 304 beats_out[i] = beats[i]; | |
| 305 } | |
| 306 | |
| 307 | |
| 308 ////////// CREATE ARRAY AND RETURN IT /////////////////// | |
| 309 int nd=1; | |
| 310 npy_intp m= beatnum; | |
| 311 //double fArray[5] = {0,1,2,3,4}; | |
| 312 | |
| 313 PyObject* c=PyArray_SimpleNew(nd, &m, NPY_DOUBLE); | |
| 314 | |
| 315 void *arr_data = PyArray_DATA((PyArrayObject*)c); | |
| 316 | |
| 317 memcpy(arr_data, beats_out, PyArray_ITEMSIZE((PyArrayObject*) c) * m); | |
| 318 | |
| 319 | |
| 320 Py_DECREF(arr1); | |
| 321 Py_INCREF(Py_None); | |
| 322 //return Py_None; | |
| 323 | |
| 324 return (PyObject *)c; | |
| 325 | |
| 326 //return Py_BuildValue("c", type); | |
| 327 //return Py_BuildValue("d", sum); | |
| 328 //return Py_BuildValue("i", k); | |
| 329 /* | |
| 330 fail: | |
| 331 Py_XDECREF(arr1); | |
| 332 Py_XDECREF(arr2); | |
| 333 PyArray_XDECREF_ERR(oarr); | |
| 334 return NULL;*/ | |
| 335 } | |
| 336 | |
| 337 | |
| 338 | |
| 339 static PyMethodDef btrack_methods[] = { | |
| 340 { "onsetdf",btrack_onsetdf,METH_VARARGS,"onset detection function"}, | |
| 341 { "btrack",btrack_btrack,METH_VARARGS,"beat tracker"}, | |
| 342 { "btrack_df",btrack_btrack_df,METH_VARARGS,"beat tracker with detection function input"}, | |
| 343 {NULL, NULL, 0, NULL} /* Sentinel */ | |
| 344 }; | |
| 345 | |
| 346 PyMODINIT_FUNC initbtrack(void) | |
| 347 { | |
| 348 (void)Py_InitModule("btrack", btrack_methods); | |
| 349 import_array(); | |
| 350 } | |
| 351 | |
| 352 int main(int argc, char *argv[]) | |
| 353 { | |
| 354 /* Pass argv[0] to the Python interpreter */ | |
| 355 Py_SetProgramName(argv[0]); | |
| 356 | |
| 357 /* Initialize the Python interpreter. Required. */ | |
| 358 Py_Initialize(); | |
| 359 | |
| 360 /* Add a static module */ | |
| 361 initbtrack(); | |
| 362 } |
