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