ref: 3c18f9ee1f7276f0557e2f2ca1255f9955a1268e
parent: 9a122641d3ce463227354550416537a5c95ece1d
author: Paul Brossier <piem@piem.org>
date: Wed Oct 7 19:32:42 EDT 2009
src/spectral/filterbank_mel.{c,h}: rename _set_mel_coeffs to _set_triangle_bands, add some warnings, setters return uint_t,
--- a/src/spectral/filterbank_mel.c
+++ b/src/spectral/filterbank_mel.c
@@ -25,9 +25,9 @@
#include "spectral/filterbank.h"
#include "mathutils.h"
-void
-aubio_filterbank_set_mel_coeffs (aubio_filterbank_t * fb, fvec_t * freqs,
- smpl_t samplerate)
+uint_t
+aubio_filterbank_set_triangle_bands (aubio_filterbank_t * fb,
+ smpl_t samplerate, fvec_t * freqs)
{
fvec_t *filters = aubio_filterbank_get_coeffs (fb);
@@ -43,6 +43,16 @@
n_filters, freqs->length - 2);
}
+ if (freqs->length - 2 < n_filters) {
+ AUBIO_WRN ("too many filters, %d allocated but %d requested\n",
+ n_filters, freqs->length - 2);
+ }
+
+ if (freqs->data[0][freqs->length - 1] > samplerate / 2) {
+ AUBIO_WRN ("Nyquist frequency is %fHz, but highest frequency band ends at \
+%fHz\n", samplerate / 2, freqs->data[0][freqs->length - 1]);
+ }
+
/* convenience reference to lower/center/upper frequency for each triangle */
fvec_t *lower_freqs = new_fvec (n_filters, 1);
fvec_t *upper_freqs = new_fvec (n_filters, 1);
@@ -69,12 +79,24 @@
/* fill fft_freqs lookup table, which assigns the frequency in hz to each bin */
for (bin = 0; bin < win_s; bin++) {
- fft_freqs->data[0][bin] = aubio_bintofreq (bin, samplerate, (win_s - 1) * 2);
+ fft_freqs->data[0][bin] =
+ aubio_bintofreq (bin, samplerate, (win_s - 1) * 2);
}
/* zeroing of all filters */
fvec_zeros (filters);
+ if (fft_freqs->data[0][1] >= lower_freqs->data[0][0]) {
+ /* - 1 to make sure we don't miss the smallest power of two */
+ uint_t min_win_s =
+ (uint_t) FLOOR (samplerate / lower_freqs->data[0][0]) - 1;
+ AUBIO_WRN ("Lowest frequency bin (%.2fHz) is higher than lowest frequency \
+band (%.2f-%.2fHz). Consider increasing the window size from %d to %d.\n",
+ fft_freqs->data[0][1], lower_freqs->data[0][0],
+ upper_freqs->data[0][0], (win_s - 1) * 2,
+ aubio_next_power_of_two (min_win_s));
+ }
+
/* building each filter table */
for (fn = 0; fn < n_filters; fn++) {
@@ -82,10 +104,10 @@
for (bin = 0; bin < win_s - 1; bin++) {
if (fft_freqs->data[0][bin] <= lower_freqs->data[0][fn] &&
fft_freqs->data[0][bin + 1] > lower_freqs->data[0][fn]) {
+ bin++;
break;
}
}
- bin++;
/* compute positive slope step size */
smpl_t riseInc =
@@ -97,10 +119,11 @@
filters->data[fn][bin] =
(fft_freqs->data[0][bin] - lower_freqs->data[0][fn]) * riseInc;
- if (fft_freqs->data[0][bin + 1] > center_freqs->data[0][fn])
+ if (fft_freqs->data[0][bin + 1] >= center_freqs->data[0][fn]) {
+ bin++;
break;
+ }
}
- bin++;
/* compute negative slope step size */
smpl_t downInc =
@@ -112,7 +135,11 @@
filters->data[fn][bin] +=
(upper_freqs->data[0][fn] - fft_freqs->data[0][bin]) * downInc;
- if (fft_freqs->data[0][bin + 1] > upper_freqs->data[0][fn])
+ if (filters->data[fn][bin] < 0.) {
+ filters->data[fn][bin] = 0.;
+ }
+
+ if (fft_freqs->data[0][bin + 1] >= upper_freqs->data[0][fn])
break;
}
/* nothing else to do */
@@ -127,12 +154,15 @@
del_fvec (triangle_heights);
del_fvec (fft_freqs);
+ return 0;
}
-void
+uint_t
aubio_filterbank_set_mel_coeffs_slaney (aubio_filterbank_t * fb,
smpl_t samplerate)
{
+ uint_t retval;
+
/* Malcolm Slaney parameters */
smpl_t lowestFrequency = 133.3333;
smpl_t linearSpacing = 66.66666666;
@@ -160,9 +190,10 @@
}
/* now compute the actual coefficients */
- aubio_filterbank_set_mel_coeffs (fb, freqs, samplerate);
+ retval = aubio_filterbank_set_triangle_bands (fb, samplerate, freqs);
/* destroy vector used to store frequency limits */
del_fvec (freqs);
+ return retval;
}
--- a/src/spectral/filterbank_mel.h
+++ b/src/spectral/filterbank_mel.h
@@ -39,7 +39,7 @@
{
#endif
-/** filterbank initialization for mel filters
+/** filterbank initialization with triangular and overlapping bands
\param fb filterbank object
\param freqs arbitrary array of boundary frequencies
@@ -46,11 +46,11 @@
\param samplerate audio sampling rate
This function computes the coefficients of the filterbank based on the
- boundaries found in freqs, in Hz, and using triangular overlapping windows.
+ boundaries found in freqs, in Hz, and using triangular overlapping bands.
*/
-void aubio_filterbank_set_mel_coeffs (aubio_filterbank_t * fb,
- fvec_t * freqs, smpl_t samplerate);
+uint_t aubio_filterbank_set_triangle_bands (aubio_filterbank_t * fb,
+ smpl_t samplerate, fvec_t * freqs);
/** filterbank initialization for Mel filters using Slaney's coefficients
@@ -60,7 +60,7 @@
This function fills the filterbank coefficients according to Malcolm Slaney.
*/
-void aubio_filterbank_set_mel_coeffs_slaney (aubio_filterbank_t * fb,
+uint_t aubio_filterbank_set_mel_coeffs_slaney (aubio_filterbank_t * fb,
smpl_t samplerate);
#ifdef __cplusplus