comparison modules-and-plug-ins/python-module/btrack_python_module.cpp @ 24:deb49a2590f3 develop

Updated README, commented more code, added a Vamp plug-in
author Adam <adamstark.uk@gmail.com>
date Mon, 27 Jan 2014 23:11:31 +0000
parents a8e3e95d14e4
children 0fdaf082ad1a
comparison
equal deleted inserted replaced
23:92ee4ace9d46 24:deb49a2590f3
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 //=======================================================================
8 static PyObject * btrack_onsetdf(PyObject *dummy, PyObject *args) 8 static PyObject * btrack_trackBeats(PyObject *dummy, PyObject *args)
9 { 9 {
10 PyObject *arg1=NULL; 10 PyObject *arg1=NULL;
11 PyObject *arr1=NULL; 11 PyObject *arr1=NULL;
12 12
13 if (!PyArg_ParseTuple(args, "O", &arg1)) 13 if (!PyArg_ParseTuple(args, "O", &arg1))
14 { 14 {
15 return NULL; 15 return NULL;
16 } 16 }
17 17
18 arr1 = PyArray_FROM_OTF(arg1, NPY_DOUBLE, NPY_IN_ARRAY); 18 arr1 = PyArray_FROM_OTF(arg1, NPY_DOUBLE, NPY_IN_ARRAY);
19 if (arr1 == NULL) 19 if (arr1 == NULL)
20 { 20 {
21 return NULL; 21 return NULL;
22 } 22 }
23 23
24 24
25 25
26 ////////// GET INPUT DATA /////////////////// 26 ////////// GET INPUT DATA ///////////////////
27 27
28 // get data as array 28 // get data as array
29 double* data = (double*) PyArray_DATA(arr1); 29 double* data = (double*) PyArray_DATA(arr1);
30 30
31 // get array size 31 // get array size
32 long signal_length = PyArray_Size((PyObject*)arr1); 32 long signal_length = PyArray_Size((PyObject*)arr1);
33
33 34
34 ////////// BEGIN PROCESS /////////////////// 35 ////////// BEGIN PROCESS ///////////////////
35 int hopSize = 512; 36 int hopSize = 512;
36 int frameSize = 1024; 37 int frameSize = 1024;
37 int df_type = 6; 38
38 int numframes; 39 int numframes;
39 double buffer[hopSize]; // buffer to hold one hopsize worth of audio samples 40 double buffer[hopSize]; // buffer to hold one hopsize worth of audio samples
40 41
41 42
42 // get number of audio frames, given the hop size and signal length 43 // get number of audio frames, given the hop size and signal length
43 numframes = (int) floor(((double) signal_length) / ((double) hopSize)); 44 numframes = (int) floor(((double) signal_length) / ((double) hopSize));
44 45
45 OnsetDetectionFunction onset(hopSize,frameSize,df_type,1); 46
46 47 BTrack b(hopSize,frameSize);
47 double df[numframes]; 48
48 49
49 50 double beats[5000];
51 int beatnum = 0;
50 52
51 /////////////////////////////////////////// 53 ///////////////////////////////////////////
52 //////// Begin Processing Loop //////////// 54 //////// Begin Processing Loop ////////////
53 55
54 for (int i=0;i < numframes;i++) 56 for (int i=0;i < numframes;i++)
55 { 57 {
56 // add new samples to frame
57 for (int n = 0;n < hopSize;n++)
58 {
59 buffer[n] = data[(i*hopSize)+n];
60 }
61
62 df[i] = onset.calculateOnsetDetectionFunctionSample(buffer);
63
64 }
65
66 ///////// End Processing Loop /////////////
67 ///////////////////////////////////////////
68
69
70 ////////// END PROCESS ///////////////////
71
72
73
74 ////////// CREATE ARRAY AND RETURN IT ///////////////////
75 int nd=1;
76 npy_intp m= numframes;
77 //double fArray[5] = {0,1,2,3,4};
78
79 PyObject* c=PyArray_SimpleNew(nd, &m, NPY_DOUBLE);
80
81 void *arr_data = PyArray_DATA((PyArrayObject*)c);
82
83 memcpy(arr_data, df, PyArray_ITEMSIZE((PyArrayObject*) c) * m);
84
85
86 Py_DECREF(arr1);
87 Py_INCREF(Py_None);
88 //return Py_None;
89
90 return (PyObject *)c;
91 }
92
93 //=======================================================================
94 static PyObject * btrack_btrack(PyObject *dummy, PyObject *args)
95 {
96 PyObject *arg1=NULL;
97 PyObject *arr1=NULL;
98
99 if (!PyArg_ParseTuple(args, "O", &arg1))
100 {
101 return NULL;
102 }
103
104 arr1 = PyArray_FROM_OTF(arg1, NPY_DOUBLE, NPY_IN_ARRAY);
105 if (arr1 == NULL)
106 {
107 return NULL;
108 }
109
110
111
112 ////////// GET INPUT DATA ///////////////////
113
114 // get data as array
115 double* data = (double*) PyArray_DATA(arr1);
116
117 // get array size
118 long signal_length = PyArray_Size((PyObject*)arr1);
119
120
121 ////////// BEGIN PROCESS ///////////////////
122 int hopSize = 512;
123 int frameSize = 1024;
124
125 int numframes;
126 double buffer[hopSize]; // buffer to hold one hopsize worth of audio samples
127
128
129 // get number of audio frames, given the hop size and signal length
130 numframes = (int) floor(((double) signal_length) / ((double) hopSize));
131
132
133 BTrack b(hopSize,frameSize);
134
135
136 double beats[5000];
137 int beatnum = 0;
138
139 ///////////////////////////////////////////
140 //////// Begin Processing Loop ////////////
141
142 for (int i=0;i < numframes;i++)
143 {
144 // add new samples to frame 58 // add new samples to frame
145 for (int n = 0;n < hopSize;n++) 59 for (int n = 0;n < hopSize;n++)
146 { 60 {
147 buffer[n] = data[(i*hopSize)+n]; 61 buffer[n] = data[(i*hopSize)+n];
148 } 62 }
166 ////////// END PROCESS /////////////////// 80 ////////// END PROCESS ///////////////////
167 81
168 double beats_out[beatnum]; // create output array 82 double beats_out[beatnum]; // create output array
169 83
170 // copy beats into output array 84 // copy beats into output array
171 for (int i = 0;i < beatnum;i++) 85 for (int i = 0;i < beatnum;i++)
172 { 86 {
173 beats_out[i] = beats[i]; 87 beats_out[i] = beats[i];
174 } 88 }
175 89
176 90
182 96
183 PyObject* c=PyArray_SimpleNew(nd, &m, NPY_DOUBLE); 97 PyObject* c=PyArray_SimpleNew(nd, &m, NPY_DOUBLE);
184 98
185 void *arr_data = PyArray_DATA((PyArrayObject*)c); 99 void *arr_data = PyArray_DATA((PyArrayObject*)c);
186 100
187 memcpy(arr_data, beats_out, PyArray_ITEMSIZE((PyArrayObject*) c) * m); 101 memcpy(arr_data, beats_out, PyArray_ITEMSIZE((PyArrayObject*) c) * m);
188 102
189 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
190 Py_DECREF(arr1); 189 Py_DECREF(arr1);
191 Py_INCREF(Py_None); 190 Py_INCREF(Py_None);
192 //return Py_None; 191 //return Py_None;
193 192
194 return (PyObject *)c; 193 return (PyObject *)c;
195 } 194 }
196 195
197 //======================================================================= 196
198 static PyObject * btrack_btrack_df(PyObject *dummy, PyObject *args) 197 //=======================================================================
198 static PyObject * btrack_trackBeatsFromOnsetDF(PyObject *dummy, PyObject *args)
199 { 199 {
200 PyObject *arg1=NULL; 200 PyObject *arg1=NULL;
201 PyObject *arr1=NULL; 201 PyObject *arr1=NULL;
202 202
203 if (!PyArg_ParseTuple(args, "O", &arg1)) 203 if (!PyArg_ParseTuple(args, "O", &arg1))
281 //return Py_None; 281 //return Py_None;
282 282
283 return (PyObject *)c; 283 return (PyObject *)c;
284 } 284 }
285 285
286
287 //======================================================================= 286 //=======================================================================
288 static PyMethodDef btrack_methods[] = { 287 static PyMethodDef btrack_methods[] = {
289 { "onsetdf",btrack_onsetdf,METH_VARARGS,"onset detection function"}, 288 { "calculateOnsetDF",btrack_calculateOnsetDF,METH_VARARGS,"Calculate the onset detection function"},
290 { "btrack",btrack_btrack,METH_VARARGS,"beat tracker"}, 289 { "trackBeats",btrack_trackBeats,METH_VARARGS,"Track beats from audio"},
291 { "btrack_df",btrack_btrack_df,METH_VARARGS,"beat tracker with detection function input"}, 290 { "trackBeatsFromOnsetDF",btrack_trackBeatsFromOnsetDF,METH_VARARGS,"Track beats from an onset detection function"},
292 {NULL, NULL, 0, NULL} /* Sentinel */ 291 {NULL, NULL, 0, NULL} /* Sentinel */
293 }; 292 };
294 293
295 //======================================================================= 294 //=======================================================================
296 PyMODINIT_FUNC initbtrack(void) 295 PyMODINIT_FUNC initbtrack(void)