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