comparison modules-and-plug-ins/python-module/btrack_python_module.cpp @ 18:450c53430540 develop

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 <adamstark.uk@gmail.com>
date Wed, 22 Jan 2014 18:47:16 +0000
parents a31841af2bbc
children baf35f208814
comparison
equal deleted inserted replaced
17:a31841af2bbc 18:450c53430540
2 #include <Python.h> 2 #include <Python.h>
3 #include "../../src/OnsetDetectionFunction.h" 3 #include "../../src/OnsetDetectionFunction.h"
4 #include "../../src/BTrack.h" 4 #include "../../src/BTrack.h"
5 #include <numpy/arrayobject.h> 5 #include <numpy/arrayobject.h>
6 6
7 //=======================================================================
7 static PyObject * btrack_onsetdf(PyObject *dummy, PyObject *args) 8 static PyObject * btrack_onsetdf(PyObject *dummy, PyObject *args)
8 { 9 {
9 PyObject *arg1=NULL; 10 PyObject *arg1=NULL;
10 PyObject *arr1=NULL; 11 PyObject *arr1=NULL;
11 12
27 // get data as array 28 // get data as array
28 double* data = (double*) PyArray_DATA(arr1); 29 double* data = (double*) PyArray_DATA(arr1);
29 30
30 // get array size 31 // get array size
31 long signal_length = PyArray_Size((PyObject*)arr1); 32 long signal_length = PyArray_Size((PyObject*)arr1);
32 //int k = (int) theSize;
33
34 // get data type
35 //char type = PyArray_DESCR(arr1)->type;
36 33
37 ////////// BEGIN PROCESS /////////////////// 34 ////////// BEGIN PROCESS ///////////////////
38 int hsize = 512; 35 int hopSize = 512;
39 int fsize = 1024; 36 int frameSize = 1024;
40 int df_type = 6; 37 int df_type = 6;
41 int numframes; 38 int numframes;
42 double buffer[hsize]; // buffer to hold one hopsize worth of audio samples 39 double buffer[hopSize]; // buffer to hold one hopsize worth of audio samples
43 40
44 41
45 // get number of audio frames, given the hop size and signal length 42 // get number of audio frames, given the hop size and signal length
46 numframes = (int) floor(((double) signal_length) / ((double) hsize)); 43 numframes = (int) floor(((double) signal_length) / ((double) hopSize));
47 44
48 OnsetDetectionFunction onset(hsize,fsize,df_type,1); 45 OnsetDetectionFunction onset(hopSize,frameSize,df_type,1);
49 46
50 double df[numframes]; 47 double df[numframes];
51 48
52 49
53 50
55 //////// Begin Processing Loop //////////// 52 //////// Begin Processing Loop ////////////
56 53
57 for (int i=0;i < numframes;i++) 54 for (int i=0;i < numframes;i++)
58 { 55 {
59 // add new samples to frame 56 // add new samples to frame
60 for (int n = 0;n < hsize;n++) 57 for (int n = 0;n < hopSize;n++)
61 { 58 {
62 buffer[n] = data[(i*hsize)+n]; 59 buffer[n] = data[(i*hopSize)+n];
63 } 60 }
64 61
65 df[i] = onset.getDFsample(buffer); 62 df[i] = onset.getDFsample(buffer);
66 63
67 } 64 }
89 Py_DECREF(arr1); 86 Py_DECREF(arr1);
90 Py_INCREF(Py_None); 87 Py_INCREF(Py_None);
91 //return Py_None; 88 //return Py_None;
92 89
93 return (PyObject *)c; 90 return (PyObject *)c;
94 91 }
95 //return Py_BuildValue("c", type); 92
96 //return Py_BuildValue("d", sum); 93 //=======================================================================
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) 94 static PyObject * btrack_btrack(PyObject *dummy, PyObject *args)
108 { 95 {
109 PyObject *arg1=NULL; 96 PyObject *arg1=NULL;
110 PyObject *arr1=NULL; 97 PyObject *arr1=NULL;
111 98
127 // get data as array 114 // get data as array
128 double* data = (double*) PyArray_DATA(arr1); 115 double* data = (double*) PyArray_DATA(arr1);
129 116
130 // get array size 117 // get array size
131 long signal_length = PyArray_Size((PyObject*)arr1); 118 long signal_length = PyArray_Size((PyObject*)arr1);
132 //int k = (int) theSize; 119
133
134 // get data type
135 //char type = PyArray_DESCR(arr1)->type;
136 120
137 ////////// BEGIN PROCESS /////////////////// 121 ////////// BEGIN PROCESS ///////////////////
138 int hsize = 512; 122 int hopSize = 512;
139 int fsize = 1024; 123 int frameSize = 1024;
140 int df_type = 6; 124
141 int numframes; 125 int numframes;
142 double buffer[hsize]; // buffer to hold one hopsize worth of audio samples 126 double buffer[hopSize]; // buffer to hold one hopsize worth of audio samples
143 127
144 128
145 // get number of audio frames, given the hop size and signal length 129 // get number of audio frames, given the hop size and signal length
146 numframes = (int) floor(((double) signal_length) / ((double) hsize)); 130 numframes = (int) floor(((double) signal_length) / ((double) hopSize));
147 131
148 OnsetDetectionFunction onset(hsize,fsize,df_type,1); 132
149 BTrack b; 133 BTrack b(hopSize,frameSize);
150 134
151 b.initialise((int) hsize); // initialise beat tracker 135
152
153 // set parameters
154 //b.setparams(0.9,5);
155
156 double df[numframes];
157 double beats[5000]; 136 double beats[5000];
158 int beatnum = 0; 137 int beatnum = 0;
159
160 double df_val;
161 138
162 /////////////////////////////////////////// 139 ///////////////////////////////////////////
163 //////// Begin Processing Loop //////////// 140 //////// Begin Processing Loop ////////////
164 141
165 for (int i=0;i < numframes;i++) 142 for (int i=0;i < numframes;i++)
166 { 143 {
167 // add new samples to frame 144 // add new samples to frame
168 for (int n = 0;n < hsize;n++) 145 for (int n = 0;n < hopSize;n++)
169 { 146 {
170 buffer[n] = data[(i*hsize)+n]; 147 buffer[n] = data[(i*hopSize)+n];
171 } 148 }
172 149
173 df[i] = onset.getDFsample(buffer); 150 // process the current audio frame
151 b.processAudioFrame(buffer);
174 152
175 df_val = df[i] + 0.0001; 153 // if a beat is currently scheduled
176
177 b.process(df_val); // process df sample in beat tracker
178
179 if (b.playbeat == 1) 154 if (b.playbeat == 1)
180 { 155 {
181 beats[beatnum] = (((double) hsize) / 44100) * ((double) i); 156 //beats[beatnum] = (((double) hopSize) / 44100) * ((double) i);
182 beatnum = beatnum + 1; 157 beats[beatnum] = BTrack::getBeatTimeInSeconds(i,hopSize,44100);
158 beatnum = beatnum + 1;
183 } 159 }
184 160
185 } 161 }
186 162
187 ///////// End Processing Loop ///////////// 163 ///////// End Processing Loop /////////////
215 Py_DECREF(arr1); 191 Py_DECREF(arr1);
216 Py_INCREF(Py_None); 192 Py_INCREF(Py_None);
217 //return Py_None; 193 //return Py_None;
218 194
219 return (PyObject *)c; 195 return (PyObject *)c;
220 196 }
221 //return Py_BuildValue("c", type); 197
222 //return Py_BuildValue("d", sum); 198 //=======================================================================
223 //return Py_BuildValue("i", k);
224 /*
225 fail:
226 Py_XDECREF(arr1);
227 Py_XDECREF(arr2);
228 PyArray_XDECREF_ERR(oarr);
229 return NULL;*/
230 }
231
232 static PyObject * btrack_btrack_df(PyObject *dummy, PyObject *args) 199 static PyObject * btrack_btrack_df(PyObject *dummy, PyObject *args)
233 { 200 {
234 PyObject *arg1=NULL; 201 PyObject *arg1=NULL;
235 PyObject *arr1=NULL; 202 PyObject *arr1=NULL;
236 203
252 // get data as array 219 // get data as array
253 double* data = (double*) PyArray_DATA(arr1); 220 double* data = (double*) PyArray_DATA(arr1);
254 221
255 // get array size 222 // get array size
256 long numframes = PyArray_Size((PyObject*)arr1); 223 long numframes = PyArray_Size((PyObject*)arr1);
257 //int k = (int) theSize; 224
258
259 // get data type
260 //char type = PyArray_DESCR(arr1)->type;
261
262 ////////// BEGIN PROCESS /////////////////// 225 ////////// BEGIN PROCESS ///////////////////
263 int hsize = 512; 226 int hopSize = 512;
264 227 int frameSize = 2*hopSize;
265 BTrack b; 228
266 229 BTrack b(hopSize,frameSize);
267 b.initialise((int) hsize); // initialise beat tracker
268
269 // set parameters
270 //b.setparams(0.9,5);
271 230
272 double beats[5000]; 231 double beats[5000];
273 int beatnum = 0; 232 int beatnum = 0;
274 double df_val; 233 double df_val;
275 234
278 237
279 for (long i=0;i < numframes;i++) 238 for (long i=0;i < numframes;i++)
280 { 239 {
281 df_val = data[i] + 0.0001; 240 df_val = data[i] + 0.0001;
282 241
283 b.process(df_val); // process df sample in beat tracker 242 b.processOnsetDetectionFunctionSample(df_val); // process df sample in beat tracker
284 243
285 if (b.playbeat == 1) 244 if (b.playbeat == 1)
286 { 245 {
287 beats[beatnum] = (((double) hsize) / 44100) * ((double) i); 246 //beats[beatnum] = (((double) hopSize) / 44100) * ((double) i);
247 beats[beatnum] = BTrack::getBeatTimeInSeconds(i,hopSize,44100);
288 beatnum = beatnum + 1; 248 beatnum = beatnum + 1;
289 } 249 }
290 250
291 } 251 }
292 252
321 Py_DECREF(arr1); 281 Py_DECREF(arr1);
322 Py_INCREF(Py_None); 282 Py_INCREF(Py_None);
323 //return Py_None; 283 //return Py_None;
324 284
325 return (PyObject *)c; 285 return (PyObject *)c;
326 286 }
327 //return Py_BuildValue("c", type); 287
328 //return Py_BuildValue("d", sum); 288
329 //return Py_BuildValue("i", k); 289 //=======================================================================
330 /*
331 fail:
332 Py_XDECREF(arr1);
333 Py_XDECREF(arr2);
334 PyArray_XDECREF_ERR(oarr);
335 return NULL;*/
336 }
337
338
339
340 static PyMethodDef btrack_methods[] = { 290 static PyMethodDef btrack_methods[] = {
341 { "onsetdf",btrack_onsetdf,METH_VARARGS,"onset detection function"}, 291 { "onsetdf",btrack_onsetdf,METH_VARARGS,"onset detection function"},
342 { "btrack",btrack_btrack,METH_VARARGS,"beat tracker"}, 292 { "btrack",btrack_btrack,METH_VARARGS,"beat tracker"},
343 { "btrack_df",btrack_btrack_df,METH_VARARGS,"beat tracker with detection function input"}, 293 { "btrack_df",btrack_btrack_df,METH_VARARGS,"beat tracker with detection function input"},
344 {NULL, NULL, 0, NULL} /* Sentinel */ 294 {NULL, NULL, 0, NULL} /* Sentinel */
345 }; 295 };
346 296
297 //=======================================================================
347 PyMODINIT_FUNC initbtrack(void) 298 PyMODINIT_FUNC initbtrack(void)
348 { 299 {
349 (void)Py_InitModule("btrack", btrack_methods); 300 (void)Py_InitModule("btrack", btrack_methods);
350 import_array(); 301 import_array();
351 } 302 }
352 303
304 //=======================================================================
353 int main(int argc, char *argv[]) 305 int main(int argc, char *argv[])
354 { 306 {
355 /* Pass argv[0] to the Python interpreter */ 307 /* Pass argv[0] to the Python interpreter */
356 Py_SetProgramName(argv[0]); 308 Py_SetProgramName(argv[0]);
357 309