src/spectral/filterbank_mel.c: correct computation of coefficients, use float sampler...
authorPaul Brossier <piem@piem.org>
Thu, 17 Sep 2009 02:02:04 +0000 (04:02 +0200)
committerPaul Brossier <piem@piem.org>
Thu, 17 Sep 2009 02:02:04 +0000 (04:02 +0200)
src/spectral/filterbank_mel.c
src/spectral/filterbank_mel.h

index 01b6c4db5f5fb343c550c64f7cd443cb502831e2..5a6ef166e80a32aebd2092551dde33aa201914f9 100644 (file)
@@ -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_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;
@@ -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 */
 
   }
 
index e75f733257c1dc1cb0725125d9f32b0e372ec7b0..8672e243ef1db84396038e9be4672b434fbea309 100644 (file)
@@ -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
 }