Mercurial > hg > btrack
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 } |