shithub: aubio

Download patch

ref: 787f1f341dda2329703d7b0759fdb25a214eba01
parent: 7a46bf6cec4e3b9ce9f40ff1db3a98933e016c56
parent: 83d5abff88c1b5cb25a2ae20b110676377e8622b
author: Amaury Hazan <mahmoudax@gmail.org>
date: Wed Sep 12 13:55:48 EDT 2007

merged from laptop, change debug to AUBIO_DBG in filterbank.c

--- a/examples/aubiomfcc.c
+++ b/examples/aubiomfcc.c
@@ -23,7 +23,7 @@
 fvec_t * mfcc_out;
 aubio_mfcc_t * mfcc;
 
-uint_t n_filters = 20;
+uint_t n_filters = 40;
 uint_t n_coefs = 11;
 
 unsigned int pos = 0; /*frames%dspblocksize*/
@@ -52,7 +52,13 @@
      
       //compute mfccs
       aubio_mfcc_do(mfcc, fftgrain, mfcc_out);
-
+      
+      uint_t coef_cnt;
+      for (coef_cnt = 0; coef_cnt < n_coefs; coef_cnt++) {
+          outmsg("%f ",mfcc_out->data[0][coef_cnt]);
+      }
+      outmsg("\n");
+      
       /* end of block loop */
       pos = -1; /* so it will be zero next j loop */
     }
@@ -77,26 +83,24 @@
 //         }
         //outmsg("%f ",mfcc_out->data[0][0]);
         
-        /*for (coef_cnt = 0; coef_cnt < n_coefs; coef_cnt++) {
-          outmsg("%f ",mfcc_out->data[0][coef_cnt]);
-        }
-        outmsg("\n");/*/
+        
       }
 }
 
 int main(int argc, char **argv) {
   // params
-  //uint_t n_filters = 40;
-  //uint_t n_coefs = 15;
-
+  
   examples_common_init(argc,argv);
   smpl_t lowfreq = 133.333f;
   smpl_t highfreq = 44100.f;
   mfcc_out = new_fvec(n_coefs,channels);
   
+  
   //populating the filter
   mfcc = new_aubio_mfcc(buffer_size, samplerate, n_filters, n_coefs , lowfreq, highfreq, channels);
-
+  dump_filterbank(mfcc);
+  
+  
   //process
   examples_common_process(aubio_process,process_print);
   
--- a/examples/plotfb.py
+++ b/examples/plotfb.py
@@ -4,8 +4,14 @@
 import numpy
 import sys
 
+
 filename=sys.argv[1]
 
+doLog=False
+if len(sys.argv)>2: 
+  if sys.argv[2]=='log':
+    doLog=True
+
 mat = pylab.load(filename)
 nmat= numpy.array(mat)
 print numpy.shape(nmat)
@@ -14,7 +20,10 @@
 
 n_filters=numpy.shape(nmat)[0]
 for i in range(n_filters):
-  pylab.plot(nmat[i,:])
+  if doLog==True:
+    pylab.semilogx(nmat[i,:])
+  else:
+    pylab.plot(nmat[i,:]) 
 
 
 pylab.hold(False)
--- a/examples/utils.c
+++ b/examples/utils.c
@@ -39,8 +39,10 @@
 aubio_onsetdetection_type type_onset2 = aubio_onset_complex;
 smpl_t threshold                      = 0.3;
 smpl_t silence                        = -90.;
-uint_t buffer_size                    = 512; //1024;
-uint_t overlap_size                   = 256; //512;
+// uint_t buffer_size                    = 512;
+// uint_t overlap_size                   = 256;
+uint_t buffer_size                    = 1024;
+uint_t overlap_size                   = 512;
 uint_t channels                       = 1;
 uint_t samplerate                     = 44100;
 
--- a/src/filterbank.c
+++ b/src/filterbank.c
@@ -18,9 +18,6 @@
 
 */
 
-/* part of this mfcc implementation were inspired from LibXtract
-   http://libxtract.sourceforge.net/
-*/
 
 #include "aubio_priv.h"
 #include "sample.h"
@@ -54,14 +51,8 @@
   return fb;
 }
 
