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