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