source: python/ext/py-filterbank.c @ 598774b

sampler
Last change on this file since 598774b was 7876b67, checked in by Paul Brossier <piem@piem.org>, 9 years ago

python/ext/py-filterbank.c: fix error message formatting, do not delete if not created

  • Property mode set to 100644
File size: 5.4 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 fft 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    PyErr_SetString (PyExc_ValueError,
142        "error when setting filter to A-weighting");
143    return NULL;
144  }
145  Py_RETURN_NONE;
146}
147
148static PyObject *
149Py_filterbank_set_mel_coeffs_slaney (Py_filterbank * self, PyObject *args)
150{
151  uint_t err = 0;
152
153  uint_t samplerate;
154  if (!PyArg_ParseTuple (args, "I", &samplerate)) {
155    return NULL;
156  }
157
158  err = aubio_filterbank_set_mel_coeffs_slaney (self->o, samplerate);
159  if (err > 0) {
160    PyErr_SetString (PyExc_ValueError,
161        "error when setting filter to A-weighting");
162    return NULL;
163  }
164  Py_RETURN_NONE;
165}
166
167static PyObject *
168Py_filterbank_set_coeffs (Py_filterbank * self, PyObject *args)
169{
170  uint_t err = 0;
171
172  PyObject *input;
173  if (!PyArg_ParseTuple (args, "O", &input)) {
174    return NULL;
175  }
176
177  if (!PyAubio_ArrayToCFmat(input, &(self->coeffs))) {
178    return NULL;
179  }
180
181  err = aubio_filterbank_set_coeffs (self->o, &(self->coeffs));
182
183  if (err > 0) {
184    PyErr_SetString (PyExc_ValueError,
185        "error when setting filter coefficients");
186    return NULL;
187  }
188  Py_RETURN_NONE;
189}
190
191static PyObject *
192Py_filterbank_get_coeffs (Py_filterbank * self, PyObject *unused)
193{
194  return (PyObject *)PyAubio_CFmatToArray(
195      aubio_filterbank_get_coeffs (self->o) );
196}
197
198static PyMethodDef Py_filterbank_methods[] = {
199  {"set_triangle_bands", (PyCFunction) Py_filterbank_set_triangle_bands,
200    METH_VARARGS, "set coefficients of filterbanks"},
201  {"set_mel_coeffs_slaney", (PyCFunction) Py_filterbank_set_mel_coeffs_slaney,
202    METH_VARARGS, "set coefficients of filterbank as in Auditory Toolbox"},
203  {"get_coeffs", (PyCFunction) Py_filterbank_get_coeffs,
204    METH_NOARGS, "get coefficients of filterbank"},
205  {"set_coeffs", (PyCFunction) Py_filterbank_set_coeffs,
206    METH_VARARGS, "set coefficients of filterbank"},
207  {NULL}
208};
209
210PyTypeObject Py_filterbankType = {
211  PyVarObject_HEAD_INIT (NULL, 0)
212  "aubio.filterbank",
213  sizeof (Py_filterbank),
214  0,
215  (destructor) Py_filterbank_del,
216  0,
217  0,
218  0,
219  0,
220  0,
221  0,
222  0,
223  0,
224  0,
225  (ternaryfunc)Py_filterbank_do,
226  0,
227  0,
228  0,
229  0,
230  Py_TPFLAGS_DEFAULT,
231  Py_filterbank_doc,
232  0,
233  0,
234  0,
235  0,
236  0,
237  0,
238  Py_filterbank_methods,
239  Py_filterbank_members,
240  0,
241  0,
242  0,
243  0,
244  0,
245  0,
246  (initproc) Py_filterbank_init,
247  0,
248  Py_filterbank_new,
249  0,
250  0,
251  0,
252  0,
253  0,
254  0,
255  0,
256  0,
257  0,
258};
Note: See TracBrowser for help on using the repository browser.