source: python/ext/py-filterbank.c @ 04cd251

feature/autosinkfeature/constantqfeature/pitchshiftfeature/pydocstringsfeature/timestretch
Last change on this file since 04cd251 was 04cd251, checked in by Paul Brossier <piem@piem.org>, 9 months ago

[py] add filterbank.set_mel_coeffs, improve error messages

  • Property mode set to 100644
File size: 7.7 KB
Line 
1#include "aubio-types.h"
2
3static char Py_filterbank_doc[] = "filterbank object";
4
5typedef struct
6{
7  PyObject_HEAD
8  aubio_filterbank_t * o;
9  uint_t n_filters;
10  uint_t win_s;
11  cvec_t vec;
12  fvec_t freqs;
13  fmat_t coeffs;
14  PyObject *out;
15  fvec_t c_out;
16} Py_filterbank;
17
18static PyObject *
19Py_filterbank_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
20{
21  int win_s = 0, n_filters = 0;
22  Py_filterbank *self;
23  static char *kwlist[] = { "n_filters", "win_s", NULL };
24
25  if (!PyArg_ParseTupleAndKeywords (args, kwds, "|II", kwlist,
26          &n_filters, &win_s)) {
27    return NULL;
28  }
29
30  self = (Py_filterbank *) type->tp_alloc (type, 0);
31
32  if (self == NULL) {
33    return NULL;
34  }
35
36  self->win_s = Py_default_vector_length;
37  if (win_s > 0) {
38    self->win_s = win_s;
39  } else if (win_s < 0) {
40    PyErr_SetString (PyExc_ValueError,
41        "can not use negative window size");
42    return NULL;
43  }
44
45  self->n_filters = 40;
46  if (n_filters > 0) {
47    self->n_filters = n_filters;
48  } else if (n_filters < 0) {
49    PyErr_SetString (PyExc_ValueError,
50        "can not use negative number of filters");
51    return NULL;
52  }
53
54  return (PyObject *) self;
55}
56
57static int
58Py_filterbank_init (Py_filterbank * self, PyObject * args, PyObject * kwds)
59{
60  self->o = new_aubio_filterbank (self->n_filters, self->win_s);
61  if (self->o == NULL) {
62    PyErr_Format(PyExc_RuntimeError, "error creating filterbank with"
63        " n_filters=%d, win_s=%d", self->n_filters, self->win_s);
64    return -1;
65  }
66  self->out = new_py_fvec(self->n_filters);
67
68  return 0;
69}
70
71static void
72Py_filterbank_del (Py_filterbank *self, PyObject *unused)
73{
74  if (self->o) {
75    free(self->coeffs.data);
76    del_aubio_filterbank(self->o);
77  }
78  Py_XDECREF(self->out);
79  Py_TYPE(self)->tp_free((PyObject *) self);
80}
81
82static PyObject *
83Py_filterbank_do(Py_filterbank * self, PyObject * args)
84{
85  PyObject *input;
86
87  if (!PyArg_ParseTuple (args, "O", &input)) {
88    return NULL;
89  }
90
91  if (!PyAubio_PyCvecToCCvec(input, &(self->vec) )) {
92    return NULL;
93  }
94
95  if (self->vec.length != self->win_s / 2 + 1) {
96    PyErr_Format(PyExc_ValueError,
97                 "input cvec has length %d, but filterbank expects length %d",
98                 self->vec.length, self->win_s / 2 + 1);
99    return NULL;
100  }
101
102  Py_INCREF(self->out);
103  if (!PyAubio_ArrayToCFvec(self->out, &(self->c_out))) {
104    return NULL;
105  }
106  // compute the function
107  aubio_filterbank_do (self->o, &(self->vec), &(self->c_out));
108  return self->out;
109}
110
111static PyMemberDef Py_filterbank_members[] = {
112  {"win_s", T_INT, offsetof (Py_filterbank, win_s), READONLY,
113    "size of the window"},
114  {"n_filters", T_INT, offsetof (Py_filterbank, n_filters), READONLY,
115    "number of filters"},
116  {NULL} /* sentinel */
117};
118
119static PyObject *
120Py_filterbank_set_triangle_bands (Py_filterbank * self, PyObject *args)
121{
122  uint_t err = 0;
123
124  PyObject *input;
125  uint_t samplerate;
126  if (!PyArg_ParseTuple (args, "OI", &input, &samplerate)) {
127    return NULL;
128  }
129
130  if (input == NULL) {
131    return NULL;
132  }
133
134  if (!PyAubio_ArrayToCFvec(input, &(self->freqs) )) {
135    return NULL;
136  }
137
138  err = aubio_filterbank_set_triangle_bands (self->o,
139      &(self->freqs), samplerate);
140  if (err > 0) {
141    if (PyErr_Occurred() == NULL) {
142      PyErr_SetString (PyExc_ValueError, "error running set_triangle_bands");
143    } else {
144      // change the RuntimeError into ValueError
145      PyObject *type, *value, *traceback;
146      PyErr_Fetch(&type, &value, &traceback);
147      PyErr_Restore(PyExc_ValueError, value, traceback);
148    }
149    return NULL;
150  }
151  Py_RETURN_NONE;
152}
153
154static PyObject *
155Py_filterbank_set_mel_coeffs_slaney (Py_filterbank * self, PyObject *args)
156{
157  uint_t err = 0;
158
159  uint_t samplerate;
160  if (!PyArg_ParseTuple (args, "I", &samplerate)) {
161    return NULL;
162  }
163
164  err = aubio_filterbank_set_mel_coeffs_slaney (self->o, samplerate);
165  if (err > 0) {
166    if (PyErr_Occurred() == NULL) {
167      PyErr_SetString (PyExc_ValueError, "error running set_mel_coeffs_slaney");
168    } else {
169      // change the RuntimeError into ValueError
170      PyObject *type, *value, *traceback;
171      PyErr_Fetch(&type, &value, &traceback);
172      PyErr_Restore(PyExc_ValueError, value, traceback);
173    }
174    return NULL;
175  }
176  Py_RETURN_NONE;
177}
178
179static PyObject *
180Py_filterbank_set_mel_coeffs (Py_filterbank * self, PyObject *args)
181{
182  uint_t err = 0;
183
184  uint_t samplerate;
185  smpl_t freq_min;
186  smpl_t freq_max;
187  if (!PyArg_ParseTuple (args, "I" AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR,
188        &samplerate, &freq_min, &freq_max)) {
189    return NULL;
190  }
191
192  err = aubio_filterbank_set_mel_coeffs (self->o, samplerate,
193      freq_min, freq_max);
194  if (err > 0) {
195    if (PyErr_Occurred() == NULL) {
196      PyErr_SetString (PyExc_ValueError, "error running set_mel_coeffs");
197    } else {
198      // change the RuntimeError into ValueError
199      PyObject *type, *value, *traceback;
200      PyErr_Fetch(&type, &value, &traceback);
201      PyErr_Restore(PyExc_ValueError, value, traceback);
202    }
203    return NULL;
204  }
205  Py_RETURN_NONE;
206}
207
208static PyObject *
209Py_filterbank_set_mel_coeffs_htk (Py_filterbank * self, PyObject *args)
210{
211  uint_t err = 0;
212
213  uint_t samplerate;
214  smpl_t freq_min;
215  smpl_t freq_max;
216  if (!PyArg_ParseTuple (args, "I" AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR,
217        &samplerate, &freq_min, &freq_max)) {
218    return NULL;
219  }
220
221  err = aubio_filterbank_set_mel_coeffs_htk (self->o,
222      freq_min, freq_max, samplerate);
223  if (err > 0) {
224    if (PyErr_Occurred() == NULL) {
225      PyErr_SetString (PyExc_ValueError, "error running set_mel_coeffs_htk");
226    } else {
227      // change the RuntimeError into ValueError
228      PyObject *type, *value, *traceback;
229      PyErr_Fetch(&type, &value, &traceback);
230      PyErr_Restore(PyExc_ValueError, value, traceback);
231    }
232    return NULL;
233  }
234  Py_RETURN_NONE;
235}
236
237static PyObject *
238Py_filterbank_set_coeffs (Py_filterbank * self, PyObject *args)
239{
240  uint_t err = 0;
241
242  PyObject *input;
243  if (!PyArg_ParseTuple (args, "O", &input)) {
244    return NULL;
245  }
246
247  if (!PyAubio_ArrayToCFmat(input, &(self->coeffs))) {
248    return NULL;
249  }
250
251  err = aubio_filterbank_set_coeffs (self->o, &(self->coeffs));
252
253  if (err > 0) {
254    PyErr_SetString (PyExc_ValueError,
255        "error when setting filter coefficients");
256    return NULL;
257  }
258  Py_RETURN_NONE;
259}
260
261static PyObject *
262Py_filterbank_get_coeffs (Py_filterbank * self, PyObject *unused)
263{
264  return (PyObject *)PyAubio_CFmatToArray(
265      aubio_filterbank_get_coeffs (self->o) );
266}
267
268static PyMethodDef Py_filterbank_methods[] = {
269  {"set_triangle_bands", (PyCFunction) Py_filterbank_set_triangle_bands,
270    METH_VARARGS, "set coefficients of filterbanks"},
271  {"set_mel_coeffs_slaney", (PyCFunction) Py_filterbank_set_mel_coeffs_slaney,
272    METH_VARARGS, "set coefficients of filterbank as in Auditory Toolbox"},
273  {"set_mel_coeffs", (PyCFunction) Py_filterbank_set_mel_coeffs,
274    METH_VARARGS, "set coefficients of filterbank to linearly spaced mel scale"},
275  {"set_mel_coeffs_htk", (PyCFunction) Py_filterbank_set_mel_coeffs_htk,
276    METH_VARARGS, "set coefficients of filterbank to linearly spaced mel scale"},
277  {"get_coeffs", (PyCFunction) Py_filterbank_get_coeffs,
278    METH_NOARGS, "get coefficients of filterbank"},
279  {"set_coeffs", (PyCFunction) Py_filterbank_set_coeffs,
280    METH_VARARGS, "set coefficients of filterbank"},
281  {NULL}
282};
283
284PyTypeObject Py_filterbankType = {
285  PyVarObject_HEAD_INIT (NULL, 0)
286  "aubio.filterbank",
287  sizeof (Py_filterbank),
288  0,
289  (destructor) Py_filterbank_del,
290  0,
291  0,
292  0,
293  0,
294  0,
295  0,
296  0,
297  0,
298  0,
299  (ternaryfunc)Py_filterbank_do,
300  0,
301  0,
302  0,
303  0,
304  Py_TPFLAGS_DEFAULT,
305  Py_filterbank_doc,
306  0,
307  0,
308  0,
309  0,
310  0,
311  0,
312  Py_filterbank_methods,
313  Py_filterbank_members,
314  0,
315  0,
316  0,
317  0,
318  0,
319  0,
320  (initproc) Py_filterbank_init,
321  0,
322  Py_filterbank_new,
323  0,
324  0,
325  0,
326  0,
327  0,
328  0,
329  0,
330  0,
331  0,
332};
Note: See TracBrowser for help on using the repository browser.