source: python/ext/py-filterbank.c @ 337e70d

feature/cnnfeature/crepe
Last change on this file since 337e70d was 843b22f, checked in by Paul Brossier <piem@piem.org>, 5 years ago

[py] incref exception type before restoring it

  • Property mode set to 100644
File size: 14.6 KB
RevLine 
[5652a8c]1#include "aubio-types.h"
[615ac7d]2
[e5efa0f]3static char Py_filterbank_doc[] = ""
4"filterbank(n_filters=40, win_s=1024)\n"
5"\n"
6"Create a bank of spectral filters. Each instance is a callable\n"
7"that holds a matrix of coefficients.\n"
8"\n"
9"See also :meth:`set_mel_coeffs`, :meth:`set_mel_coeffs_htk`,\n"
10":meth:`set_mel_coeffs_slaney`, :meth:`set_triangle_bands`, and\n"
11":meth:`set_coeffs`.\n"
12"\n"
13"Parameters\n"
14"----------\n"
15"n_filters : int\n"
16"    Number of filters to create.\n"
17"win_s : int\n"
18"    Size of the input spectrum to process.\n"
19"\n"
20"Examples\n"
21"--------\n"
22">>> f = aubio.filterbank(128, 1024)\n"
23">>> f.set_mel_coeffs(44100, 0, 10000)\n"
24">>> c = aubio.cvec(1024)\n"
25">>> f(c).shape\n"
26"(128, )\n"
27"";
28
29static char Py_filterbank_set_triangle_bands_doc[] =""
30"set_triangle_bands(freqs, samplerate)\n"
31"\n"
32"Set triangular bands. The coefficients will be set to triangular\n"
33"overlapping windows using the boundaries specified by `freqs`.\n"
34"\n"
35"`freqs` should contain `n_filters + 2` frequencies in Hz, ordered\n"
36"by value, from smallest to largest. The first element should be greater\n"
37"or equal to zero; the last element should be smaller or equal to\n"
38"`samplerate / 2`.\n"
39"\n"
40"Parameters\n"
41"----------\n"
42"freqs: fvec\n"
43"    List of frequencies, in Hz.\n"
44"samplerate : float\n"
45"    Sampling-rate of the expected input.\n"
46"\n"
47"Example\n"
48"-------\n"
49">>> fb = aubio.filterbank(n_filters=100, win_s=2048)\n"
50">>> samplerate = 44100; freqs = np.linspace(0, 20200, 102)\n"
51">>> fb.set_triangle_bands(aubio.fvec(freqs), samplerate)\n"
52"";
53
54static char Py_filterbank_set_mel_coeffs_slaney_doc[] = ""
55"set_mel_coeffs_slaney(samplerate)\n"
56"\n"
57"Set coefficients of filterbank to match Slaney's Auditory Toolbox.\n"
58"\n"
59"The filter coefficients will be set as in Malcolm Slaney's\n"
60"implementation. The filterbank should have been created with\n"
61"`n_filters = 40`.\n"
62"\n"
63"This is approximately equivalent to using :meth:`set_mel_coeffs` with\n"
64"`fmin = 400./3., fmax = 6853.84`.\n"
65"\n"
66"Parameters\n"
67"----------\n"
68"samplerate : float\n"
69"    Sampling-rate of the expected input.\n"
70"\n"
71"References\n"
72"----------\n"
73"\n"
74"Malcolm Slaney, `Auditory Toolbox Version 2, Technical Report #1998-010\n"
75"<https://engineering.purdue.edu/~malcolm/interval/1998-010/>`_\n"
76"";
77
78static char Py_filterbank_set_mel_coeffs_doc[] = ""
79"set_mel_coeffs(samplerate, fmin, fmax)\n"
80"\n"
81"Set coefficients of filterbank to linearly spaced mel scale.\n"
82"\n"
83"Parameters\n"
84"----------\n"
85"samplerate : float\n"
86"    Sampling-rate of the expected input.\n"
87"fmin : float\n"
88"    Lower frequency boundary of the first filter.\n"
89"fmax : float\n"
90"    Upper frequency boundary of the last filter.\n"
91"\n"
92"See also\n"
93"--------\n"
94"hztomel\n"
95"";
96
97static char Py_filterbank_set_mel_coeffs_htk_doc[] = ""
98"set_mel_coeffs_htk(samplerate, fmin, fmax)\n"
99"\n"
100"Set coefficients of the filters to be linearly spaced in the HTK mel scale.\n"
101"\n"
102"Parameters\n"
103"----------\n"
104"samplerate : float\n"
105"    Sampling-rate of the expected input.\n"
106"fmin : float\n"
107"    Lower frequency boundary of the first filter.\n"
108"fmax : float\n"
109"    Upper frequency boundary of the last filter.\n"
110"\n"
111"See also\n"
112"--------\n"
113"hztomel with `htk=True`\n"
114"";
115
116static char Py_filterbank_get_coeffs_doc[] = ""
117"get_coeffs()\n"
118"\n"
119"Get coefficients matrix of filterbank.\n"
120"\n"
121"Returns\n"
122"-------\n"
123"array_like\n"
124"    Array of shape (n_filters, win_s/2+1) containing the coefficients.\n"
125"";
126
127static char Py_filterbank_set_coeffs_doc[] = ""
128"set_coeffs(coeffs)\n"
129"\n"
130"Set coefficients of filterbank.\n"
131"\n"
132"Parameters\n"
133"----------\n"
134"coeffs : fmat\n"
135"    Array of shape (n_filters, win_s/2+1) containing the coefficients.\n"
136"";
137
138static char Py_filterbank_set_power_doc[] = ""
139"set_power(power)\n"
140"\n"
141"Set power applied to input spectrum of filterbank.\n"
142"\n"
143"Parameters\n"
144"----------\n"
145"power : float\n"
146"    Power to raise input spectrum to before computing the filters.\n"
147"";
148
149static char Py_filterbank_get_power_doc[] = ""
150"get_power()\n"
151"\n"
152"Get power applied to filterbank.\n"
153"\n"
154"Returns\n"
155"-------\n"
156"float\n"
157"    Power parameter.\n"
158"";
159
160static char Py_filterbank_set_norm_doc[] = ""
161"set_norm(norm)\n"
162"\n"
163"Set norm parameter. If set to `0`, the filters will not be normalized.\n"
164"If set to `1`, the filters will be normalized to one. Default to `1`.\n"
165"\n"
166"This function should be called *before* :meth:`set_triangle_bands`,\n"
167":meth:`set_mel_coeffs`, :meth:`set_mel_coeffs_htk`, or\n"
168":meth:`set_mel_coeffs_slaney`.\n"
169"\n"
170"Parameters\n"
171"----------\n"
172"norm : int\n"
173"   `0` to disable, `1` to enable\n"
174"";
175
176static char Py_filterbank_get_norm_doc[] = ""
177"get_norm()\n"
178"\n"
179"Get norm parameter of filterbank.\n"
180"\n"
181"Returns\n"
182"-------\n"
183"float\n"
184"    Norm parameter.\n"
185"";
[615ac7d]186
[59cb451]187typedef struct
188{
189  PyObject_HEAD
190  aubio_filterbank_t * o;
191  uint_t n_filters;
192  uint_t win_s;
[569b363]193  cvec_t vec;
194  fvec_t freqs;
195  fmat_t coeffs;
[b055b4e]196  PyObject *out;
197  fvec_t c_out;
[59cb451]198} Py_filterbank;
[615ac7d]199
200static PyObject *
201Py_filterbank_new (PyTypeObject * type, PyObject * args, PyObject * kwds)
202{
203  int win_s = 0, n_filters = 0;
204  Py_filterbank *self;
205  static char *kwlist[] = { "n_filters", "win_s", NULL };
206
207  if (!PyArg_ParseTupleAndKeywords (args, kwds, "|II", kwlist,
208          &n_filters, &win_s)) {
209    return NULL;
210  }
211
212  self = (Py_filterbank *) type->tp_alloc (type, 0);
213
214  if (self == NULL) {
215    return NULL;
216  }
217
218  self->win_s = Py_default_vector_length;
219  if (win_s > 0) {
220    self->win_s = win_s;
221  } else if (win_s < 0) {
222    PyErr_SetString (PyExc_ValueError,
223        "can not use negative window size");
224    return NULL;
225  }
226
227  self->n_filters = 40;
228  if (n_filters > 0) {
229    self->n_filters = n_filters;
230  } else if (n_filters < 0) {
231    PyErr_SetString (PyExc_ValueError,
232        "can not use negative number of filters");
233    return NULL;
234  }
235
236  return (PyObject *) self;
237}
238
[59cb451]239static int
240Py_filterbank_init (Py_filterbank * self, PyObject * args, PyObject * kwds)
241{
242  self->o = new_aubio_filterbank (self->n_filters, self->win_s);
243  if (self->o == NULL) {
[7876b67]244    PyErr_Format(PyExc_RuntimeError, "error creating filterbank with"
245        " n_filters=%d, win_s=%d", self->n_filters, self->win_s);
[59cb451]246    return -1;
247  }
[b055b4e]248  self->out = new_py_fvec(self->n_filters);
[615ac7d]249
[59cb451]250  return 0;
251}
[615ac7d]252
[59cb451]253static void
254Py_filterbank_del (Py_filterbank *self, PyObject *unused)
255{
[7876b67]256  if (self->o) {
257    free(self->coeffs.data);
258    del_aubio_filterbank(self->o);
259  }
260  Py_XDECREF(self->out);
[5c1200a]261  Py_TYPE(self)->tp_free((PyObject *) self);
[59cb451]262}
[615ac7d]263
[f6cbefe]264static PyObject *
[615ac7d]265Py_filterbank_do(Py_filterbank * self, PyObject * args)
266{
267  PyObject *input;
268
269  if (!PyArg_ParseTuple (args, "O", &input)) {
270    return NULL;
271  }
272
[92a8800]273  if (!PyAubio_PyCvecToCCvec(input, &(self->vec) )) {
[615ac7d]274    return NULL;
275  }
276
[de0a492]277  if (self->vec.length != self->win_s / 2 + 1) {
278    PyErr_Format(PyExc_ValueError,
[b5cec0c]279                 "input cvec has length %d, but filterbank expects length %d",
[de0a492]280                 self->vec.length, self->win_s / 2 + 1);
281    return NULL;
282  }
283
[b055b4e]284  Py_INCREF(self->out);
285  if (!PyAubio_ArrayToCFvec(self->out, &(self->c_out))) {
286    return NULL;
287  }
[615ac7d]288  // compute the function
[b055b4e]289  aubio_filterbank_do (self->o, &(self->vec), &(self->c_out));
290  return self->out;
[615ac7d]291}
292
[5652a8c]293static PyMemberDef Py_filterbank_members[] = {
[615ac7d]294  {"win_s", T_INT, offsetof (Py_filterbank, win_s), READONLY,
295    "size of the window"},
296  {"n_filters", T_INT, offsetof (Py_filterbank, n_filters), READONLY,
297    "number of filters"},
[5652a8c]298  {NULL} /* sentinel */
299};
[615ac7d]300
[f6cbefe]301static PyObject *
[615ac7d]302Py_filterbank_set_triangle_bands (Py_filterbank * self, PyObject *args)
303{
304  uint_t err = 0;
305
306  PyObject *input;
[35ce4ab]307  smpl_t samplerate;
[51284ab]308  if (!PyArg_ParseTuple (args, "O" AUBIO_NPY_SMPL_CHR, &input, &samplerate)) {
[615ac7d]309    return NULL;
310  }
311
312  if (input == NULL) {
313    return NULL;
314  }
315
[569b363]316  if (!PyAubio_ArrayToCFvec(input, &(self->freqs) )) {
[615ac7d]317    return NULL;
318  }
319
320  err = aubio_filterbank_set_triangle_bands (self->o,
[569b363]321      &(self->freqs), samplerate);
[615ac7d]322  if (err > 0) {
[04cd251]323    if (PyErr_Occurred() == NULL) {
324      PyErr_SetString (PyExc_ValueError, "error running set_triangle_bands");
325    } else {
326      // change the RuntimeError into ValueError
327      PyObject *type, *value, *traceback;
328      PyErr_Fetch(&type, &value, &traceback);
[843b22f]329      Py_XDECREF(type);
330      type = PyExc_ValueError;
331      Py_XINCREF(type);
332      PyErr_Restore(type, value, traceback);
[04cd251]333    }
[615ac7d]334    return NULL;
335  }
[9e6695d]336  Py_RETURN_NONE;
[615ac7d]337}
338
[f6cbefe]339static PyObject *
[615ac7d]340Py_filterbank_set_mel_coeffs_slaney (Py_filterbank * self, PyObject *args)
341{
342  uint_t err = 0;
343
[a380b73]344  smpl_t samplerate;
345  if (!PyArg_ParseTuple (args, AUBIO_NPY_SMPL_CHR, &samplerate)) {
[615ac7d]346    return NULL;
347  }
348
349  err = aubio_filterbank_set_mel_coeffs_slaney (self->o, samplerate);
350  if (err > 0) {
[04cd251]351    if (PyErr_Occurred() == NULL) {
352      PyErr_SetString (PyExc_ValueError, "error running set_mel_coeffs_slaney");
353    } else {
354      // change the RuntimeError into ValueError
355      PyObject *type, *value, *traceback;
356      PyErr_Fetch(&type, &value, &traceback);
[843b22f]357      Py_XDECREF(type);
358      type = PyExc_ValueError;
359      Py_XINCREF(type);
360      PyErr_Restore(type, value, traceback);
[04cd251]361    }
362    return NULL;
363  }
364  Py_RETURN_NONE;
365}
366
367static PyObject *
368Py_filterbank_set_mel_coeffs (Py_filterbank * self, PyObject *args)
369{
370  uint_t err = 0;
371
[f6bfc26]372  smpl_t samplerate;
[04cd251]373  smpl_t freq_min;
374  smpl_t freq_max;
[f6bfc26]375  if (!PyArg_ParseTuple (args, AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR
376        AUBIO_NPY_SMPL_CHR, &samplerate, &freq_min, &freq_max)) {
[04cd251]377    return NULL;
378  }
379
380  err = aubio_filterbank_set_mel_coeffs (self->o, samplerate,
381      freq_min, freq_max);
382  if (err > 0) {
383    if (PyErr_Occurred() == NULL) {
384      PyErr_SetString (PyExc_ValueError, "error running set_mel_coeffs");
385    } else {
386      // change the RuntimeError into ValueError
387      PyObject *type, *value, *traceback;
388      PyErr_Fetch(&type, &value, &traceback);
[843b22f]389      Py_XDECREF(type);
390      type = PyExc_ValueError;
391      Py_XINCREF(type);
392      PyErr_Restore(type, value, traceback);
[04cd251]393    }
394    return NULL;
395  }
396  Py_RETURN_NONE;
397}
398
399static PyObject *
400Py_filterbank_set_mel_coeffs_htk (Py_filterbank * self, PyObject *args)
401{
402  uint_t err = 0;
403
[f6bfc26]404  smpl_t samplerate;
[04cd251]405  smpl_t freq_min;
406  smpl_t freq_max;
[f6bfc26]407  if (!PyArg_ParseTuple (args, AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR
408        AUBIO_NPY_SMPL_CHR, &samplerate, &freq_min, &freq_max)) {
[04cd251]409    return NULL;
410  }
411
[1d51820]412  err = aubio_filterbank_set_mel_coeffs_htk (self->o, samplerate,
413      freq_min, freq_max);
[04cd251]414  if (err > 0) {
415    if (PyErr_Occurred() == NULL) {
416      PyErr_SetString (PyExc_ValueError, "error running set_mel_coeffs_htk");
417    } else {
418      // change the RuntimeError into ValueError
419      PyObject *type, *value, *traceback;
420      PyErr_Fetch(&type, &value, &traceback);
[843b22f]421      Py_XDECREF(type);
422      type = PyExc_ValueError;
423      Py_XINCREF(type);
424      PyErr_Restore(type, value, traceback);
[04cd251]425    }
[615ac7d]426    return NULL;
427  }
[9e6695d]428  Py_RETURN_NONE;
[615ac7d]429}
430
[f6cbefe]431static PyObject *
432Py_filterbank_set_coeffs (Py_filterbank * self, PyObject *args)
433{
434  uint_t err = 0;
435
436  PyObject *input;
437  if (!PyArg_ParseTuple (args, "O", &input)) {
438    return NULL;
439  }
440
[569b363]441  if (!PyAubio_ArrayToCFmat(input, &(self->coeffs))) {
[f6cbefe]442    return NULL;
443  }
444
[569b363]445  err = aubio_filterbank_set_coeffs (self->o, &(self->coeffs));
[f6cbefe]446
447  if (err > 0) {
448    PyErr_SetString (PyExc_ValueError,
449        "error when setting filter coefficients");
450    return NULL;
451  }
[9e6695d]452  Py_RETURN_NONE;
[f6cbefe]453}
454
455static PyObject *
[615ac7d]456Py_filterbank_get_coeffs (Py_filterbank * self, PyObject *unused)
457{
[363ce7a]458  return (PyObject *)PyAubio_CFmatToArray(
459      aubio_filterbank_get_coeffs (self->o) );
[615ac7d]460}
461
[78706cd]462static PyObject *
463Py_filterbank_set_power(Py_filterbank *self, PyObject *args)
464{
[35f7e059]465  smpl_t power;
[78706cd]466
[51284ab]467  if (!PyArg_ParseTuple (args, AUBIO_NPY_SMPL_CHR, &power)) {
[78706cd]468    return NULL;
469  }
[f6bfc26]470  if(aubio_filterbank_set_power (self->o, power)) {
[78706cd]471    if (PyErr_Occurred() == NULL) {
472      PyErr_SetString (PyExc_ValueError,
473          "error running filterbank.set_power");
474    } else {
475      // change the RuntimeError into ValueError
476      PyObject *type, *value, *traceback;
477      PyErr_Fetch(&type, &value, &traceback);
[843b22f]478      Py_XDECREF(type);
479      type = PyExc_ValueError;
480      Py_XINCREF(type);
481      PyErr_Restore(type, value, traceback);
[78706cd]482    }
483    return NULL;
484  }
485  Py_RETURN_NONE;
486}
487
488static PyObject *
[e5efa0f]489Py_filterbank_get_power (Py_filterbank * self, PyObject *unused)
490{
491  smpl_t power = aubio_filterbank_get_power(self->o);
492  return (PyObject *)PyFloat_FromDouble (power);
493}
494
495static PyObject *
[78706cd]496Py_filterbank_set_norm(Py_filterbank *self, PyObject *args)
497{
[35f7e059]498  smpl_t norm;
[78706cd]499
[51284ab]500  if (!PyArg_ParseTuple (args, AUBIO_NPY_SMPL_CHR, &norm)) {
[78706cd]501    return NULL;
502  }
[35f7e059]503  if(aubio_filterbank_set_norm (self->o, norm)) {
[78706cd]504    if (PyErr_Occurred() == NULL) {
505      PyErr_SetString (PyExc_ValueError,
506          "error running filterbank.set_power");
507    } else {
508      // change the RuntimeError into ValueError
509      PyObject *type, *value, *traceback;
510      PyErr_Fetch(&type, &value, &traceback);
[843b22f]511      Py_XDECREF(type);
512      type = PyExc_ValueError;
513      Py_XINCREF(type);
514      PyErr_Restore(type, value, traceback);
[78706cd]515    }
516    return NULL;
517  }
518  Py_RETURN_NONE;
519}
520
[e5efa0f]521static PyObject *
522Py_filterbank_get_norm (Py_filterbank * self, PyObject *unused)
523{
524  smpl_t norm = aubio_filterbank_get_norm(self->o);
525  return (PyObject *)PyFloat_FromDouble (norm);
526}
527
[615ac7d]528static PyMethodDef Py_filterbank_methods[] = {
529  {"set_triangle_bands", (PyCFunction) Py_filterbank_set_triangle_bands,
[e5efa0f]530    METH_VARARGS, Py_filterbank_set_triangle_bands_doc},
[615ac7d]531  {"set_mel_coeffs_slaney", (PyCFunction) Py_filterbank_set_mel_coeffs_slaney,
[e5efa0f]532    METH_VARARGS, Py_filterbank_set_mel_coeffs_slaney_doc},
[04cd251]533  {"set_mel_coeffs", (PyCFunction) Py_filterbank_set_mel_coeffs,
[e5efa0f]534    METH_VARARGS, Py_filterbank_set_mel_coeffs_doc},
[04cd251]535  {"set_mel_coeffs_htk", (PyCFunction) Py_filterbank_set_mel_coeffs_htk,
[e5efa0f]536    METH_VARARGS, Py_filterbank_set_mel_coeffs_htk_doc},
[615ac7d]537  {"get_coeffs", (PyCFunction) Py_filterbank_get_coeffs,
[e5efa0f]538    METH_NOARGS, Py_filterbank_get_coeffs_doc},
[f6cbefe]539  {"set_coeffs", (PyCFunction) Py_filterbank_set_coeffs,
[e5efa0f]540    METH_VARARGS, Py_filterbank_set_coeffs_doc},
[78706cd]541  {"set_power", (PyCFunction) Py_filterbank_set_power,
[e5efa0f]542    METH_VARARGS, Py_filterbank_set_power_doc},
543  {"get_power", (PyCFunction) Py_filterbank_get_power,
544    METH_NOARGS, Py_filterbank_get_power_doc},
[78706cd]545  {"set_norm", (PyCFunction) Py_filterbank_set_norm,
[e5efa0f]546    METH_VARARGS, Py_filterbank_set_norm_doc},
547  {"get_norm", (PyCFunction) Py_filterbank_get_norm,
548    METH_NOARGS, Py_filterbank_get_norm_doc},
[615ac7d]549  {NULL}
550};
551
[5652a8c]552PyTypeObject Py_filterbankType = {
553  PyVarObject_HEAD_INIT (NULL, 0)
554  "aubio.filterbank",
555  sizeof (Py_filterbank),
556  0,
557  (destructor) Py_filterbank_del,
558  0,
559  0,
560  0,
561  0,
562  0,
563  0,
564  0,
565  0,
566  0,
567  (ternaryfunc)Py_filterbank_do,
568  0,
569  0,
570  0,
571  0,
572  Py_TPFLAGS_DEFAULT,
573  Py_filterbank_doc,
574  0,
575  0,
576  0,
577  0,
578  0,
579  0,
580  Py_filterbank_methods,
581  Py_filterbank_members,
582  0,
583  0,
584  0,
585  0,
586  0,
587  0,
588  (initproc) Py_filterbank_init,
589  0,
590  Py_filterbank_new,
[0e70ef9]591  0,
592  0,
593  0,
594  0,
595  0,
596  0,
597  0,
598  0,
599  0,
[5652a8c]600};
Note: See TracBrowser for help on using the repository browser.