Mercurial > hg > btrack
comparison modules-and-plug-ins/python-module/btrack_python_module.cpp @ 14:18fc3c248436 develop
Added a unit testing project, and did some commenting. Also moved python-module into a modules-and-plug-ins folder
author | Adam <adamstark.uk@gmail.com> |
---|---|
date | Tue, 21 Jan 2014 10:24:33 +0000 |
parents | |
children | 2b94d3d2fb9d |
comparison
equal
deleted
inserted
replaced
11:7ce3f8718da1 | 14:18fc3c248436 |
---|---|
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 } |