From b50760734e6e06bb594067fd696f9e1a544b6e18 Mon Sep 17 00:00:00 2001 From: Paul Brossier Date: Thu, 17 Sep 2009 04:02:04 +0200 Subject: [PATCH] src/spectral/filterbank_mel.c: correct computation of coefficients, use float samplerate, use POW, make sure we don't try to set unexisting filters --- src/spectral/filterbank_mel.c | 69 ++++++++++++++++------------------- src/spectral/filterbank_mel.h | 4 +- 2 files changed, 33 insertions(+), 40 deletions(-) diff --git a/src/spectral/filterbank_mel.c b/src/spectral/filterbank_mel.c index 01b6c4db..5a6ef166 100644 --- a/src/spectral/filterbank_mel.c +++ b/src/spectral/filterbank_mel.c @@ -26,7 +26,7 @@ #include "mathutils.h" void -aubio_filterbank_set_mel_coeffs (aubio_filterbank_t * fb, uint_t samplerate, +aubio_filterbank_set_mel_coeffs (aubio_filterbank_t * fb, smpl_t samplerate, smpl_t freq_min, smpl_t freq_max) { @@ -42,6 +42,11 @@ aubio_filterbank_set_mel_coeffs (aubio_filterbank_t * fb, uint_t samplerate, uint_t logFilters = 27; uint_t allFilters = linearFilters + logFilters; + if (allFilters > n_filters) { + AUBIO_WRN("not enough Mel filters, got %d but %d needed\n", + n_filters, allFilters); + } + //buffers for computing filter frequencies fvec_t *freqs = new_fvec (allFilters + 2, 1); @@ -64,7 +69,7 @@ aubio_filterbank_set_mel_coeffs (aubio_filterbank_t * fb, uint_t samplerate, //second step: filling all the log filter frequencies for (filter_cnt = 0; filter_cnt < logFilters + 2; filter_cnt++) { freqs->data[0][filter_cnt + linearFilters] = - lastlinearCF * (pow (logSpacing, filter_cnt + 1)); + lastlinearCF * (POW(logSpacing, filter_cnt + 1)); } //Option 1. copying interesting values to lower_freqs, center_freqs and upper freqs arrays @@ -83,30 +88,20 @@ aubio_filterbank_set_mel_coeffs (aubio_filterbank_t * fb, uint_t samplerate, - lower_freqs->data[0][filter_cnt]); } - //AUBIO_DBG("filter tables frequencies\n"); - //for(filter_cnt=0; filter_cntdata[0][filter_cnt], - // center_freqs->data[0][filter_cnt], upper_freqs->data[0][filter_cnt], - // triangle_heights->data[0][filter_cnt]); - //filling the fft_freqs lookup table, which assigns the frequency in hz to each bin for (bin_cnt = 0; bin_cnt < win_s; bin_cnt++) { fft_freqs->data[0][bin_cnt] = aubio_bintofreq (bin_cnt, samplerate, win_s); } - //building each filter table - for (filter_cnt = 0; filter_cnt < allFilters; filter_cnt++) { - //TODO:check special case : lower freq =0 - //calculating rise increment in mag/Hz - smpl_t riseInc = - triangle_heights->data[0][filter_cnt] / - (center_freqs->data[0][filter_cnt] - lower_freqs->data[0][filter_cnt]); + /* zeroing begining of filter */ + fvec_zeros(filters); + + /* building each filter table */ + for (filter_cnt = 0; filter_cnt < n_filters; filter_cnt++) { - //zeroing begining of filter + /* skip first elements */ for (bin_cnt = 0; bin_cnt < win_s - 1; bin_cnt++) { - filters->data[filter_cnt][bin_cnt] = 0.0; if (fft_freqs->data[0][bin_cnt] <= lower_freqs->data[0][filter_cnt] && fft_freqs->data[0][bin_cnt + 1] > lower_freqs->data[0][filter_cnt]) { break; @@ -114,39 +109,37 @@ aubio_filterbank_set_mel_coeffs (aubio_filterbank_t * fb, uint_t samplerate, } bin_cnt++; - //positive slope + /* compute positive slope step size */ + smpl_t riseInc = + triangle_heights->data[0][filter_cnt] / + (center_freqs->data[0][filter_cnt] - lower_freqs->data[0][filter_cnt]); + + /* compute coefficients in positive slope */ for (; bin_cnt < win_s - 1; bin_cnt++) { filters->data[filter_cnt][bin_cnt] = (fft_freqs->data[0][bin_cnt] - lower_freqs->data[0][filter_cnt]) * riseInc; - //if(fft_freqs->data[0][bin_cnt]<= center_freqs->data[0][filter_cnt] && fft_freqs->data[0][bin_cnt+1]> center_freqs->data[0][filter_cnt]) + if (fft_freqs->data[0][bin_cnt + 1] > center_freqs->data[0][filter_cnt]) break; } - //bin_cnt++; + bin_cnt++; + + /* compute negative slope step size */ + smpl_t downInc = + triangle_heights->data[0][filter_cnt] / + (upper_freqs->data[0][filter_cnt] - center_freqs->data[0][filter_cnt]); - //negative slope + /* compute coefficents in negative slope */ for (; bin_cnt < win_s - 1; bin_cnt++) { + filters->data[filter_cnt][bin_cnt] += + (upper_freqs->data[0][filter_cnt] - + fft_freqs->data[0][bin_cnt]) * downInc; - //checking whether last value is less than 0... - smpl_t val = - triangle_heights->data[0][filter_cnt] - (fft_freqs->data[0][bin_cnt] - - center_freqs->data[0][filter_cnt]) * riseInc; - if (val >= 0) - filters->data[filter_cnt][bin_cnt] = val; - else - filters->data[filter_cnt][bin_cnt] = 0.0; - - //if(fft_freqs->data[0][bin_cnt]<= upper_freqs->data[0][bin_cnt] && fft_freqs->data[0][bin_cnt+1]> upper_freqs->data[0][filter_cnt]) - //TODO: CHECK whether bugfix correct if (fft_freqs->data[0][bin_cnt + 1] > upper_freqs->data[0][filter_cnt]) break; } - //bin_cnt++; - - //zeroing tail - for (; bin_cnt < win_s; bin_cnt++) - filters->data[filter_cnt][bin_cnt] = 0.f; + /* nothing else to do */ } diff --git a/src/spectral/filterbank_mel.h b/src/spectral/filterbank_mel.h index e75f7332..8672e243 100644 --- a/src/spectral/filterbank_mel.h +++ b/src/spectral/filterbank_mel.h @@ -45,13 +45,13 @@ extern "C" \param n_filters number of filters \param win_s window size - \param samplerate + \param samplerate audio sampling rate \param freq_min lowest filter frequency \param freq_max highest filter frequency */ void aubio_filterbank_set_mel_coeffs (aubio_filterbank_t * fb, - uint_t samplerate, smpl_t freq_min, smpl_t freq_max); + smpl_t samplerate, smpl_t freq_min, smpl_t freq_max); #ifdef __cplusplus } -- 2.26.2