62c6a26eef8b81e2fb0265cc434548a453c75843
[aubio.git] / python / ext / py-filterbank.c
1 #include "aubio-types.h"
2
3 static char Py_filterbank_doc[] = "filterbank object";
4
5 typedef 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
18 static PyObject *
19 Py_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
57 static int
58 Py_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
71 static void
72 Py_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
82 static PyObject *
83 Py_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
111 static 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
119 static PyObject *
120 Py_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
154 static PyObject *
155 Py_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
179 static PyObject *
180 Py_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
208 static PyObject *
209 Py_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, samplerate,
222       freq_min, freq_max);
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
237 static PyObject *
238 Py_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
261 static PyObject *
262 Py_filterbank_get_coeffs (Py_filterbank * self, PyObject *unused)
263 {
264   return (PyObject *)PyAubio_CFmatToArray(
265       aubio_filterbank_get_coeffs (self->o) );
266 }
267
268 static PyObject *
269 Py_filterbank_set_power(Py_filterbank *self, PyObject *args)
270 {
271   uint_t playing;
272
273   if (!PyArg_ParseTuple (args, "I", &playing)) {
274     return NULL;
275   }
276   if(aubio_filterbank_set_power (self->o, playing)) {
277     if (PyErr_Occurred() == NULL) {
278       PyErr_SetString (PyExc_ValueError,
279           "error running filterbank.set_power");
280     } else {
281       // change the RuntimeError into ValueError
282       PyObject *type, *value, *traceback;
283       PyErr_Fetch(&type, &value, &traceback);
284       PyErr_Restore(PyExc_ValueError, value, traceback);
285     }
286     return NULL;
287   }
288   Py_RETURN_NONE;
289 }
290
291 static PyObject *
292 Py_filterbank_set_norm(Py_filterbank *self, PyObject *args)
293 {
294   uint_t playing;
295
296   if (!PyArg_ParseTuple (args, "I", &playing)) {
297     return NULL;
298   }
299   if(aubio_filterbank_set_norm (self->o, playing)) {
300     if (PyErr_Occurred() == NULL) {
301       PyErr_SetString (PyExc_ValueError,
302           "error running filterbank.set_power");
303     } else {
304       // change the RuntimeError into ValueError
305       PyObject *type, *value, *traceback;
306       PyErr_Fetch(&type, &value, &traceback);
307       PyErr_Restore(PyExc_ValueError, value, traceback);
308     }
309     return NULL;
310   }
311   Py_RETURN_NONE;
312 }
313
314 static PyMethodDef Py_filterbank_methods[] = {
315   {"set_triangle_bands", (PyCFunction) Py_filterbank_set_triangle_bands,
316     METH_VARARGS, "set coefficients of filterbanks"},
317   {"set_mel_coeffs_slaney", (PyCFunction) Py_filterbank_set_mel_coeffs_slaney,
318     METH_VARARGS, "set coefficients of filterbank as in Auditory Toolbox"},
319   {"set_mel_coeffs", (PyCFunction) Py_filterbank_set_mel_coeffs,
320     METH_VARARGS, "set coefficients of filterbank to linearly spaced mel scale"},
321   {"set_mel_coeffs_htk", (PyCFunction) Py_filterbank_set_mel_coeffs_htk,
322     METH_VARARGS, "set coefficients of filterbank to linearly spaced mel scale"},
323   {"get_coeffs", (PyCFunction) Py_filterbank_get_coeffs,
324     METH_NOARGS, "get coefficients of filterbank"},
325   {"set_coeffs", (PyCFunction) Py_filterbank_set_coeffs,
326     METH_VARARGS, "set coefficients of filterbank"},
327   {"set_power", (PyCFunction) Py_filterbank_set_power,
328     METH_VARARGS, "set power applied to filterbank input spectrum"},
329   {"set_norm", (PyCFunction) Py_filterbank_set_norm,
330     METH_VARARGS, "set norm applied to filterbank input spectrum"},
331   {NULL}
332 };
333
334 PyTypeObject Py_filterbankType = {
335   PyVarObject_HEAD_INIT (NULL, 0)
336   "aubio.filterbank",
337   sizeof (Py_filterbank),
338   0,
339   (destructor) Py_filterbank_del,
340   0,
341   0,
342   0,
343   0,
344   0,
345   0,
346   0,
347   0,
348   0,
349   (ternaryfunc)Py_filterbank_do,
350   0,
351   0,
352   0,
353   0,
354   Py_TPFLAGS_DEFAULT,
355   Py_filterbank_doc,
356   0,
357   0,
358   0,
359   0,
360   0,
361   0,
362   Py_filterbank_methods,
363   Py_filterbank_members,
364   0,
365   0,
366   0,
367   0,
368   0,
369   0,
370   (initproc) Py_filterbank_init,
371   0,
372   Py_filterbank_new,
373   0,
374   0,
375   0,
376   0,
377   0,
378   0,
379   0,
380   0,
381   0,
382 };