shithub: aubio

Download patch

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