ext/py-filterbank.c: continue fixing memory leak (#49)
[aubio.git] / python / ext / py-filterbank.c
1 #include "aubiowraphell.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 //AUBIO_NEW(filterbank)
15 static PyObject *
16 Py_filterbank_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
17 {
18   int win_s = 0, n_filters = 0;
19   Py_filterbank *self;
20   static char *kwlist[] = { "n_filters", "win_s", NULL };
21
22   if (!PyArg_ParseTupleAndKeywords (args, kwds, "|II", kwlist,
23           &n_filters, &win_s)) {
24     return NULL;
25   }
26
27   self = (Py_filterbank *) type->tp_alloc (type, 0);
28
29   if (self == NULL) {
30     return NULL;
31   }
32
33   self->win_s = Py_default_vector_length;
34   if (win_s > 0) {
35     self->win_s = win_s;
36   } else if (win_s < 0) {
37     PyErr_SetString (PyExc_ValueError,
38         "can not use negative window size");
39     return NULL;
40   }
41
42   self->n_filters = 40;
43   if (n_filters > 0) {
44     self->n_filters = n_filters;
45   } else if (n_filters < 0) {
46     PyErr_SetString (PyExc_ValueError,
47         "can not use negative number of filters");
48     return NULL;
49   }
50
51   return (PyObject *) self;
52 }
53
54 static int
55 Py_filterbank_init (Py_filterbank * self, PyObject * args, PyObject * kwds)
56 {
57   self->o = new_aubio_filterbank (self->n_filters, self->win_s);
58   if (self->o == NULL) {
59     char_t errstr[30];
60     sprintf(errstr, "error creating filterbank with n_filters=%d, win_s=%d",
61         self->n_filters, self->win_s);
62     PyErr_SetString (PyExc_StandardError, errstr);
63     return -1;
64   }
65   self->out = new_fvec(self->n_filters);
66
67   return 0;
68 }
69
70 static void
71 Py_filterbank_del (Py_filterbank *self, PyObject *unused)
72 {
73   del_aubio_filterbank(self->o);
74   del_fvec(self->out);
75   self->ob_type->tp_free((PyObject *) self);
76 }
77
78 static PyObject *
79 Py_filterbank_do(Py_filterbank * self, PyObject * args)
80 {
81   PyObject *input;
82   cvec_t *vec;
83
84   if (!PyArg_ParseTuple (args, "O", &input)) {
85     return NULL;
86   }
87
88   vec = PyAubio_ArrayToCCvec (input);
89
90   if (vec == NULL) {
91     return NULL;
92   }
93
94   // compute the function
95   aubio_filterbank_do (self->o, vec, self->out);
96   return (PyObject *)PyAubio_CFvecToArray(self->out);
97 }
98
99 AUBIO_MEMBERS_START(filterbank)
100   {"win_s", T_INT, offsetof (Py_filterbank, win_s), READONLY,
101     "size of the window"},
102   {"n_filters", T_INT, offsetof (Py_filterbank, n_filters), READONLY,
103     "number of filters"},
104 AUBIO_MEMBERS_STOP(filterbank)
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 AUBIO_TYPEOBJECT(filterbank, "aubio.filterbank")