612a34f97d071dde73e1d39487a535311d716967
[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 *out;
13   fvec_t *freqs;
14   fmat_t *coeffs;
15 } Py_filterbank;
16
17 static PyObject *
18 Py_filterbank_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
19 {
20   int win_s = 0, n_filters = 0;
21   Py_filterbank *self;
22   static char *kwlist[] = { "n_filters", "win_s", NULL };
23
24   if (!PyArg_ParseTupleAndKeywords (args, kwds, "|II", kwlist,
25           &n_filters, &win_s)) {
26     return NULL;
27   }
28
29   self = (Py_filterbank *) type->tp_alloc (type, 0);
30
31   if (self == NULL) {
32     return NULL;
33   }
34
35   self->win_s = Py_default_vector_length;
36   if (win_s > 0) {
37     self->win_s = win_s;
38   } else if (win_s < 0) {
39     PyErr_SetString (PyExc_ValueError,
40         "can not use negative window size");
41     return NULL;
42   }
43
44   self->n_filters = 40;
45   if (n_filters > 0) {
46     self->n_filters = n_filters;
47   } else if (n_filters < 0) {
48     PyErr_SetString (PyExc_ValueError,
49         "can not use negative number of filters");
50     return NULL;
51   }
52
53   return (PyObject *) self;
54 }
55
56 static int
57 Py_filterbank_init (Py_filterbank * self, PyObject * args, PyObject * kwds)
58 {
59   self->o = new_aubio_filterbank (self->n_filters, self->win_s);
60   if (self->o == NULL) {
61     char_t errstr[30];
62     sprintf(errstr, "error creating filterbank with n_filters=%d, win_s=%d",
63         self->n_filters, self->win_s);
64     PyErr_SetString (PyExc_RuntimeError, errstr);
65     return -1;
66   }
67   self->out = new_fvec(self->n_filters);
68
69   self->vec = (cvec_t *)malloc(sizeof(cvec_t));
70
71   self->freqs = (fvec_t *)malloc(sizeof(fvec_t));
72
73   self->coeffs = (fmat_t *)malloc(sizeof(fmat_t));
74   self->coeffs->data = (smpl_t **)malloc(sizeof(smpl_t*) * self->n_filters);
75   self->coeffs->height = self->n_filters;
76
77   return 0;
78 }
79
80 static void
81 Py_filterbank_del (Py_filterbank *self, PyObject *unused)
82 {
83   del_aubio_filterbank(self->o);
84   del_fvec(self->out);
85   free(self->vec);
86   free(self->freqs);
87   free(self->coeffs->data);
88   free(self->coeffs);
89   Py_TYPE(self)->tp_free((PyObject *) self);
90 }
91
92 static PyObject *
93 Py_filterbank_do(Py_filterbank * self, PyObject * args)
94 {
95   PyObject *input;
96
97   if (!PyArg_ParseTuple (args, "O", &input)) {
98     return NULL;
99   }
100
101   if (!PyAubio_ArrayToCCvec(input, self->vec)) {
102     return NULL;
103   }
104
105   // compute the function
106   aubio_filterbank_do (self->o, self->vec, self->out);
107   return (PyObject *)PyAubio_CFvecToArray(self->out);
108 }
109
110 static PyMemberDef Py_filterbank_members[] = {
111   {"win_s", T_INT, offsetof (Py_filterbank, win_s), READONLY,
112     "size of the window"},
113   {"n_filters", T_INT, offsetof (Py_filterbank, n_filters), READONLY,
114     "number of filters"},
115   {NULL} /* sentinel */
116 };
117
118 static PyObject *
119 Py_filterbank_set_triangle_bands (Py_filterbank * self, PyObject *args)
120 {
121   uint_t err = 0;
122
123   PyObject *input;
124   uint_t samplerate;
125   if (!PyArg_ParseTuple (args, "OI", &input, &samplerate)) {
126     return NULL;
127   }
128
129   if (input == NULL) {
130     return NULL;
131   }
132
133   if (!PyAubio_ArrayToCFvec(input, self->freqs)) {
134     return NULL;
135   }
136
137   err = aubio_filterbank_set_triangle_bands (self->o,
138       self->freqs, samplerate);
139   if (err > 0) {
140     PyErr_SetString (PyExc_ValueError,
141         "error when setting filter to A-weighting");
142     return NULL;
143   }
144   Py_RETURN_NONE;
145 }
146
147 static PyObject *
148 Py_filterbank_set_mel_coeffs_slaney (Py_filterbank * self, PyObject *args)
149 {
150   uint_t err = 0;
151
152   uint_t samplerate;
153   if (!PyArg_ParseTuple (args, "I", &samplerate)) {
154     return NULL;
155   }
156
157   err = aubio_filterbank_set_mel_coeffs_slaney (self->o, samplerate);
158   if (err > 0) {
159     PyErr_SetString (PyExc_ValueError,
160         "error when setting filter to A-weighting");
161     return NULL;
162   }
163   Py_RETURN_NONE;
164 }
165
166 static PyObject *
167 Py_filterbank_set_coeffs (Py_filterbank * self, PyObject *args)
168 {
169   uint_t err = 0;
170
171   PyObject *input;
172   if (!PyArg_ParseTuple (args, "O", &input)) {
173     return NULL;
174   }
175
176   if (!PyAubio_ArrayToCFmat(input, self->coeffs)) {
177     return NULL;
178   }
179
180   err = aubio_filterbank_set_coeffs (self->o, self->coeffs);
181
182   if (err > 0) {
183     PyErr_SetString (PyExc_ValueError,
184         "error when setting filter coefficients");
185     return NULL;
186   }
187   Py_RETURN_NONE;
188 }
189
190 static PyObject *
191 Py_filterbank_get_coeffs (Py_filterbank * self, PyObject *unused)
192 {
193   return (PyObject *)PyAubio_CFmatToArray(
194       aubio_filterbank_get_coeffs (self->o) );
195 }
196
197 static PyMethodDef Py_filterbank_methods[] = {
198   {"set_triangle_bands", (PyCFunction) Py_filterbank_set_triangle_bands,
199     METH_VARARGS, "set coefficients of filterbanks"},
200   {"set_mel_coeffs_slaney", (PyCFunction) Py_filterbank_set_mel_coeffs_slaney,
201     METH_VARARGS, "set coefficients of filterbank as in Auditory Toolbox"},
202   {"get_coeffs", (PyCFunction) Py_filterbank_get_coeffs,
203     METH_NOARGS, "get coefficients of filterbank"},
204   {"set_coeffs", (PyCFunction) Py_filterbank_set_coeffs,
205     METH_VARARGS, "set coefficients of filterbank"},
206   {NULL}
207 };
208
209 PyTypeObject Py_filterbankType = {
210   PyVarObject_HEAD_INIT (NULL, 0)
211   "aubio.filterbank",
212   sizeof (Py_filterbank),
213   0,
214   (destructor) Py_filterbank_del,
215   0,
216   0,
217   0,
218   0,
219   0,
220   0,
221   0,
222   0,
223   0,
224   (ternaryfunc)Py_filterbank_do,
225   0,
226   0,
227   0,
228   0,
229   Py_TPFLAGS_DEFAULT,
230   Py_filterbank_doc,
231   0,
232   0,
233   0,
234   0,
235   0,
236   0,
237   Py_filterbank_methods,
238   Py_filterbank_members,
239   0,
240   0,
241   0,
242   0,
243   0,
244   0,
245   (initproc) Py_filterbank_init,
246   0,
247   Py_filterbank_new,
248 };