src/spectral/filterbank_mel.c: move Slaney's specific code to _slaney function
authorPaul Brossier <piem@piem.org>
Thu, 17 Sep 2009 03:54:25 +0000 (05:54 +0200)
committerPaul Brossier <piem@piem.org>
Thu, 17 Sep 2009 03:54:25 +0000 (05:54 +0200)
src/spectral/filterbank_mel.c
src/spectral/filterbank_mel.h
src/spectral/mfcc.c
swig/aubio.i

index 697e900bd5796b0071489bc05123d29de5c6e060..f0f5d2bd4dbad0b943322f5a77680da0a62cbb12 100644 (file)
 #include "mathutils.h"
 
 void
-aubio_filterbank_set_mel_coeffs (aubio_filterbank_t * fb, smpl_t samplerate,
-    smpl_t freq_min, smpl_t freq_max)
+aubio_filterbank_set_mel_coeffs (aubio_filterbank_t * fb, fvec_t * freqs,
+    smpl_t samplerate)
 {
 
   fvec_t *filters = aubio_filterbank_get_coeffs (fb);
   uint_t n_filters = filters->channels, win_s = filters->length;
 
-  /* Malcolm Slaney parameters */
-  smpl_t lowestFrequency = 133.3333;
-  smpl_t linearSpacing = 66.66666666;
-  smpl_t logSpacing = 1.0711703;
-
-  uint_t linearFilters = 13;
-  uint_t logFilters = 27;
-  uint_t allFilters = linearFilters + logFilters;
+  uint_t fn;                    /* filter counter */
+  uint_t bin;                   /* bin counter */
 
-  /* throw a warning if filterbank object fb is too short */
-  if (allFilters > n_filters) {
-    AUBIO_WRN ("not enough Mel filters, got %d but %d needed\n",
-        n_filters, allFilters);
+  /* freqs define the bands of triangular overlapping windows.
+     throw a warning if filterbank object fb is too short. */
+  if (freqs->length - 2 > n_filters) {
+    AUBIO_WRN ("not enough filters, %d allocated but %d requested\n",
+        n_filters, freqs->length - 2);
   }
 
-  /* buffers for computing filter frequencies */
-  fvec_t *freqs = new_fvec (allFilters + 2, 1);
-
   /* convenience reference to lower/center/upper frequency for each triangle */
-  fvec_t *lower_freqs = new_fvec (allFilters, 1);
-  fvec_t *upper_freqs = new_fvec (allFilters, 1);
-  fvec_t *center_freqs = new_fvec (allFilters, 1);
+  fvec_t *lower_freqs = new_fvec (n_filters, 1);
+  fvec_t *upper_freqs = new_fvec (n_filters, 1);
+  fvec_t *center_freqs = new_fvec (n_filters, 1);
 
   /* height of each triangle */
-  fvec_t *triangle_heights = new_fvec (allFilters, 1);
+  fvec_t *triangle_heights = new_fvec (n_filters, 1);
 
   /* lookup table of each bin frequency in hz */
   fvec_t *fft_freqs = new_fvec (win_s, 1);
 
-  uint_t fn;                    /* filter counter */
-  uint_t bin;                   /* bin counter */
-
-  /* first step: filling all the linear filter frequencies */
-  for (fn = 0; fn < linearFilters; fn++) {
-    freqs->data[0][fn] = lowestFrequency + fn * linearSpacing;
-  }
-  smpl_t lastlinearCF = freqs->data[0][fn - 1];
-
-  /* second step: filling all the log filter frequencies */
-  for (fn = 0; fn < logFilters + 2; fn++) {
-    freqs->data[0][fn + linearFilters] =
-        lastlinearCF * (POW (logSpacing, fn + 1));
-  }
-
   /* fill up the lower/center/upper */
-  for (fn = 0; fn < allFilters; fn++) {
+  for (fn = 0; fn < n_filters; fn++) {
     lower_freqs->data[0][fn] = freqs->data[0][fn];
     center_freqs->data[0][fn] = freqs->data[0][fn + 1];
     upper_freqs->data[0][fn] = freqs->data[0][fn + 2];
   }
 
   /* compute triangle heights so that each triangle has unit area */
-  for (fn = 0; fn < allFilters; fn++) {
+  for (fn = 0; fn < n_filters; fn++) {
     triangle_heights->data[0][fn] =
         2. / (upper_freqs->data[0][fn] - lower_freqs->data[0][fn]);
   }
@@ -143,7 +120,6 @@ aubio_filterbank_set_mel_coeffs (aubio_filterbank_t * fb, smpl_t samplerate,
   }
 
   /* destroy temporarly allocated vectors */
-  del_fvec (freqs);
   del_fvec (lower_freqs);
   del_fvec (upper_freqs);
   del_fvec (center_freqs);
@@ -152,3 +128,42 @@ aubio_filterbank_set_mel_coeffs (aubio_filterbank_t * fb, smpl_t samplerate,
   del_fvec (fft_freqs);
 
 }
+
+void
+aubio_filterbank_set_mel_coeffs_slaney (aubio_filterbank_t * fb,
+    smpl_t samplerate)
+{
+  /* Malcolm Slaney parameters */
+  smpl_t lowestFrequency = 133.3333;
+  smpl_t linearSpacing = 66.66666666;
+  smpl_t logSpacing = 1.0711703;
+
+  uint_t linearFilters = 13;
+  uint_t logFilters = 27;
+  uint_t n_filters = linearFilters + logFilters;
+
+  uint_t fn;                    /* filter counter */
+  uint_t bin;                   /* bin counter */
+
+  /* buffers to compute filter frequencies */
+  fvec_t *freqs = new_fvec (n_filters + 2, 1);
+
+  /* first step: fill all the linear filter frequencies */
+  for (fn = 0; fn < linearFilters; fn++) {
+    freqs->data[0][fn] = lowestFrequency + fn * linearSpacing;
+  }
+  smpl_t lastlinearCF = freqs->data[0][fn - 1];
+
+  /* second step: fill all the log filter frequencies */
+  for (fn = 0; fn < logFilters + 2; fn++) {
+    freqs->data[0][fn + linearFilters] =
+        lastlinearCF * (POW (logSpacing, fn + 1));
+  }
+
+  /* now compute the actual coefficients */
+  aubio_filterbank_set_mel_coeffs (fb, freqs, samplerate);
+
+  /* destroy vector used to store frequency limits */
+  del_fvec (freqs);
+
+}
index 8672e243ef1db84396038e9be4672b434fbea309..a886ba205d297876577bc27654d5e0ebb3dadc39 100644 (file)
@@ -43,15 +43,27 @@ extern "C"
 
 /** filterbank initialization for mel filters
 
-  \param n_filters number of filters
-  \param win_s window size
+  \param fb filterbank object
+  \param freqs arbitrary array of boundary frequencies
   \param samplerate audio sampling rate
-  \param freq_min lowest filter frequency
-  \param freq_max highest filter frequency
+
+  This function computes the coefficients of the filterbank based on the
+  boundaries found in freqs, in Hz, and using triangular overlapping windows.
 
 */
 void aubio_filterbank_set_mel_coeffs (aubio_filterbank_t * fb,
-    smpl_t samplerate, smpl_t freq_min, smpl_t freq_max);
+    fvec_t * freqs, smpl_t samplerate);
+
+/** filterbank initialization for Mel filters using Slaney's coefficients
+
+  \param fb filterbank object
+  \param samplerate audio sampling rate
+
+  This function fills the filterbank coefficients according to Malcolm Slaney.
+
+*/
+void aubio_filterbank_set_mel_coeffs_slaney (aubio_filterbank_t * fb,
+    smpl_t samplerate);
 
 #ifdef __cplusplus
 }
index 5d9e6ae8c6b83d269fdebfca9c5e7d56bdea3bd0..8d83e705e777afaf8ecdad33dce360321bfb2511 100644 (file)
@@ -62,7 +62,7 @@ aubio_mfcc_t * new_aubio_mfcc (uint_t win_s, uint_t samplerate, uint_t n_filters
   
   /** filterbank allocation */
   mfcc->fb = new_aubio_filterbank(n_filters, mfcc->win_s);
-  aubio_filterbank_set_mel_coeffs(mfcc->fb, samplerate, lowfreq, highfreq);
+  aubio_filterbank_set_mel_coeffs_slaney(mfcc->fb, samplerate);
 
   /** allocating space for fft object (used for dct) */
   mfcc->fft_dct=new_aubio_fft(n_filters, 1);
index 1fe613ae437275c1b510d0ba82b9205c60e77e8a..cdc0832a9bc87060114a9928f13663f3a3c9d7be 100644 (file)
@@ -162,7 +162,8 @@ smpl_t aubio_spectral_centroid(cvec_t * spectrum, smpl_t samplerate);
 
 /* filterbank */
 aubio_filterbank_t * new_aubio_filterbank(uint_t win_s, uint_t channels);
-void aubio_filterbank_set_mel_coeffs(aubio_filterbank_t *fb, uint_t samplerate, smpl_t freq_min, smpl_t freq_max);
+void aubio_filterbank_set_mel_coeffs(aubio_filterbank_t *fb, fvec_t *freqs, uint_t samplerate);
+void aubio_filterbank_set_mel_coeffs_slaney(aubio_filterbank_t *fb, uint_t samplerate);
 void del_aubio_filterbank(aubio_filterbank_t * fb);
 void aubio_filterbank_do(aubio_filterbank_t * fb, cvec_t * in, fvec_t *out);
 fvec_t * aubio_filterbank_get_coeffs(aubio_filterbank_t * fb);