#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)
{
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);
//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
- lower_freqs->data[0][filter_cnt]);
}
- //AUBIO_DBG("filter tables frequencies\n");
- //for(filter_cnt=0; filter_cnt<allFilters; filter_cnt++)
- // AUBIO_DBG("filter n. %d %f %f %f %f\n",
- // filter_cnt, lower_freqs->data[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;
}
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 */
}