python/ext/py-filterbank.c: use new_py_fvec
[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     char_t errstr[30];
63     sprintf(errstr, "error creating filterbank with n_filters=%d, win_s=%d",
64         self->n_filters, self->win_s);
65     PyErr_SetString (PyExc_RuntimeError, errstr);
66     return -1;
67   }
68   self->out = new_py_fvec(self->n_filters);
69
70   return 0;
71 }
72
73 static void
74 Py_filterbank_del (Py_filterbank *self, PyObject *unused)
75 {
76   del_aubio_filterbank(self->o);
77   Py_DECREF(self->out);
78   free(self->coeffs.data);
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   Py_INCREF(self->out);
96   if (!PyAubio_ArrayToCFvec(self->out, &(self->c_out))) {
97     return NULL;
98   }
99   // compute the function
100   aubio_filterbank_do (self->o, &(self->vec), &(self->c_out));
101   return self->out;
102 }
103
104 static PyMemberDef Py_filterbank_members[] = {
105   {"win_s", T_INT, offsetof (Py_filterbank, win_s), READONLY,
106     "size of the window"},
107   {"n_filters", T_INT, offsetof (Py_filterbank, n_filters), READONLY,
108     "number of filters"},
109   {NULL} /* sentinel */
110 };
111
112 static PyObject *
113 Py_filterbank_set_triangle_bands (Py_filterbank * self, PyObject *args)
114 {
115   uint_t err = 0;
116
117   PyObject *input;
118   uint_t samplerate;
119   if (!PyArg_ParseTuple (args, "OI", &input, &samplerate)) {
120     return NULL;
121   }
122
123   if (input == NULL) {
124     return NULL;
125   }
126
127   if (!PyAubio_ArrayToCFvec(input, &(self->freqs) )) {
128     return NULL;
129   }
130
131   err = aubio_filterbank_set_triangle_bands (self->o,
132       &(self->freqs), samplerate);
133   if (err > 0) {
134     PyErr_SetString (PyExc_ValueError,
135         "error when setting filter to A-weighting");
136     return NULL;
137   }
138   Py_RETURN_NONE;
139 }
140
141 static PyObject *
142 Py_filterbank_set_mel_coeffs_slaney (Py_filterbank * self, PyObject *args)
143 {
144   uint_t err = 0;
145
146   uint_t samplerate;
147   if (!PyArg_ParseTuple (args, "I", &samplerate)) {
148     return NULL;
149   }
150
151   err = aubio_filterbank_set_mel_coeffs_slaney (self->o, samplerate);
152   if (err > 0) {
153     PyErr_SetString (PyExc_ValueError,
154         "error when setting filter to A-weighting");
155     return NULL;
156   }
157   Py_RETURN_NONE;
158 }
159
160 static PyObject *
161 Py_filterbank_set_coeffs (Py_filterbank * self, PyObject *args)
162 {
163   uint_t err = 0;
164
165   PyObject *input;
166   if (!PyArg_ParseTuple (args, "O", &input)) {
167     return NULL;
168   }
169
170   if (!PyAubio_ArrayToCFmat(input, &(self->coeffs))) {
171     return NULL;
172   }
173
174   err = aubio_filterbank_set_coeffs (self->o, &(self->coeffs));
175
176   if (err > 0) {
177     PyErr_SetString (PyExc_ValueError,
178         "error when setting filter coefficients");
179     return NULL;
180   }
181   Py_RETURN_NONE;
182 }
183
184 static PyObject *
185 Py_filterbank_get_coeffs (Py_filterbank * self, PyObject *unused)
186 {
187   return (PyObject *)PyAubio_CFmatToArray(
188       aubio_filterbank_get_coeffs (self->o) );
189 }
190
191 static PyMethodDef Py_filterbank_methods[] = {
192   {"set_triangle_bands", (PyCFunction) Py_filterbank_set_triangle_bands,
193     METH_VARARGS, "set coefficients of filterbanks"},
194   {"set_mel_coeffs_slaney", (PyCFunction) Py_filterbank_set_mel_coeffs_slaney,
195     METH_VARARGS, "set coefficients of filterbank as in Auditory Toolbox"},
196   {"get_coeffs", (PyCFunction) Py_filterbank_get_coeffs,
197     METH_NOARGS, "get coefficients of filterbank"},
198   {"set_coeffs", (PyCFunction) Py_filterbank_set_coeffs,
199     METH_VARARGS, "set coefficients of filterbank"},
200   {NULL}
201 };
202
203 PyTypeObject Py_filterbankType = {
204   PyVarObject_HEAD_INIT (NULL, 0)
205   "aubio.filterbank",
206   sizeof (Py_filterbank),
207   0,
208   (destructor) Py_filterbank_del,
209   0,
210   0,
211   0,
212   0,
213   0,
214   0,
215   0,
216   0,
217   0,
218   (ternaryfunc)Py_filterbank_do,
219   0,
220   0,
221   0,
222   0,
223   Py_TPFLAGS_DEFAULT,
224   Py_filterbank_doc,
225   0,
226   0,
227   0,
228   0,
229   0,
230   0,
231   Py_filterbank_methods,
232   Py_filterbank_members,
233   0,
234   0,
235   0,
236   0,
237   0,
238   0,
239   (initproc) Py_filterbank_init,
240   0,
241   Py_filterbank_new,
242 };