Merge branch 'fix/awhitening'
[aubio.git] / python / ext / py-filter.c
1 #include "aubio-types.h"
2
3 typedef struct
4 {
5   PyObject_HEAD
6   aubio_filter_t * o;
7   uint_t order;
8   fvec_t vec;
9   PyObject *out;
10   fvec_t c_out;
11 } Py_filter;
12
13 static char Py_filter_doc[] = "filter object";
14
15 static PyObject *
16 Py_filter_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
17 {
18   int order= 0;
19   Py_filter *self;
20   static char *kwlist[] = { "order", NULL };
21
22   if (!PyArg_ParseTupleAndKeywords (args, kwds, "|I", kwlist,
23           &order)) {
24     return NULL;
25   }
26
27   self = (Py_filter *) type->tp_alloc (type, 0);
28
29   if (self == NULL) {
30     return NULL;
31   }
32
33   self->order = 7;
34
35   if (order > 0) {
36     self->order = order;
37   } else if (order < 0) {
38     PyErr_SetString (PyExc_ValueError,
39         "can not use negative order");
40     return NULL;
41   }
42
43   return (PyObject *) self;
44 }
45
46 static int
47 Py_filter_init (Py_filter * self, PyObject * args, PyObject * kwds)
48 {
49   self->o = new_aubio_filter (self->order);
50   if (self->o == NULL) {
51     return -1;
52   }
53   self->out = NULL;
54   return 0;
55 }
56
57 static void
58 Py_filter_del (Py_filter * self)
59 {
60   Py_XDECREF(self->out);
61   del_aubio_filter (self->o);
62   Py_TYPE(self)->tp_free ((PyObject *) self);
63 }
64
65 static PyObject *
66 Py_filter_do(Py_filter * self, PyObject * args)
67 {
68   PyObject *input;
69
70   if (!PyArg_ParseTuple (args, "O:digital_filter.do", &input)) {
71     return NULL;
72   }
73
74   if (input == NULL) {
75     return NULL;
76   }
77
78   if (!PyAubio_ArrayToCFvec(input, &(self->vec))) {
79     return NULL;
80   }
81
82   // initialize output now
83   if (self->out == NULL) {
84     self->out = new_py_fvec(self->vec.length);
85   }
86
87   Py_INCREF(self->out);
88   if (!PyAubio_ArrayToCFvec(self->out, &(self->c_out)) ) {
89     return NULL;
90   }
91   // compute the function
92   aubio_filter_do_outplace (self->o, &(self->vec), &(self->c_out));
93   return self->out;
94 }
95
96 static PyObject *
97 Py_filter_set_c_weighting (Py_filter * self, PyObject *args)
98 {
99   uint_t err = 0;
100   uint_t samplerate;
101   if (!PyArg_ParseTuple (args, "I", &samplerate)) {
102     return NULL;
103   }
104
105   err = aubio_filter_set_c_weighting (self->o, samplerate);
106   if (err > 0) {
107     PyErr_SetString (PyExc_ValueError,
108         "error when setting filter to C-weighting");
109     return NULL;
110   }
111   Py_RETURN_NONE;
112 }
113
114 static PyObject *
115 Py_filter_set_a_weighting (Py_filter * self, PyObject *args)
116 {
117   uint_t err = 0;
118   uint_t samplerate;
119   if (!PyArg_ParseTuple (args, "I", &samplerate)) {
120     return NULL;
121   }
122
123   err = aubio_filter_set_a_weighting (self->o, samplerate);
124   if (err > 0) {
125     PyErr_SetString (PyExc_ValueError,
126         "error when setting filter to A-weighting");
127     return NULL;
128   }
129   Py_RETURN_NONE;
130 }
131
132 static PyObject *
133 Py_filter_set_biquad(Py_filter * self, PyObject *args)
134 {
135   uint_t err = 0;
136   lsmp_t b0, b1, b2, a1, a2;
137   if (!PyArg_ParseTuple (args, "ddddd", &b0, &b1, &b2, &a1, &a2)) {
138     return NULL;
139   }
140
141   err = aubio_filter_set_biquad (self->o, b0, b1, b2, a1, a2);
142   if (err > 0) {
143     PyErr_SetString (PyExc_ValueError,
144         "error when setting filter with biquad coefficients");
145     return NULL;
146   }
147   Py_RETURN_NONE;
148 }
149
150 static PyMemberDef Py_filter_members[] = {
151   // TODO remove READONLY flag and define getter/setter
152   {"order", T_INT, offsetof (Py_filter, order), READONLY,
153       "order of the filter"},
154   {NULL}                        /* Sentinel */
155 };
156
157 static PyMethodDef Py_filter_methods[] = {
158   {"set_c_weighting", (PyCFunction) Py_filter_set_c_weighting, METH_VARARGS,
159       "set filter coefficients to C-weighting"},
160   {"set_a_weighting", (PyCFunction) Py_filter_set_a_weighting, METH_VARARGS,
161       "set filter coefficients to A-weighting"},
162   {"set_biquad", (PyCFunction) Py_filter_set_biquad, METH_VARARGS,
163       "set b0, b1, b2, a1, a2 biquad coefficients"},
164   {NULL}
165 };
166
167 PyTypeObject Py_filterType = {
168   PyVarObject_HEAD_INIT(NULL, 0)
169   "aubio.digital_filter",       /* tp_name           */
170   sizeof (Py_filter),           /* tp_basicsize      */
171   0,                            /* tp_itemsize       */
172   (destructor) Py_filter_del,   /* tp_dealloc        */
173   0,                            /* tp_print          */
174   0,                            /* tp_getattr        */
175   0,                            /* tp_setattr        */
176   0,                            /* tp_compare        */
177   0, //(reprfunc) Py_filter_repr,    /* tp_repr           */
178   0,                            /* tp_as_number      */
179   0,                            /* tp_as_sequence    */
180   0,                            /* tp_as_mapping     */
181   0,                            /* tp_hash           */
182   (ternaryfunc)Py_filter_do,    /* tp_call           */
183   0,                            /* tp_str            */
184   0,                            /* tp_getattro       */
185   0,                            /* tp_setattro       */
186   0,                            /* tp_as_buffer      */
187   Py_TPFLAGS_DEFAULT,           /* tp_flags          */
188   Py_filter_doc,                /* tp_doc            */
189   0,                            /* tp_traverse       */
190   0,                            /* tp_clear          */
191   0,                            /* tp_richcompare    */
192   0,                            /* tp_weaklistoffset */
193   0,                            /* tp_iter           */
194   0,                            /* tp_iternext       */
195   Py_filter_methods,            /* tp_methods        */
196   Py_filter_members,            /* tp_members        */
197   0,                            /* tp_getset         */
198   0,                            /* tp_base           */
199   0,                            /* tp_dict           */
200   0,                            /* tp_descr_get      */
201   0,                            /* tp_descr_set      */
202   0,                            /* tp_dictoffset     */
203   (initproc) Py_filter_init,    /* tp_init           */
204   0,                            /* tp_alloc          */
205   Py_filter_new,                /* tp_new            */
206   0,
207   0,
208   0,
209   0,
210   0,
211   0,
212   0,
213   0,
214   0,
215 };