python/: use Py_RETURN_NONE, fixing a memory bug triggered after opening many sinks
[aubio.git] / python / ext / py-filterbank.c
1 #include "aubiowraphell.h"
2
3 static char Py_filterbank_doc[] = "filterbank object";
4
5 AUBIO_DECLARE(filterbank, uint_t n_filters; uint_t win_s)
6
7 //AUBIO_NEW(filterbank)
8 static PyObject *
9 Py_filterbank_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
10 {
11   int win_s = 0, n_filters = 0;
12   Py_filterbank *self;
13   static char *kwlist[] = { "n_filters", "win_s", NULL };
14
15   if (!PyArg_ParseTupleAndKeywords (args, kwds, "|II", kwlist,
16           &n_filters, &win_s)) {
17     return NULL;
18   }
19
20   self = (Py_filterbank *) type->tp_alloc (type, 0);
21
22   if (self == NULL) {
23     return NULL;
24   }
25
26   self->win_s = Py_default_vector_length;
27   if (win_s > 0) {
28     self->win_s = win_s;
29   } else if (win_s < 0) {
30     PyErr_SetString (PyExc_ValueError,
31         "can not use negative window size");
32     return NULL;
33   }
34
35   self->n_filters = 40;
36   if (n_filters > 0) {
37     self->n_filters = n_filters;
38   } else if (n_filters < 0) {
39     PyErr_SetString (PyExc_ValueError,
40         "can not use negative number of filters");
41     return NULL;
42   }
43
44   return (PyObject *) self;
45 }
46
47
48 AUBIO_INIT(filterbank, self->n_filters, self->win_s)
49
50 AUBIO_DEL(filterbank)
51
52 static PyObject *
53 Py_filterbank_do(Py_filterbank * self, PyObject * args)
54 {
55   PyObject *input;
56   cvec_t *vec;
57   fvec_t *out;
58
59   if (!PyArg_ParseTuple (args, "O", &input)) {
60     return NULL;
61   }
62
63   vec = PyAubio_ArrayToCCvec (input);
64
65   if (vec == NULL) {
66     return NULL;
67   }
68
69   out = new_fvec (self->n_filters);
70
71   // compute the function
72   aubio_filterbank_do (self->o, vec, out);
73   return (PyObject *)PyAubio_CFvecToArray(out);
74 }
75
76 AUBIO_MEMBERS_START(filterbank)
77   {"win_s", T_INT, offsetof (Py_filterbank, win_s), READONLY,
78     "size of the window"},
79   {"n_filters", T_INT, offsetof (Py_filterbank, n_filters), READONLY,
80     "number of filters"},
81 AUBIO_MEMBERS_STOP(filterbank)
82
83 static PyObject *
84 Py_filterbank_set_triangle_bands (Py_filterbank * self, PyObject *args)
85 {
86   uint_t err = 0;
87
88   PyObject *input;
89   uint_t samplerate;
90   fvec_t *freqs;
91   if (!PyArg_ParseTuple (args, "OI", &input, &samplerate)) {
92     return NULL;
93   }
94
95   if (input == NULL) {
96     return NULL;
97   }
98
99   freqs = PyAubio_ArrayToCFvec (input);
100
101   if (freqs == NULL) {
102     return NULL;
103   }
104
105   err = aubio_filterbank_set_triangle_bands (self->o,
106       freqs, samplerate);
107   if (err > 0) {
108     PyErr_SetString (PyExc_ValueError,
109         "error when setting filter to A-weighting");
110     return NULL;
111   }
112   Py_RETURN_NONE;
113 }
114
115 static PyObject *
116 Py_filterbank_set_mel_coeffs_slaney (Py_filterbank * self, PyObject *args)
117 {
118   uint_t err = 0;
119
120   uint_t samplerate;
121   if (!PyArg_ParseTuple (args, "I", &samplerate)) {
122     return NULL;
123   }
124
125   err = aubio_filterbank_set_mel_coeffs_slaney (self->o, samplerate);
126   if (err > 0) {
127     PyErr_SetString (PyExc_ValueError,
128         "error when setting filter to A-weighting");
129     return NULL;
130   }
131   Py_RETURN_NONE;
132 }
133
134 static PyObject *
135 Py_filterbank_set_coeffs (Py_filterbank * self, PyObject *args)
136 {
137   uint_t err = 0;
138
139   PyObject *input;
140   fmat_t *coeffs;
141
142   if (!PyArg_ParseTuple (args, "O", &input)) {
143     return NULL;
144   }
145
146   coeffs = PyAubio_ArrayToCFmat (input);
147
148   if (coeffs == NULL) {
149     PyErr_SetString (PyExc_ValueError,
150         "unable to parse input array");
151     return NULL;
152   }
153
154   err = aubio_filterbank_set_coeffs (self->o, coeffs);
155
156   if (err > 0) {
157     PyErr_SetString (PyExc_ValueError,
158         "error when setting filter coefficients");
159     return NULL;
160   }
161   Py_RETURN_NONE;
162 }
163
164 static PyObject *
165 Py_filterbank_get_coeffs (Py_filterbank * self, PyObject *unused)
166 {
167   return (PyObject *)PyAubio_CFmatToArray(
168       aubio_filterbank_get_coeffs (self->o) );
169 }
170
171 static PyMethodDef Py_filterbank_methods[] = {
172   {"set_triangle_bands", (PyCFunction) Py_filterbank_set_triangle_bands,
173     METH_VARARGS, "set coefficients of filterbanks"},
174   {"set_mel_coeffs_slaney", (PyCFunction) Py_filterbank_set_mel_coeffs_slaney,
175     METH_VARARGS, "set coefficients of filterbank as in Auditory Toolbox"},
176   {"get_coeffs", (PyCFunction) Py_filterbank_get_coeffs,
177     METH_NOARGS, "get coefficients of filterbank"},
178   {"set_coeffs", (PyCFunction) Py_filterbank_set_coeffs,
179     METH_VARARGS, "set coefficients of filterbank"},
180   {NULL}
181 };
182
183 AUBIO_TYPEOBJECT(filterbank, "aubio.filterbank")