comparison modules-and-plug-ins/python-module/btrack_python_module.cpp @ 72:f4d9410f187e

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