source: python/ext/py-filter.c @ 11c46c8

feature/autosinkfeature/cnnfeature/crepefeature/crepe_orgfeature/timestretchfix/ffmpeg5
Last change on this file since 11c46c8 was 11c46c8, checked in by Paul Brossier <piem@piem.org>, 6 years ago

[py] digital_filter.set_* raise ValueError? (see #gh-241)

  • Property mode set to 100644
File size: 7.7 KB
RevLine 
[f826349]1#include "aubio-types.h"
2
3typedef struct
4{
5  PyObject_HEAD
6  aubio_filter_t * o;
7  uint_t order;
[569b363]8  fvec_t vec;
[21e8408]9  PyObject *out;
10  fvec_t c_out;
[f826349]11} Py_filter;
12
[1030a7b]13static char Py_filter_doc[] = ""
14"digital_filter(order=7)\n"
15"\n"
16"Create a digital filter.\n"
17"";
18
19static char Py_filter_set_c_weighting_doc[] = ""
20"set_c_weighting(samplerate)\n"
21"\n"
22"Set filter coefficients to C-weighting.\n"
23"\n"
24"`samplerate` should be one of 8000, 11025, 16000, 22050, 24000, 32000,\n"
25"44100, 48000, 88200, 96000, or 192000. `order` of the filter should be 5.\n"
26"\n"
27"Parameters\n"
28"----------\n"
29"samplerate : int\n"
30"    Sampling-rate of the input signal, in Hz.\n"
31"";
32
33static char Py_filter_set_a_weighting_doc[] = ""
34"set_a_weighting(samplerate)\n"
35"\n"
36"Set filter coefficients to A-weighting.\n"
37"\n"
38"`samplerate` should be one of 8000, 11025, 16000, 22050, 24000, 32000,\n"
39"44100, 48000, 88200, 96000, or 192000. `order` of the filter should be 7.\n"
40"\n"
41"Parameters\n"
42"----------\n"
43"samplerate : int\n"
44"    Sampling-rate of the input signal.\n"
45"";
46
47static char Py_filter_set_biquad_doc[] = ""
48"set_biquad(b0, b1, b2, a1, a2)\n"
49"\n"
50"Set biquad coefficients. `order` of the filter should be 3.\n"
51"\n"
52"Parameters\n"
53"----------\n"
54"b0 : float\n"
55"    Forward filter coefficient.\n"
56"b1 : float\n"
57"    Forward filter coefficient.\n"
58"b2 : float\n"
59"    Forward filter coefficient.\n"
60"a1 : float\n"
61"    Feedback filter coefficient.\n"
62"a2 : float\n"
63"    Feedback filter coefficient.\n"
64"";
[f826349]65
66static PyObject *
67Py_filter_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
68{
[96fe713]69  int order= 0;
[f826349]70  Py_filter *self;
[96fe713]71  static char *kwlist[] = { "order", NULL };
[f826349]72
[a52d3ae]73  if (!PyArg_ParseTupleAndKeywords (args, kwds, "|I", kwlist,
[96fe713]74          &order)) {
[f826349]75    return NULL;
76  }
77
78  self = (Py_filter *) type->tp_alloc (type, 0);
79
80  if (self == NULL) {
81    return NULL;
82  }
83
[615ac7d]84  self->order = 7;
[f826349]85
86  if (order > 0) {
87    self->order = order;
88  } else if (order < 0) {
89    PyErr_SetString (PyExc_ValueError,
90        "can not use negative order");
91    return NULL;
92  }
93
94  return (PyObject *) self;
95}
96
97static int
98Py_filter_init (Py_filter * self, PyObject * args, PyObject * kwds)
99{
[96fe713]100  self->o = new_aubio_filter (self->order);
[f826349]101  if (self->o == NULL) {
102    return -1;
103  }
[21e8408]104  self->out = NULL;
[f826349]105  return 0;
106}
107
108static void
109Py_filter_del (Py_filter * self)
110{
[21e8408]111  Py_XDECREF(self->out);
[a9f463c]112  if (self->o)
113    del_aubio_filter (self->o);
[770b9e7]114  Py_TYPE(self)->tp_free ((PyObject *) self);
[f826349]115}
116
[21e8408]117static PyObject *
[a52d3ae]118Py_filter_do(Py_filter * self, PyObject * args)
[f826349]119{
120  PyObject *input;
121
122  if (!PyArg_ParseTuple (args, "O:digital_filter.do", &input)) {
123    return NULL;
124  }
125
126  if (input == NULL) {
127    return NULL;
128  }
129
[569b363]130  if (!PyAubio_ArrayToCFvec(input, &(self->vec))) {
[f826349]131    return NULL;
132  }
133
[21e8408]134  // initialize output now
135  if (self->out == NULL) {
136    self->out = new_py_fvec(self->vec.length);
137  }
138
139  Py_INCREF(self->out);
140  if (!PyAubio_ArrayToCFvec(self->out, &(self->c_out)) ) {
141    return NULL;
[7c785e6]142  }
[f826349]143  // compute the function
[21e8408]144  aubio_filter_do_outplace (self->o, &(self->vec), &(self->c_out));
145  return self->out;
[f826349]146}
147
[21e8408]148static PyObject *
[615ac7d]149Py_filter_set_c_weighting (Py_filter * self, PyObject *args)
[f826349]150{
[615ac7d]151  uint_t err = 0;
152  uint_t samplerate;
153  if (!PyArg_ParseTuple (args, "I", &samplerate)) {
154    return NULL;
155  }
156
157  err = aubio_filter_set_c_weighting (self->o, samplerate);
[f826349]158  if (err > 0) {
[8bfef30]159    if (PyErr_Occurred() == NULL) {
160      PyErr_SetString (PyExc_ValueError,
161          "error when setting filter to C-weighting");
[11c46c8]162    } else {
163      // change the RuntimeError into ValueError
164      PyObject *type, *value, *traceback;
165      PyErr_Fetch(&type, &value, &traceback);
166      PyErr_Restore(PyExc_ValueError, value, traceback);
[8bfef30]167    }
[f826349]168    return NULL;
169  }
[9e6695d]170  Py_RETURN_NONE;
[f826349]171}
172
[21e8408]173static PyObject *
[615ac7d]174Py_filter_set_a_weighting (Py_filter * self, PyObject *args)
[f826349]175{
[615ac7d]176  uint_t err = 0;
177  uint_t samplerate;
178  if (!PyArg_ParseTuple (args, "I", &samplerate)) {
179    return NULL;
180  }
181
182  err = aubio_filter_set_a_weighting (self->o, samplerate);
[f826349]183  if (err > 0) {
[8bfef30]184    if (PyErr_Occurred() == NULL) {
185      PyErr_SetString (PyExc_ValueError,
186          "error when setting filter to A-weighting");
[11c46c8]187    } else {
188      // change the RuntimeError into ValueError
189      PyObject *type, *value, *traceback;
190      PyErr_Fetch(&type, &value, &traceback);
191      PyErr_Restore(PyExc_ValueError, value, traceback);
[8bfef30]192    }
[f826349]193    return NULL;
194  }
[9e6695d]195  Py_RETURN_NONE;
[f826349]196}
197
[a81c8cd]198static PyObject *
199Py_filter_set_biquad(Py_filter * self, PyObject *args)
200{
201  uint_t err = 0;
202  lsmp_t b0, b1, b2, a1, a2;
203  if (!PyArg_ParseTuple (args, "ddddd", &b0, &b1, &b2, &a1, &a2)) {
204    return NULL;
205  }
206
207  err = aubio_filter_set_biquad (self->o, b0, b1, b2, a1, a2);
208  if (err > 0) {
[8bfef30]209    if (PyErr_Occurred() == NULL) {
210      PyErr_SetString (PyExc_ValueError,
211          "error when setting filter with biquad coefficients");
[11c46c8]212    } else {
213      // change the RuntimeError into ValueError
214      PyObject *type, *value, *traceback;
215      PyErr_Fetch(&type, &value, &traceback);
216      PyErr_Restore(PyExc_ValueError, value, traceback);
[8bfef30]217    }
[a81c8cd]218    return NULL;
219  }
[9e6695d]220  Py_RETURN_NONE;
[a81c8cd]221}
222
[f826349]223static PyMemberDef Py_filter_members[] = {
224  // TODO remove READONLY flag and define getter/setter
225  {"order", T_INT, offsetof (Py_filter, order), READONLY,
226      "order of the filter"},
227  {NULL}                        /* Sentinel */
228};
229
230static PyMethodDef Py_filter_methods[] = {
[07bf04e6]231  {"set_c_weighting", (PyCFunction) Py_filter_set_c_weighting, METH_VARARGS,
[1030a7b]232      Py_filter_set_c_weighting_doc},
[07bf04e6]233  {"set_a_weighting", (PyCFunction) Py_filter_set_a_weighting, METH_VARARGS,
[1030a7b]234      Py_filter_set_a_weighting_doc},
[a81c8cd]235  {"set_biquad", (PyCFunction) Py_filter_set_biquad, METH_VARARGS,
[1030a7b]236      Py_filter_set_biquad_doc},
[f826349]237  {NULL}
238};
239
240PyTypeObject Py_filterType = {
[5c1200a]241  PyVarObject_HEAD_INIT(NULL, 0)
[f826349]242  "aubio.digital_filter",       /* tp_name           */
243  sizeof (Py_filter),           /* tp_basicsize      */
244  0,                            /* tp_itemsize       */
245  (destructor) Py_filter_del,   /* tp_dealloc        */
246  0,                            /* tp_print          */
247  0,                            /* tp_getattr        */
248  0,                            /* tp_setattr        */
249  0,                            /* tp_compare        */
250  0, //(reprfunc) Py_filter_repr,    /* tp_repr           */
251  0,                            /* tp_as_number      */
252  0,                            /* tp_as_sequence    */
253  0,                            /* tp_as_mapping     */
254  0,                            /* tp_hash           */
255  (ternaryfunc)Py_filter_do,    /* tp_call           */
256  0,                            /* tp_str            */
257  0,                            /* tp_getattro       */
258  0,                            /* tp_setattro       */
259  0,                            /* tp_as_buffer      */
260  Py_TPFLAGS_DEFAULT,           /* tp_flags          */
261  Py_filter_doc,                /* tp_doc            */
262  0,                            /* tp_traverse       */
263  0,                            /* tp_clear          */
264  0,                            /* tp_richcompare    */
265  0,                            /* tp_weaklistoffset */
266  0,                            /* tp_iter           */
267  0,                            /* tp_iternext       */
268  Py_filter_methods,            /* tp_methods        */
269  Py_filter_members,            /* tp_members        */
270  0,                            /* tp_getset         */
271  0,                            /* tp_base           */
272  0,                            /* tp_dict           */
273  0,                            /* tp_descr_get      */
274  0,                            /* tp_descr_set      */
275  0,                            /* tp_dictoffset     */
276  (initproc) Py_filter_init,    /* tp_init           */
277  0,                            /* tp_alloc          */
278  Py_filter_new,                /* tp_new            */
[0e70ef9]279  0,
280  0,
281  0,
282  0,
283  0,
284  0,
285  0,
286  0,
287  0,
[f826349]288};
Note: See TracBrowser for help on using the repository browser.