-aubio_filterbank_t * new_aubio_filterbank_mfcc(uint_t n_filters, uint_t win_s, smpl_t samplerate, smpl_t freq_min, smpl_t freq_max){
+aubio_filterbank_t * new_aubio_filterbank_mfcc(uint_t n_filters, uint_t win_s, uint_t samplerate, smpl_t freq_min, smpl_t freq_max){
   
-  uint_t writelog=1;
-
-  FILE * mlog;
-  if(writelog==1) mlog=fopen("filterbank.txt","w");
-  
-
   smpl_t nyquist = samplerate/2.;
   uint_t style = 1;
   aubio_filterbank_t * fb = new_aubio_filterbank(n_filters, win_s);
@@ -151,14 +142,6 @@
     for(k = next_peak + 1; k < fb->win_s; k++)
       fb->filters[n]->data[0][k]=0.f;
 
-    if(writelog){
-      //dumping filter values
-      smpl_t area_tmp=0.f;
-      for(k = 0; k < fb->win_s; k++){
-        fprintf(mlog,"%f ",fb->filters[n]->data[0][k]);
-      }
-      fprintf(mlog,"\n");
-    }
 
   }
 
@@ -167,12 +150,187 @@
   free(height_norm);
   free(fft_peak);
 
-  if(mlog) fclose(mlog);
 
   return fb;
 
 }
 
