err = aubio_filterbank_set_triangle_bands (self->o,
&(self->freqs), samplerate);
if (err > 0) {
- PyErr_SetString (PyExc_ValueError,
- "error when running set_triangle_bands");
+ if (PyErr_Occurred() == NULL) {
+ PyErr_SetString (PyExc_ValueError, "error running set_triangle_bands");
+ } else {
+ // change the RuntimeError into ValueError
+ PyObject *type, *value, *traceback;
+ PyErr_Fetch(&type, &value, &traceback);
+ PyErr_Restore(PyExc_ValueError, value, traceback);
+ }
return NULL;
}
Py_RETURN_NONE;
err = aubio_filterbank_set_mel_coeffs_slaney (self->o, samplerate);
if (err > 0) {
- PyErr_SetString (PyExc_ValueError,
- "error when running set_mel_coeffs_slaney");
+ if (PyErr_Occurred() == NULL) {
+ PyErr_SetString (PyExc_ValueError, "error running set_mel_coeffs_slaney");
+ } else {
+ // change the RuntimeError into ValueError
+ PyObject *type, *value, *traceback;
+ PyErr_Fetch(&type, &value, &traceback);
+ PyErr_Restore(PyExc_ValueError, value, traceback);
+ }
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+static PyObject *
+Py_filterbank_set_mel_coeffs (Py_filterbank * self, PyObject *args)
+{
+ uint_t err = 0;
+
+ uint_t samplerate;
+ smpl_t freq_min;
+ smpl_t freq_max;
+ if (!PyArg_ParseTuple (args, "I" AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR,
+ &samplerate, &freq_min, &freq_max)) {
+ return NULL;
+ }
+
+ err = aubio_filterbank_set_mel_coeffs (self->o, samplerate,
+ freq_min, freq_max);
+ if (err > 0) {
+ if (PyErr_Occurred() == NULL) {
+ PyErr_SetString (PyExc_ValueError, "error running set_mel_coeffs");
+ } else {
+ // change the RuntimeError into ValueError
+ PyObject *type, *value, *traceback;
+ PyErr_Fetch(&type, &value, &traceback);
+ PyErr_Restore(PyExc_ValueError, value, traceback);
+ }
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+static PyObject *
+Py_filterbank_set_mel_coeffs_htk (Py_filterbank * self, PyObject *args)
+{
+ uint_t err = 0;
+
+ uint_t samplerate;
+ smpl_t freq_min;
+ smpl_t freq_max;
+ if (!PyArg_ParseTuple (args, "I" AUBIO_NPY_SMPL_CHR AUBIO_NPY_SMPL_CHR,
+ &samplerate, &freq_min, &freq_max)) {
+ return NULL;
+ }
+
+ err = aubio_filterbank_set_mel_coeffs_htk (self->o, samplerate,
+ freq_min, freq_max);
+ if (err > 0) {
+ if (PyErr_Occurred() == NULL) {
+ PyErr_SetString (PyExc_ValueError, "error running set_mel_coeffs_htk");
+ } else {
+ // change the RuntimeError into ValueError
+ PyObject *type, *value, *traceback;
+ PyErr_Fetch(&type, &value, &traceback);
+ PyErr_Restore(PyExc_ValueError, value, traceback);
+ }
return NULL;
}
Py_RETURN_NONE;
aubio_filterbank_get_coeffs (self->o) );
}
+static PyObject *
+Py_filterbank_set_power(Py_filterbank *self, PyObject *args)
+{
+ uint_t playing;
+
+ if (!PyArg_ParseTuple (args, "I", &playing)) {
+ return NULL;
+ }
+ if(aubio_filterbank_set_power (self->o, playing)) {
+ if (PyErr_Occurred() == NULL) {
+ PyErr_SetString (PyExc_ValueError,
+ "error running filterbank.set_power");
+ } else {
+ // change the RuntimeError into ValueError
+ PyObject *type, *value, *traceback;
+ PyErr_Fetch(&type, &value, &traceback);
+ PyErr_Restore(PyExc_ValueError, value, traceback);
+ }
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+static PyObject *
+Py_filterbank_set_norm(Py_filterbank *self, PyObject *args)
+{
+ uint_t playing;
+
+ if (!PyArg_ParseTuple (args, "I", &playing)) {
+ return NULL;
+ }
+ if(aubio_filterbank_set_norm (self->o, playing)) {
+ if (PyErr_Occurred() == NULL) {
+ PyErr_SetString (PyExc_ValueError,
+ "error running filterbank.set_power");
+ } else {
+ // change the RuntimeError into ValueError
+ PyObject *type, *value, *traceback;
+ PyErr_Fetch(&type, &value, &traceback);
+ PyErr_Restore(PyExc_ValueError, value, traceback);
+ }
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
static PyMethodDef Py_filterbank_methods[] = {
{"set_triangle_bands", (PyCFunction) Py_filterbank_set_triangle_bands,
METH_VARARGS, "set coefficients of filterbanks"},
{"set_mel_coeffs_slaney", (PyCFunction) Py_filterbank_set_mel_coeffs_slaney,
METH_VARARGS, "set coefficients of filterbank as in Auditory Toolbox"},
+ {"set_mel_coeffs", (PyCFunction) Py_filterbank_set_mel_coeffs,
+ METH_VARARGS, "set coefficients of filterbank to linearly spaced mel scale"},
+ {"set_mel_coeffs_htk", (PyCFunction) Py_filterbank_set_mel_coeffs_htk,
+ METH_VARARGS, "set coefficients of filterbank to linearly spaced mel scale"},
{"get_coeffs", (PyCFunction) Py_filterbank_get_coeffs,
METH_NOARGS, "get coefficients of filterbank"},
{"set_coeffs", (PyCFunction) Py_filterbank_set_coeffs,
METH_VARARGS, "set coefficients of filterbank"},
+ {"set_power", (PyCFunction) Py_filterbank_set_power,
+ METH_VARARGS, "set power applied to filterbank input spectrum"},
+ {"set_norm", (PyCFunction) Py_filterbank_set_norm,
+ METH_VARARGS, "set norm applied to filterbank input spectrum"},
{NULL}
};
#include "fvec.h"
#include "fmat.h"
#include "cvec.h"
+#include "vecutils.h"
#include "spectral/filterbank.h"
#include "mathutils.h"
uint_t win_s;
uint_t n_filters;
fmat_t *filters;
+ smpl_t norm;
+ smpl_t power;
};
aubio_filterbank_t *
/* allocate filter tables, a matrix of length win_s and of height n_filters */
fb->filters = new_fmat (n_filters, win_s / 2 + 1);
+ fb->norm = 1;
+
+ fb->power = 1;
+
return fb;
}
tmp.length = in->length;
tmp.data = in->norm;
+ if (f->power != 1.) fvec_pow(&tmp, f->power);
+
fmat_vecmul(f->filters, &tmp, out);
return;
fmat_copy(filter_coeffs, f->filters);
return 0;
}
+
+uint_t
+aubio_filterbank_set_norm (aubio_filterbank_t *f, smpl_t norm)
+{
+ if (norm != 0 && norm != 1) return AUBIO_FAIL;
+ f->norm = norm;
+ return AUBIO_OK;
+}
+
+smpl_t
+aubio_filterbank_get_norm (aubio_filterbank_t *f)
+{
+ return f->norm;
+}
+
+uint_t
+aubio_filterbank_set_power (aubio_filterbank_t *f, smpl_t power)
+{
+ f->power = power;
+ return AUBIO_OK;
+}
+
+smpl_t
+aubio_filterbank_get_power (aubio_filterbank_t *f)
+{
+ return f->norm;
+}
*/
uint_t aubio_filterbank_set_coeffs (aubio_filterbank_t * f, const fmat_t * filters);
+/** set norm parameter
+
+ \param f filterbank object, as returned by new_aubio_filterbank()
+ \param norm `1` to norm the filters, `0` otherwise.
+
+ If set to `0`, the filters will not be normalized. If set to `1`,
+ each filter will be normalized to one. Defaults to `1`.
+
+ This function should be called *before* setting the filters with one of
+ aubio_filterbank_set_triangle_bands(), aubio_filterbank_set_mel_coeffs(),
+ aubio_filterbank_set_mel_coeffs_htk(), or
+ aubio_filterbank_set_mel_coeffs_slaney().
+
+ */
+uint_t aubio_filterbank_set_norm (aubio_filterbank_t *f, smpl_t norm);
+
+/** get norm parameter
+
+ \param f filterbank object, as returned by new_aubio_filterbank()
+ \returns `1` if norm is set, `0` otherwise. Defaults to `1`.
+
+ */
+smpl_t aubio_filterbank_get_norm (aubio_filterbank_t *f);
+
+/** set power parameter
+
+ \param f filterbank object, as returned by new_aubio_filterbank()
+ \param power Raise norm of the input spectrum norm to this power before
+ computing filterbank. Defaults to `1`.
+
+ */
+uint_t aubio_filterbank_set_power (aubio_filterbank_t *f, smpl_t power);
+
+/** get power parameter
+
+ \param f filterbank object, as returned by new_aubio_filterbank()
+ \return current power parameter. Defaults to `1`.
+
+ */
+smpl_t aubio_filterbank_get_power (aubio_filterbank_t *f);
+
#ifdef __cplusplus
}
#endif
}
/* compute triangle heights so that each triangle has unit area */
- for (fn = 0; fn < n_filters; fn++) {
- triangle_heights->data[fn] =
- 2. / (upper_freqs->data[fn] - lower_freqs->data[fn]);
+ if (aubio_filterbank_get_norm(fb)) {
+ for (fn = 0; fn < n_filters; fn++) {
+ triangle_heights->data[fn] =
+ 2. / (upper_freqs->data[fn] - lower_freqs->data[fn]);
+ }
+ } else {
+ fvec_ones (triangle_heights);
}
/* fill fft_freqs lookup table, which assigns the frequency in hz to each bin */
}
/* compute positive slope step size */
- riseInc =
- triangle_heights->data[fn] /
- (center_freqs->data[fn] - lower_freqs->data[fn]);
+ riseInc = triangle_heights->data[fn]
+ / (center_freqs->data[fn] - lower_freqs->data[fn]);
/* compute coefficients in positive slope */
for (; bin < win_s - 1; bin++) {
}
/* compute negative slope step size */
- downInc =
- triangle_heights->data[fn] /
- (upper_freqs->data[fn] - center_freqs->data[fn]);
+ downInc = triangle_heights->data[fn]
+ / (upper_freqs->data[fn] - center_freqs->data[fn]);
/* compute coefficents in negative slope */
for (; bin < win_s - 1; bin++) {
return retval;
}
+
+uint_t
+aubio_filterbank_set_mel_coeffs (aubio_filterbank_t * fb, smpl_t samplerate,
+ smpl_t freq_min, smpl_t freq_max)
+{
+ uint_t m, retval;
+ smpl_t start, end, step;
+ fvec_t *freqs;
+ fmat_t *coeffs = aubio_filterbank_get_coeffs(fb);
+ uint_t n_bands = coeffs->height;
+
+ if (freq_max < 0) {
+ AUBIO_ERR("filterbank: set_mel_coeffs freq_max should be > 0\n");
+ return AUBIO_FAIL;
+ } else if (freq_max == 0) {
+ end = aubio_hztomel(samplerate / 2.);
+ } else {
+ end = aubio_hztomel(freq_max);
+ }
+ if (freq_min < 0) {
+ AUBIO_ERR("filterbank: set_mel_coeffs freq_min should be > 0\n");
+ return AUBIO_FAIL;
+ } else {
+ start = aubio_hztomel(freq_min);
+ }
+ if (n_bands <= 0) {
+ AUBIO_ERR("filterbank: set_mel_coeffs n_bands should be > 0\n");
+ return AUBIO_FAIL;
+ }
+
+ freqs = new_fvec(n_bands + 2);
+ step = (end - start) / (n_bands + 1);
+
+ for (m = 0; m < n_bands + 2; m++)
+ {
+ freqs->data[m] = MIN(aubio_meltohz(start + step * m), samplerate/2.);
+ }
+
+ retval = aubio_filterbank_set_triangle_bands (fb, freqs, samplerate);
+
+ /* destroy vector used to store frequency limits */
+ del_fvec (freqs);
+ return retval;
+}
+
+uint_t
+aubio_filterbank_set_mel_coeffs_htk (aubio_filterbank_t * fb, smpl_t samplerate,
+ smpl_t freq_min, smpl_t freq_max)
+{
+ uint_t m, retval;
+ smpl_t start, end, step;
+ fvec_t *freqs;
+ fmat_t *coeffs = aubio_filterbank_get_coeffs(fb);
+ uint_t n_bands = coeffs->height;
+
+ if (freq_max < 0) {
+ AUBIO_ERR("filterbank: set_mel_coeffs freq_max should be > 0\n");
+ return AUBIO_FAIL;
+ } else if (freq_max == 0) {
+ end = aubio_hztomel_htk(samplerate / 2.);
+ } else {
+ end = aubio_hztomel_htk(freq_max);
+ }
+ if (freq_min < 0) {
+ AUBIO_ERR("filterbank: set_mel_coeffs freq_min should be > 0\n");
+ return AUBIO_FAIL;
+ } else {
+ start = aubio_hztomel_htk(freq_min);
+ }
+ if (n_bands <= 0) {
+ AUBIO_ERR("filterbank: set_mel_coeffs n_bands should be > 0\n");
+ return AUBIO_FAIL;
+ }
+
+ freqs = new_fvec (n_bands + 2);
+ step = (end - start) / (n_bands + 1);
+
+ for (m = 0; m < n_bands + 2; m++)
+ {
+ freqs->data[m] = MIN(aubio_meltohz_htk(start + step * m), samplerate/2.);
+ }
+
+ retval = aubio_filterbank_set_triangle_bands (fb, freqs, samplerate);
+
+ /* destroy vector used to store frequency limits */
+ del_fvec (freqs);
+ return retval;
+}
\param fb filterbank object
\param samplerate audio sampling rate
- The filter coefficients are built according to Malcolm Slaney's Auditory
- Toolbox, available online at the following address (see file mfcc.m):
+ The filter coefficients are built to match exactly Malcolm Slaney's Auditory
+ Toolbox implementation (see file mfcc.m). The number of filters should be 40.
+ References
+ ----------
+
+ Malcolm Slaney, *Auditory Toolbox Version 2, Technical Report #1998-010*
https://engineering.purdue.edu/~malcolm/interval/1998-010/
*/
uint_t aubio_filterbank_set_mel_coeffs_slaney (aubio_filterbank_t * fb,
smpl_t samplerate);
+/** Mel filterbank initialization
+
+ \param fb filterbank object
+ \param samplerate audio sampling rate
+ \param fmin start frequency, in Hz
+ \param fmax end frequency, in Hz
+
+ The filterbank will be initialized with bands linearly spaced in the mel
+ scale, from `fmin` to `fmax`.
+
+ References
+ ----------
+
+ Malcolm Slaney, *Auditory Toolbox Version 2, Technical Report #1998-010*
+ https://engineering.purdue.edu/~malcolm/interval/1998-010/
+
+*/
+uint_t aubio_filterbank_set_mel_coeffs(aubio_filterbank_t * fb,
+ smpl_t samplerate, smpl_t fmin, smpl_t fmax);
+
+/** Mel filterbank initialization
+
+ \param fb filterbank object
+ \param samplerate audio sampling rate
+ \param fmin start frequency, in Hz
+ \param fmax end frequency, in Hz
+
+ The bank of filters will be initalized to to cover linearly spaced bands in
+ the Htk mel scale, from `fmin` to `fmax`.
+
+ References
+ ----------
+
+ Douglas O'Shaughnessy (1987). *Speech communication: human and machine*.
+ Addison-Wesley. p. 150. ISBN 978-0-201-16520-3.
+
+ HTK Speech Recognition Toolkit: http://htk.eng.cam.ac.uk/
+
+*/
+uint_t aubio_filterbank_set_mel_coeffs_htk(aubio_filterbank_t * fb,
+ smpl_t samplerate, smpl_t fmin, smpl_t fmax);
+
#ifdef __cplusplus
}
#endif