From 1e37adec4dc504c99185e178b4a16934e53b6c55 Mon Sep 17 00:00:00 2001 From: Paul Brossier Date: Thu, 17 Sep 2009 05:54:25 +0200 Subject: [PATCH] src/spectral/filterbank_mel.c: move Slaney's specific code to _slaney function --- src/spectral/filterbank_mel.c | 93 ++++++++++++++++++++--------------- src/spectral/filterbank_mel.h | 22 +++++++-- src/spectral/mfcc.c | 2 +- swig/aubio.i | 3 +- 4 files changed, 74 insertions(+), 46 deletions(-) diff --git a/src/spectral/filterbank_mel.c b/src/spectral/filterbank_mel.c index 697e900b..f0f5d2bd 100644 --- a/src/spectral/filterbank_mel.c +++ b/src/spectral/filterbank_mel.c @@ -26,66 +26,43 @@ #include "mathutils.h" void -aubio_filterbank_set_mel_coeffs (aubio_filterbank_t * fb, smpl_t samplerate, - smpl_t freq_min, smpl_t freq_max) +aubio_filterbank_set_mel_coeffs (aubio_filterbank_t * fb, fvec_t * freqs, + smpl_t samplerate) { fvec_t *filters = aubio_filterbank_get_coeffs (fb); uint_t n_filters = filters->channels, win_s = filters->length; - /* Malcolm Slaney parameters */ - smpl_t lowestFrequency = 133.3333; - smpl_t linearSpacing = 66.66666666; - smpl_t logSpacing = 1.0711703; - - uint_t linearFilters = 13; - uint_t logFilters = 27; - uint_t allFilters = linearFilters + logFilters; + uint_t fn; /* filter counter */ + uint_t bin; /* bin counter */ - /* throw a warning if filterbank object fb is too short */ - if (allFilters > n_filters) { - AUBIO_WRN ("not enough Mel filters, got %d but %d needed\n", - n_filters, allFilters); + /* freqs define the bands of triangular overlapping windows. + throw a warning if filterbank object fb is too short. */ + if (freqs->length - 2 > n_filters) { + AUBIO_WRN ("not enough filters, %d allocated but %d requested\n", + n_filters, freqs->length - 2); } - /* buffers for computing filter frequencies */ - fvec_t *freqs = new_fvec (allFilters + 2, 1); - /* convenience reference to lower/center/upper frequency for each triangle */ - fvec_t *lower_freqs = new_fvec (allFilters, 1); - fvec_t *upper_freqs = new_fvec (allFilters, 1); - fvec_t *center_freqs = new_fvec (allFilters, 1); + fvec_t *lower_freqs = new_fvec (n_filters, 1); + fvec_t *upper_freqs = new_fvec (n_filters, 1); + fvec_t *center_freqs = new_fvec (n_filters, 1); /* height of each triangle */ - fvec_t *triangle_heights = new_fvec (allFilters, 1); + fvec_t *triangle_heights = new_fvec (n_filters, 1); /* lookup table of each bin frequency in hz */ fvec_t *fft_freqs = new_fvec (win_s, 1); - uint_t fn; /* filter counter */ - uint_t bin; /* bin counter */ - - /* first step: filling all the linear filter frequencies */ - for (fn = 0; fn < linearFilters; fn++) { - freqs->data[0][fn] = lowestFrequency + fn * linearSpacing; - } - smpl_t lastlinearCF = freqs->data[0][fn - 1]; - - /* second step: filling all the log filter frequencies */ - for (fn = 0; fn < logFilters + 2; fn++) { - freqs->data[0][fn + linearFilters] = - lastlinearCF * (POW (logSpacing, fn + 1)); - } - /* fill up the lower/center/upper */ - for (fn = 0; fn < allFilters; fn++) { + for (fn = 0; fn < n_filters; fn++) { lower_freqs->data[0][fn] = freqs->data[0][fn]; center_freqs->data[0][fn] = freqs->data[0][fn + 1]; upper_freqs->data[0][fn] = freqs->data[0][fn + 2]; } /* compute triangle heights so that each triangle has unit area */ - for (fn = 0; fn < allFilters; fn++) { + for (fn = 0; fn < n_filters; fn++) { triangle_heights->data[0][fn] = 2. / (upper_freqs->data[0][fn] - lower_freqs->data[0][fn]); } @@ -143,7 +120,6 @@ aubio_filterbank_set_mel_coeffs (aubio_filterbank_t * fb, smpl_t samplerate, } /* destroy temporarly allocated vectors */ - del_fvec (freqs); del_fvec (lower_freqs); del_fvec (upper_freqs); del_fvec (center_freqs); @@ -152,3 +128,42 @@ aubio_filterbank_set_mel_coeffs (aubio_filterbank_t * fb, smpl_t samplerate, del_fvec (fft_freqs); } + +void +aubio_filterbank_set_mel_coeffs_slaney (aubio_filterbank_t * fb, + smpl_t samplerate) +{ + /* Malcolm Slaney parameters */ + smpl_t lowestFrequency = 133.3333; + smpl_t linearSpacing = 66.66666666; + smpl_t logSpacing = 1.0711703; + + uint_t linearFilters = 13; + uint_t logFilters = 27; + uint_t n_filters = linearFilters + logFilters; + + uint_t fn; /* filter counter */ + uint_t bin; /* bin counter */ + + /* buffers to compute filter frequencies */ + fvec_t *freqs = new_fvec (n_filters + 2, 1); + + /* first step: fill all the linear filter frequencies */ + for (fn = 0; fn < linearFilters; fn++) { + freqs->data[0][fn] = lowestFrequency + fn * linearSpacing; + } + smpl_t lastlinearCF = freqs->data[0][fn - 1]; + + /* second step: fill all the log filter frequencies */ + for (fn = 0; fn < logFilters + 2; fn++) { + freqs->data[0][fn + linearFilters] = + lastlinearCF * (POW (logSpacing, fn + 1)); + } + + /* now compute the actual coefficients */ + aubio_filterbank_set_mel_coeffs (fb, freqs, samplerate); + + /* destroy vector used to store frequency limits */ + del_fvec (freqs); + +} diff --git a/src/spectral/filterbank_mel.h b/src/spectral/filterbank_mel.h index 8672e243..a886ba20 100644 --- a/src/spectral/filterbank_mel.h +++ b/src/spectral/filterbank_mel.h @@ -43,15 +43,27 @@ extern "C" /** filterbank initialization for mel filters - \param n_filters number of filters - \param win_s window size + \param fb filterbank object + \param freqs arbitrary array of boundary frequencies \param samplerate audio sampling rate - \param freq_min lowest filter frequency - \param freq_max highest filter frequency + + This function computes the coefficients of the filterbank based on the + boundaries found in freqs, in Hz, and using triangular overlapping windows. */ void aubio_filterbank_set_mel_coeffs (aubio_filterbank_t * fb, - smpl_t samplerate, smpl_t freq_min, smpl_t freq_max); + fvec_t * freqs, smpl_t samplerate); + +/** filterbank initialization for Mel filters using Slaney's coefficients + + \param fb filterbank object + \param samplerate audio sampling rate + + This function fills the filterbank coefficients according to Malcolm Slaney. + +*/ +void aubio_filterbank_set_mel_coeffs_slaney (aubio_filterbank_t * fb, + smpl_t samplerate); #ifdef __cplusplus } diff --git a/src/spectral/mfcc.c b/src/spectral/mfcc.c index 5d9e6ae8..8d83e705 100644 --- a/src/spectral/mfcc.c +++ b/src/spectral/mfcc.c @@ -62,7 +62,7 @@ aubio_mfcc_t * new_aubio_mfcc (uint_t win_s, uint_t samplerate, uint_t n_filters /** filterbank allocation */ mfcc->fb = new_aubio_filterbank(n_filters, mfcc->win_s); - aubio_filterbank_set_mel_coeffs(mfcc->fb, samplerate, lowfreq, highfreq); + aubio_filterbank_set_mel_coeffs_slaney(mfcc->fb, samplerate); /** allocating space for fft object (used for dct) */ mfcc->fft_dct=new_aubio_fft(n_filters, 1); diff --git a/swig/aubio.i b/swig/aubio.i index 1fe613ae..cdc0832a 100644 --- a/swig/aubio.i +++ b/swig/aubio.i @@ -162,7 +162,8 @@ smpl_t aubio_spectral_centroid(cvec_t * spectrum, smpl_t samplerate); /* filterbank */ aubio_filterbank_t * new_aubio_filterbank(uint_t win_s, uint_t channels); -void aubio_filterbank_set_mel_coeffs(aubio_filterbank_t *fb, uint_t samplerate, smpl_t freq_min, smpl_t freq_max); +void aubio_filterbank_set_mel_coeffs(aubio_filterbank_t *fb, fvec_t *freqs, uint_t samplerate); +void aubio_filterbank_set_mel_coeffs_slaney(aubio_filterbank_t *fb, uint_t samplerate); void del_aubio_filterbank(aubio_filterbank_t * fb); void aubio_filterbank_do(aubio_filterbank_t * fb, cvec_t * in, fvec_t *out); fvec_t * aubio_filterbank_get_coeffs(aubio_filterbank_t * fb); -- 2.26.2