+/*
+FB initialization based on Slaney's auditory toolbox
+TODO:
+  *solve memory leak problems while
+  *solve quantization issues when constructing signal:
+    *bug for win_s=512
+    *corrections for win_s=1024 -> why even filters with smaller amplitude
+
+*/
+
+aubio_filterbank_t * new_aubio_filterbank_mfcc2(uint_t n_filters, uint_t win_s, uint_t samplerate, smpl_t freq_min, smpl_t freq_max){
+  
+  aubio_filterbank_t * fb = new_aubio_filterbank(n_filters, win_s);
+  
+  
+  //slaney params
+  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;
+  
+  //buffers for computing filter frequencies
+  fvec_t * freqs=new_fvec( allFilters +2 , 1);
+  
+  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=freqs;
+  fvec_t * upper_freqs=freqs;
+  fvec_t * center_freqs=freqs*/;
+  
+  fvec_t * triangle_heights=new_fvec( allFilters, 1);
+  //lookup table of each bin frequency in hz
+  fvec_t * fft_freqs=new_fvec(win_s, 1);
+
+  uint_t filter_cnt, bin_cnt;
+  
+  //first: filling all the linear filter frequencies
+  for(filter_cnt=0; filter_cnt<linearFilters; filter_cnt++){
+    freqs->data[0][filter_cnt]=lowestFrequency+ filter_cnt*linearSpacing;
+  }
+  smpl_t lastlinearCF=freqs->data[0][filter_cnt-1];
+  
+  //second: 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));
+  }
+  
+  
+  //make fvec->data point directly to freqs arrays
+  lower_freqs->data=freqs->data;
+  center_freqs->data[0]=&(freqs->data[0][1]);
+  upper_freqs->data[0]=&(freqs->data[0][2]);
+
+  
+  //computing triangle heights so that each triangle has unit area
+  for(filter_cnt=0; filter_cnt<allFilters; filter_cnt++){
+    triangle_heights->data[0][filter_cnt]=2./(upper_freqs->data[0][filter_cnt]-lower_freqs->data[0][filter_cnt]);
+  }
+
+  //AUBIO_DBG
+  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++){
+    
+    //TODO: check the formula!
+    
+    fft_freqs->data[0][bin_cnt]= (smpl_t)samplerate* (smpl_t)bin_cnt/ (smpl_t)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
+    AUBIO_DBG("\nfilter %d",filter_cnt);
+
+    AUBIO_DBG("\nzero begin\n");
+    
+    for(bin_cnt=0; bin_cnt<win_s-1; bin_cnt++){
+      //zeroing beigining of array
+      fb->filters[filter_cnt]->data[0][bin_cnt]=0.f;
+      AUBIO_DBG(".");
+      //AUBIO_DBG("%f %f %f\n", fft_freqs->data[0][bin_cnt], fft_freqs->data[0][bin_cnt+1], lower_freqs->data[0][filter_cnt]); 
+      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++;
+    
+    AUBIO_DBG("\npos slope\n");
+    //positive slope
+    for(; bin_cnt<win_s-1; bin_cnt++){
+      AUBIO_DBG(".");
+      fb->filters[filter_cnt]->data[0][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++;
+    
+    
+    //negative slope
+    AUBIO_DBG("\nneg slope\n");   
+    for(; bin_cnt<win_s-1; bin_cnt++){
+      //AUBIO_DBG(".");
+      
+      //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)
+        fb->filters[filter_cnt]->data[0][bin_cnt]=val;
+      else fb->filters[filter_cnt]->data[0][bin_cnt]=0.f;
+      
+      //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++;
+    
+    AUBIO_DBG("\nzero end\n");
+    //zeroing tail
+    for(; bin_cnt<win_s; bin_cnt++)
+      //AUBIO_DBG(".");
+      fb->filters[filter_cnt]->data[0][bin_cnt]=0.f;
+
+  }
+  
+  
+  del_fvec(freqs);
+  //TODO: Check how to do a proper free for the following f_vec
+
+  //del_fvec(lower_freqs);
+  //del_fvec(upper_freqs);
+  //del_fvec(center_freqs);
+  del_fvec(triangle_heights);
+  del_fvec(fft_freqs);
+
+  
+
+  return fb;
+
+}
+
+void aubio_dump_filterbank(aubio_filterbank_t * fb){
+
+  FILE * mlog;
+  mlog=fopen("filterbank.txt","w");
+  
+  int k,n;
+  //dumping filter values
+  //smpl_t area_tmp=0.f;
+  for(n = 0; n < fb->n_filters; n++){
+    for(k = 0; k < fb->win_s; k++){
+      fprintf(mlog,"%f ",fb->filters[n]->data[0][k]);
+    }
+    fprintf(mlog,"\n");
+  }
+  
+  if(mlog) fclose(mlog);
+}
 
 void del_aubio_filterbank(aubio_filterbank_t * fb){
   uint_t filter_cnt;
--- a/src/filterbank.h
+++ b/src/filterbank.h
@@ -45,15 +45,28 @@
 
 /** filterbank initialization for mel filters
 
-  \param nyquist nyquist frequency, i.e. half of the sampling rate
-  \param style libxtract style
-  \param freqmin lowest filter frequency
-  \param freqmax highest filter frequency
+  
+  \param n_filters number of filters
+  \param win_s window size
+  \param samplerate
+  \param freq_min lowest filter frequency
+  \param freq_max highest filter frequency
 
 */
-aubio_filterbank_t * new_aubio_filterbank_mfcc(uint_t n_filters, uint_t win_s, smpl_t samplerate, smpl_t freq_min, smpl_t freq_max);
+aubio_filterbank_t * new_aubio_filterbank_mfcc(uint_t n_filters, uint_t win_s, uint_t samplerate, smpl_t freq_min, smpl_t freq_max);
 
+/** filterbank initialization for mel filters
 
+  \param n_filters number of filters
+  \param win_s window size
+  \param samplerate
+  \param freq_min lowest filter frequency
+  \param freq_max highest filter frequency
+
+*/
+aubio_filterbank_t * new_aubio_filterbank_mfcc_2(uint_t n_filters, uint_t win_s, uint_t samplerate, smpl_t freq_min, smpl_t freq_max);
+
+
 /** destroy filterbank object
 
   \param fb filterbank, as returned by new_aubio_filterbank method
@@ -65,6 +78,11 @@
 
 */
 void aubio_filterbank_do(aubio_filterbank_t * fb, cvec_t * in, fvec_t *out);
+
+/** dump filterbank filter tables in a txt file
+
+*/
+void aubio_dump_filterbank(aubio_filterbank_t * fb);
 
 #ifdef __cplusplus
 }
--- a/src/mfcc.c
+++ b/src/mfcc.c
@@ -59,8 +59,9 @@
   mfcc->lowfreq=lowfreq;
   mfcc->highfreq=highfreq;
 
+  
   /** filterbank allocation */
-  mfcc->fb = new_aubio_filterbank_mfcc(n_filters, mfcc->win_s, samplerate, lowfreq, highfreq);
+  mfcc->fb = new_aubio_filterbank_mfcc2(n_filters, mfcc->win_s, samplerate, lowfreq, highfreq);
 
   /** allocating space for fft object (used for dct) */
   mfcc->fft_dct=new_aubio_mfft(n_filters, 1);
@@ -109,5 +110,11 @@
         *COS(mf->fftgrain_dct->phas[0][i]);
     }
     return;
+}
+
+//a bit a kludge
+void dump_filterbank(aubio_mfcc_t * mf){
+  aubio_dump_filterbank(mf->fb);
+
 }
 
--- a/src/mfcc.h
+++ b/src/mfcc.h
@@ -69,6 +69,13 @@
 */
 void aubio_dct_do(aubio_mfcc_t * mf, fvec_t *in, fvec_t *out);
 
+/** dump filterbank to log file
+
+  \param mf mfcc object as returned by new_aubio_mfcc
+  
+*/
+void dump_filterbank(aubio_mfcc_t * mf);
+
 #ifdef __cplusplus
 }
 #endif
--