merged from piem, corrected mffcs coefs/filter number
authorAmaury Hazan <mahmoudax@gmail.org>
Mon, 10 Sep 2007 17:29:32 +0000 (19:29 +0200)
committerAmaury Hazan <mahmoudax@gmail.org>
Mon, 10 Sep 2007 17:29:32 +0000 (19:29 +0200)
added some scripts to visualize filterbank and mfccs

1  2 
examples/aubiomfcc.c
examples/plotfb.py
examples/plotmat.py
examples/utils.c
src/filterbank.c
src/mfcc.c
src/mfcc.h

index df4dd2a4523c39169540d7ff6a7984d771ccb4ee,9df59e34c58b96d33a4d231a28ee8b5d0de6ad78..189150b94d991b12bf52128735842c966092f336
  
  #include "utils.h"
  
+ /* mfcc objects */
+ fvec_t * mfcc_out;
+ aubio_mfcc_t * mfcc;
++uint_t n_filters = 20;
++uint_t n_coefs = 11;
++
  unsigned int pos = 0; /*frames%dspblocksize*/
  uint_t usepitch = 0;
  
@@@ -72,32 -64,32 +67,35 @@@ void process_print (void) 
           write extracted mfccs
        */
        
 -      uint_t filter_cnt;
++      uint_t coef_cnt;
        if (output_filename == NULL) {
--        if(frames >= 4) {
-           outmsg("%f\n",(frames-4)*overlap_size/(float)samplerate);
 -          outmsg("%f\t",(frames-4)*overlap_size/(float)samplerate);
--        } else if (frames < 4) {
-           outmsg("%f\n",0.);
 -          outmsg("%f\t",0.);
 -        }
 -        outmsg("%f",mfcc_out->data[0][0]);
 -        for (filter_cnt = 1; filter_cnt < mfcc_out->length; filter_cnt++) {
 -          outmsg(",%f",mfcc_out->data[0][filter_cnt]);
++//         if(frames >= 4) {
++//           outmsg("%f\t",(frames-4)*overlap_size/(float)samplerate);
++//         } 
++//         else if (frames < 4) {
++//           outmsg("%f\t",0.);
++//         }
++        //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");
++        outmsg("\n");/*/
        }
  }
  
  int main(int argc, char **argv) {
-   examples_common_init(argc,argv);
-   
-   //allocate and initialize mel filter bank
-   
-   //allocating global mf (in utils.c)
-   uint_t banksize = (uint) ( sizeof(aubio_mel_filter));
-   mf = (aubio_mel_filter *)getbytes(banksize);
+   // params
 -  uint_t n_filters = 11;
++  //uint_t n_filters = 40;
++  //uint_t n_coefs = 15;
 +
-   mf->n_filters = 20;
-   mf->filters = (smpl_t **)getbytes(mf->n_filters * sizeof(smpl_t *));
-   for(n = 0; n < mf->n_filters; n++)
-     mf->filters[n] = (smpl_t *)getbytes((buffer_size/2+1) * sizeof(smpl_t));
+   examples_common_init(argc,argv);
 -  smpl_t lowfreq = 0.;
 -  smpl_t highfreq = samplerate;
 -  mfcc_out = new_fvec(n_filters,channels);
++  smpl_t lowfreq = 133.333f;
++  smpl_t highfreq = 44100.f;
++  mfcc_out = new_fvec(n_coefs,channels);
    
    //populating the filter
-   aubio_mfcc_init(buffer_size, nyquist, XTRACT_EQUAL_GAIN, lowfreq, highfreq, mf->n_filters, mf->filters);
 -  mfcc = new_aubio_mfcc(buffer_size, samplerate, n_filters, lowfreq, highfreq,
 -      channels);
++  mfcc = new_aubio_mfcc(buffer_size, samplerate, n_filters, n_coefs , lowfreq, highfreq, channels);
  
    //process
    examples_common_process(aubio_process,process_print);
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..a715dda732e180293ddc282d9be99aaa9165d64c
new file mode 100755 (executable)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,21 @@@
++#!/usr/bin/env python
++
++import pylab
++import numpy
++import sys
++
++filename=sys.argv[1]
++
++mat = pylab.load(filename)
++nmat= numpy.array(mat)
++print numpy.shape(nmat)
++
++pylab.hold(True)
++
++n_filters=numpy.shape(nmat)[0]
++for i in range(n_filters):
++  pylab.plot(nmat[i,:])
++
++
++pylab.hold(False)
++pylab.show()
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f88f5e830dc91d0ce65c358d00f2d96248fdfcdb
new file mode 100755 (executable)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,18 @@@
++#!/usr/bin/env python
++
++import pylab
++import numpy
++import sys
++
++filename=sys.argv[1]
++
++mat=pylab.load(filename)
++nmat=numpy.array(mat).T
++print numpy.shape(nmat)
++
++
++pylab.matshow(nmat, cmap=pylab.cm.gray, aspect='auto')
++#pylab.imshow(nmat, cmap=pylab.cm.gray, aspect='auto', interpolation=False)
++#pylab.contour(nmat, cmap=pylab.cm.gray, aspect='auto')
++
++pylab.show()
index b0b02e75f80e9f2c55ed7459eb9c4449b7c9f6a0,0445917c9c4aef729d0e68475906df2296659a53..51a6da6a8324fada6983c1b71dd2c553965d7b13
@@@ -60,21 -60,20 +60,6 @@@ fvec_t *onset2
  int isonset = 0;
  aubio_pickpeak_t * parms;
  
--/* mfcc objects */
--//parameters
--uint_t n_filters=20;
- uint_t nyquist= samplerate / 2.; 
--smpl_t lowfreq=80.f;
--smpl_t highfreq=18000.f;
--// filterbank object
- aubio_mel_filter * mf;
 -aubio_filterbank_t * mf;
--
--// DCT mfft and result storage
- aubio_mfft * fft_dct;
 -aubio_mfft_t * fft_dct;
--cvec_t * fftgrain_dct;
- smpl_t mfcc_outbuf[11];
 -smpl_t * mfcc_outbuf[11];
--
--
  /* pitch objects */
  smpl_t pitch               = 0.;
  aubio_pitchdetection_t * pitchdet;
@@@ -314,9 -313,9 +299,7 @@@ void examples_common_init(int argc,cha
    obuf      = new_fvec(overlap_size, channels);
    fftgrain  = new_cvec(buffer_size, channels);
  
--  //init for mfcc process
--  fftgrain_dct= new_cvec(n_filters, channels);
--
++  
    if (usepitch) {
      pitchdet = new_aubio_pitchdetection(buffer_size*4, 
          overlap_size, channels, samplerate, type_pitch, mode_pitch);
    /* phase vocoder */
    pv = new_aubio_pvoc(buffer_size, overlap_size, channels);
    
--  // dct phase vocoder
--  //TODO: check size
--  fft_dct = new_aubio_mfft(n_filters, channels);
--
    /* onsets */
    parms = new_aubio_peakpicker(threshold);
    o = new_aubio_onsetdetection(type_onset,buffer_size,channels);
@@@ -368,10 -367,10 +347,6 @@@ void examples_common_del(void)
    del_fvec(onset);
    del_fvec(woodblock);
    
--  //mffc related
--  del_aubio_mfft(fft_dct);
--  del_cvec(fftgrain_dct);
--  
    aubio_cleanup();
  }
  
index 3a63eebb37014e53ec054cf0db394684064e3271,efeb55a9adbc250ec03beb41136a4f4bac23fd7f..c6e496dd59b151a941497ed112027aad8bf338f3
  
  */
  
+ /* part of this mfcc implementation were inspired from LibXtract
+    http://libxtract.sourceforge.net/
+ */
  #include "aubio_priv.h"
+ #include "sample.h"
  #include "filterbank.h"
  
- // Struct Declaration
++#include "stdio.h"
 +
+ #define USE_EQUAL_GAIN 1
+ #define VERY_SMALL_NUMBER 2e-42
  
- /** \brief A structure to store a set of n_filters Mel filters */
- typedef struct aubio_mel_filter_ {
-     int n_filters;
-     smpl_t **filters;
+ /** \brief A structure to store a set of n_filters filters of lenghts win_s */
+ struct aubio_filterbank_t_ {
+     uint_t win_s;
+     uint_t n_filters;
+     fvec_t **filters;
  };
  
- // Initialization
+ aubio_filterbank_t * new_aubio_filterbank(uint_t n_filters, uint_t win_s){
+   /** allocating space for filterbank object */
+   aubio_filterbank_t * fb = AUBIO_NEW(aubio_filterbank_t);
+   uint_t filter_cnt;
+   fb->win_s=win_s;
+   fb->n_filters=n_filters;
  
- int aubio_mfcc_init(int N, smpl_t nyquist, int style, smpl_t freq_min, smpl_t freq_max, int freq_bands, smpl_t **fft_tables){
+   /** allocating filter tables */
+   fb->filters=AUBIO_ARRAY(fvec_t*,n_filters);
+   for (filter_cnt=0; filter_cnt<n_filters; filter_cnt++)
+     /* considering one-channel filters */
+     fb->filters[filter_cnt]=new_fvec(win_s, 1);
  
-     int n, i, k, *fft_peak, M, next_peak; 
-     smpl_t norm, mel_freq_max, mel_freq_min, norm_fact, height, inc, val, 
-         freq_bw_mel, *mel_peak, *height_norm, *lin_peak;
+   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){
++  
++  uint_t writelog=1;
++
++  FILE * mlog;
++  if(writelog==1) mlog=fopen("filterbank.txt","w");
++  
 +
-     mel_peak = height_norm = lin_peak = NULL;
-     fft_peak = NULL;
-     norm = 1; 
+   smpl_t nyquist = samplerate/2.;
+   uint_t style = 1;
+   aubio_filterbank_t * fb = new_aubio_filterbank(n_filters, win_s);
  
-     mel_freq_max = 1127 * log(1 + freq_max / 700);
-     mel_freq_min = 1127 * log(1 + freq_min / 700);
-     freq_bw_mel = (mel_freq_max - mel_freq_min) / freq_bands;
+   uint_t n, i, k, *fft_peak, M, next_peak; 
+   smpl_t norm, mel_freq_max, mel_freq_min, norm_fact, height, inc, val, 
+          freq_bw_mel, *mel_peak, *height_norm, *lin_peak;
  
-     mel_peak = (smpl_t *)malloc((freq_bands + 2) * sizeof(smpl_t)); 
-     /* +2 for zeros at start and end */
-     lin_peak = (smpl_t *)malloc((freq_bands + 2) * sizeof(smpl_t));
-     fft_peak = (int *)malloc((freq_bands + 2) * sizeof(int));
-     height_norm = (smpl_t *)malloc(freq_bands * sizeof(smpl_t));
+   mel_peak = height_norm = lin_peak = NULL;
+   fft_peak = NULL;
+   norm = 1; 
  
-     if(mel_peak == NULL || height_norm == NULL || 
-                     lin_peak == NULL || fft_peak == NULL)
-                     return XTRACT_MALLOC_FAILED;
-     
-     M = N >> 1;
+   mel_freq_max = 1127 * log(1 + freq_max / 700);
+   mel_freq_min = 1127 * log(1 + freq_min / 700);
+   freq_bw_mel = (mel_freq_max - mel_freq_min) / fb->n_filters;
  
-     mel_peak[0] = mel_freq_min;
-     lin_peak[0] = 700 * (exp(mel_peak[0] / 1127) - 1);
-     fft_peak[0] = lin_peak[0] / nyquist * M;
+   mel_peak = (smpl_t *)malloc((fb->n_filters + 2) * sizeof(smpl_t)); 
+   /* +2 for zeros at start and end */
+   lin_peak = (smpl_t *)malloc((fb->n_filters + 2) * sizeof(smpl_t));
+   fft_peak = (uint_t *)malloc((fb->n_filters + 2) * sizeof(uint_t));
+   height_norm = (smpl_t *)malloc(fb->n_filters * sizeof(smpl_t));
  
+   if(mel_peak == NULL || height_norm == NULL || 
+       lin_peak == NULL || fft_peak == NULL)
+     return NULL;
  
-     for (n = 1; n <= freq_bands; n++){  
+   M = fb->win_s >> 1;
+   mel_peak[0] = mel_freq_min;
+   lin_peak[0] = 700 * (exp(mel_peak[0] / 1127) - 1);
+   fft_peak[0] = lin_peak[0] / nyquist * M;
+   for (n = 1; n <= fb->n_filters; n++){  
      /*roll out peak locations - mel, linear and linear on fft window scale */
-         mel_peak[n] = mel_peak[n - 1] + freq_bw_mel;
-         lin_peak[n] = 700 * (exp(mel_peak[n] / 1127) -1);
-         fft_peak[n] = lin_peak[n] / nyquist * M;
+     mel_peak[n] = mel_peak[n - 1] + freq_bw_mel;
+     lin_peak[n] = 700 * (exp(mel_peak[n] / 1127) -1);
+     fft_peak[n] = lin_peak[n] / nyquist * M;
+   }
+   for (n = 0; n < fb->n_filters; n++){
+     /*roll out normalised gain of each peak*/
+     if (style == USE_EQUAL_GAIN){
+       height = 1; 
+       norm_fact = norm;
      }
+     else{
+       height = 2 / (lin_peak[n + 2] - lin_peak[n]);
+       norm_fact = norm / (2 / (lin_peak[2] - lin_peak[0]));
+     }
+     height_norm[n] = height * norm_fact;
+   }
+   i = 0;
  
-     for (n = 0; n < freq_bands; n++){
-         /*roll out normalised gain of each peak*/
-         if (style == XTRACT_EQUAL_GAIN){
-             height = 1; 
-             norm_fact = norm;
-         }
-         else{
-             height = 2 / (lin_peak[n + 2] - lin_peak[n]);
-             norm_fact = norm / (2 / (lin_peak[2] - lin_peak[0]));
-         }
-         height_norm[n] = height * norm_fact;
+   for(n = 0; n < fb->n_filters; n++){
+     /*calculate the rise increment*/
+     if(n > 0)
+       inc = height_norm[n] / (fft_peak[n] - fft_peak[n - 1]);
+     else
+       inc = height_norm[n] / fft_peak[n];
+     val = 0;  
+     /*zero the start of the array*/
+     for(k = 0; k < i; k++)
+       fb->filters[n]->data[0][k]=0.f;
+     /*fill in the rise */
+     for(; i <= fft_peak[n]; i++){ 
+       fb->filters[n]->data[0][k]=val;
+       val += inc;
      }
  
-     i = 0;
-    
-     for(n = 0; n < freq_bands; n++){
-   
-   /*calculate the rise increment*/
-         if(n > 0)
-             inc = height_norm[n] / (fft_peak[n] - fft_peak[n - 1]);
-         else
-             inc = height_norm[n] / fft_peak[n];
-         val = 0;  
-   
-   /*zero the start of the array*/
-   for(k = 0; k < i; k++)
-      fft_tables[n][k] = 0.f;
-   
-   /*fill in the rise */
-         for(; i <= fft_peak[n]; i++){ 
-             fft_tables[n][i] = val;
-             val += inc;
-         }
-   
-         /*calculate the fall increment */
-         inc = height_norm[n] / (fft_peak[n + 1] - fft_peak[n]);
-   
-         val = 0;
-   next_peak = fft_peak[n + 1];
-   
-   /*reverse fill the 'fall' */
-         for(i = next_peak; i > fft_peak[n]; i--){ 
-             fft_tables[n][i] = val;
-             val += inc;
-         }
-   /*zero the rest of the array*/
-   for(k = next_peak + 1; k < N; k++)
-       fft_tables[n][k] = 0.f;
+     /*calculate the fall increment */
+     inc = height_norm[n] / (fft_peak[n + 1] - fft_peak[n]);
+     val = 0;
+     next_peak = fft_peak[n + 1];
+     /*reverse fill the 'fall' */
+     for(i = next_peak; i > fft_peak[n]; i--){ 
+       fb->filters[n]->data[0][k]=val;
+       val += inc;
+     }
+     /*zero the rest of the array*/
+     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");
 +    }
 +
-     free(mel_peak);
-     free(lin_peak);
-     free(height_norm);
-     free(fft_peak);
+   }
+   free(mel_peak);
+   free(lin_peak);
+   free(height_norm);
+   free(fft_peak);
++  if(mlog) fclose(mlog);
++
+   return fb;
  
-     return XTRACT_SUCCESS;
+ }
+ void del_aubio_filterbank(aubio_filterbank_t * fb){
+   uint_t filter_cnt;
+   /** deleting filter tables first */
+   for (filter_cnt=0; filter_cnt<fb->n_filters; filter_cnt++)
+     del_fvec(fb->filters[filter_cnt]);
+   AUBIO_FREE(fb->filters);
+   AUBIO_FREE(fb);
+ }
  
+ void aubio_filterbank_do(aubio_filterbank_t * f, cvec_t * in, fvec_t *out) {
+   uint_t n, filter_cnt;
+   for(filter_cnt = 0; (filter_cnt < f->n_filters)
+     && (filter_cnt < out->length); filter_cnt++){
+       out->data[0][filter_cnt] = 0.f;
+       for(n = 0; n < in->length; n++){
+           out->data[0][filter_cnt] += in->norm[0][n] 
+             * f->filters[filter_cnt]->data[0][n];
+       }
+       out->data[0][filter_cnt] =
+         LOG(out->data[0][filter_cnt] < VERY_SMALL_NUMBER ? 
+             VERY_SMALL_NUMBER : out->data[0][filter_cnt]);
+   }
+   return;
  }
diff --cc src/mfcc.c
index a92d9e61e59a724cb62f3084873588da5966885f,fe5ea48ad07693e0084b46c280c1b622355d86b6..3bd6da64366258facb7e584761f40c914b7b6676
  #include "mfcc.h"
  #include "math.h"
  
- /*
- new_aubio_mfcc
- aubio_mfcc_do
- del_aubio_mfcc
- */
- // Computation
- // Added last two arguments to be able to pass from example
- int aubio_mfcc_do(const float *data, const int N, const void *argv, float *result, aubio_mfft_t * fft_dct, cvec_t * fftgrain_dct){
-     aubio_mel_filter *f;
-     int n, filter;
-     f = (aubio_mel_filter *)argv;
-     
-     for(filter = 0; filter < f->n_filters; filter++){
-         result[filter] = 0.f;
-         for(n = 0; n < N; n++){
-             result[filter] += data[n] * f->filters[filter][n];
-         }
-         result[filter] = LOG(result[filter] < XTRACT_LOG_LIMIT ? XTRACT_LOG_LIMIT : result[filter]);
-     }
-     //TODO: check that zero padding 
-     for(n = filter + 1; n < N; n++) result[n] = 0; 
-     
-     aubio_dct_do(result, f->n_filters, NULL, result, fft_dct, fftgrain_dct);
-     
-     return XTRACT_SUCCESS;
+ /** Internal structure for mfcc object **/
+ struct aubio_mfcc_t_{
+   uint_t win_s;             /** grain length */
+   uint_t samplerate;        /** sample rate (needed?) */
+   uint_t channels;          /** number of channels */
 -  uint_t n_coefs;           /** number of coefficients (= fb->n_filters/2 +1) */
++  uint_t n_filters;         /** number of  *filters */
++  uint_t n_coefs;           /** number of coefficients (<= n_filters/2 +1) */
+   smpl_t lowfreq;           /** lowest frequency for filters */ 
+   smpl_t highfreq;          /** highest frequency for filters */
+   aubio_filterbank_t * fb;  /** filter bank */
+   fvec_t * in_dct;          /** input buffer for dct * [fb->n_filters] */
+   aubio_mfft_t * fft_dct;   /** fft object for dct */
+   cvec_t * fftgrain_dct;    /** output buffer for dct */
+ };
 -aubio_mfcc_t * new_aubio_mfcc (uint_t win_s, uint_t samplerate ,uint_t n_coefs, smpl_t lowfreq, smpl_t highfreq, uint_t channels){
++aubio_mfcc_t * new_aubio_mfcc (uint_t win_s, uint_t samplerate, uint_t n_filters, uint_t n_coefs, smpl_t lowfreq, smpl_t highfreq, uint_t channels){
+   /** allocating space for mfcc object */
+   aubio_mfcc_t * mfcc = AUBIO_NEW(aubio_mfcc_t);
+   //we need (n_coefs-1)*2 filters to obtain n_coefs coefficients after dct
 -  uint_t n_filters = (n_coefs-1)*2;
++  //uint_t n_filters = (n_coefs-1)*2;
+   
+   mfcc->win_s=win_s;
+   mfcc->samplerate=samplerate;
+   mfcc->channels=channels;
++  mfcc->n_filters=n_filters;
+   mfcc->n_coefs=n_coefs;
+   mfcc->lowfreq=lowfreq;
+   mfcc->highfreq=highfreq;
+   /** filterbank allocation */
+   mfcc->fb = new_aubio_filterbank_mfcc(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);
+   /** allocating buffers */
+   mfcc->in_dct=new_fvec(mfcc->win_s, 1);
+   
+   mfcc->fftgrain_dct=new_cvec(n_filters, 1);
+   return mfcc;
+ };
+ void del_aubio_mfcc(aubio_mfcc_t *mf){
+   /** deleting filterbank */
+   del_aubio_filterbank(mf->fb);
+   /** deleting mfft object */
+   del_aubio_mfft(mf->fft_dct);
+   /** deleting buffers */
+   del_fvec(mf->in_dct);
+   del_cvec(mf->fftgrain_dct);
+   
+   /** deleting mfcc object */
+   AUBIO_FREE(mf);
  }
  
- // Added last two arguments to be able to pass from example
- int aubio_dct_do(const float *data, const int N, const void *argv, float *result, aubio_mfft_t * fft_dct, cvec_t * fftgrain_dct){
-     
+ void aubio_mfcc_do(aubio_mfcc_t * mf, cvec_t *in, fvec_t *out){
+     // compute filterbank
+     aubio_filterbank_do(mf->fb, in, mf->in_dct);
+     //TODO: check that zero padding 
+     // the following line seems useless since the in_dct buffer has the correct size
+     //for(n = filter + 1; n < N; n++) result[n] = 0; 
      
-     //call aubio p_voc in dct setting
+     aubio_dct_do(mf, mf->in_dct, out);
  
-     //TODO: fvec as input? Remove data length, N?
+     return;
+ }
  
-     fvec_t * momo = new_fvec(20, 1);
-     momo->data = data;
-     
+ void aubio_dct_do(aubio_mfcc_t * mf, fvec_t *in, fvec_t *out){
+     uint_t i;
      //compute mag spectrum
-     aubio_mfft_do (fft_dct, data, fftgrain_dct);
-     int i;
+     aubio_mfft_do (mf->fft_dct, in, mf->fftgrain_dct);
      //extract real part of fft grain
-     for(i=0; i<N ;i++){
-       result[i]= fftgrain_dct->norm[0][i]*COS(fftgrain_dct->phas[0][i]);
 -    //for(i=0; i<mf->n_coefs ;i++){
 -    for(i=0; i<out->length;i++){
++    for(i=0; i<mf->n_coefs ;i++){
++    //for(i=0; i<out->length;i++){
+       out->data[0][i]= mf->fftgrain_dct->norm[0][i]
+         *COS(mf->fftgrain_dct->phas[0][i]);
      }
-     return XTRACT_SUCCESS;
+     return;
  }
diff --cc src/mfcc.h
index d4b036399e8c248a1a47e42fd4dac02aa0740037,c86b089f3996d2bd24fcafa64cfea6571be5fda6..3e7c714c5f19eb5fd371b1c691cd6a12dd8425dd
  extern "C" {
  #endif
  
+ #include "sample.h"
  #include "filterbank.h"
  
- //libXtract constants and enums
- // TODO: remove them 
- #define XTRACT_SQ(a) ((a) * (a))
- #define XTRACT_MIN(a, b) ((a) < (b) ? (a) : (b))
- #define XTRACT_MAX(a, b) ((a) > (b) ? (a) : (b))
- #define XTRACT_NEEDS_FFTW printf("LibXtract must be compiled with fftw support to use this function.\n")
- #define XTRACT_VERY_SMALL_NUMBER 2e-42
- #define XTRACT_LOG_LIMIT XTRACT_VERY_SMALL_NUMBER
- #define XTRACT_LOG_LIMIT_DB -96.0
- #define XTRACT_DB_SCALE_OFFSET 96.0
- #define XTRACT_VERY_BIG_NUMBER 2e42
- #define XTRACT_SR_UPPER_LIMIT 192000.0
- #define XTRACT_SR_LOWER_LIMIT 22050.0
- #define XTRACT_SR_DEFAULT 44100.0
- #define XTRACT_FUNDAMENTAL_DEFAULT 440.0
- #define XTRACT_CHECK_nyquist if(!nyquist) nyquist = XTRACT_SR_DEFAULT / 2
- #define XTRACT_CHECK_q if(!q) q = XTRACT_SR_DEFAULT / N
- #define XTRACT_IS_ODD(x) (x % 2 != 0 ? 1 : 0) 
- #define XTRACT_SR_LIMIT SR_UPPER_LIMIT
- #define XTRACT_FFT_BANDS_MIN 16
- #define XTRACT_FFT_BANDS_MAX 65536
- #define XTRACT_FFT_BANDS_DEF 1024
- #define XTRACT_SPEC_BW_MIN 0.168 /* Minimum spectral bandwidth \
-             (= SR_LOWER_LIMIT / FFT_BANDS_MAX*/ 
- #define XTRACT_SPEC_BW_MAX 12000.0 /* SR_UPPER_LIMIT / FFT_BANDS_MIN */
- #define XTRACT_SPEC_BW_DEF 43.066 /* SR_DEFAULT / FFT_BANDS_DEF */
- /** \brief Enumeration of feature initialisation functions */
- enum xtract_feature_init_ {
-     XTRACT_INIT_MFCC = 100,
-     XTRACT_INIT_BARK
- };
- /** \brief Enumeration of feature types */
- enum xtract_feature_types_ {
-     XTRACT_SCALAR,
-     XTRACT_VECTOR,
-     XTRACT_DELTA
- };
- /** \brief Enumeration of mfcc types */
- enum xtract_mfcc_types_ {
-     XTRACT_EQUAL_GAIN,
-     XTRACT_EQUAL_AREA
- };
- /** \brief Enumeration of return codes */
- enum xtract_return_codes_ {
-     XTRACT_SUCCESS,
-     XTRACT_MALLOC_FAILED,
-     XTRACT_BAD_ARGV,
-     XTRACT_BAD_VECTOR_SIZE,
-     XTRACT_NO_RESULT,
-     XTRACT_FEATURE_NOT_IMPLEMENTED
- };
- /** \brief Enumeration of spectrum types */
- enum xtract_spectrum_ {
-     XTRACT_MAGNITUDE_SPECTRUM,
-     XTRACT_LOG_MAGNITUDE_SPECTRUM,
-     XTRACT_POWER_SPECTRUM,
-     XTRACT_LOG_POWER_SPECTRUM
- };
- /** \brief Enumeration of data types*/
- typedef enum type_ {
-     XTRACT_FLOAT,
-     XTRACT_FLOATARRAY,
-     XTRACT_INT,
-     XTRACT_MEL_FILTER
- } xtract_type_t;
- /** \brief Enumeration of units*/
- typedef enum unit_ {
-     /* NONE, ANY */
-     XTRACT_HERTZ = 2,
-     XTRACT_ANY_AMPLITUDE_HERTZ,
-     XTRACT_DBFS,
-     XTRACT_DBFS_HERTZ,
-     XTRACT_PERCENT,
-     XTRACT_SONE
- } xtract_unit_t;
- /** \brief Boolean */
- typedef enum {
-     XTRACT_FALSE,
-     XTRACT_TRUE
- } xtract_bool_t;
- /** \brief Enumeration of vector format types*/
- typedef enum xtract_vector_ {
-     /* N/2 magnitude/log-magnitude/power/log-power coeffs and N/2 frequencies */
-     XTRACT_SPECTRAL,     
-     /* N spectral amplitudes */
-     XTRACT_SPECTRAL_MAGNITUDES, 
-     /* N/2 magnitude/log-magnitude/power/log-power peak coeffs and N/2 
-      * frequencies */
-     XTRACT_SPECTRAL_PEAKS,
-     /* N spectral peak amplitudes */
-     XTRACT_SPECTRAL_PEAKS_MAGNITUDES,
-     /* N spectral peak frequencies */
-     XTRACT_SPECTRAL_PEAKS_FREQUENCIES,
-     /* N/2 magnitude/log-magnitude/power/log-power harmonic peak coeffs and N/2 
-      * frequencies */
-     XTRACT_SPECTRAL_HARMONICS,
-     /* N spectral harmonic amplitudes */
-     XTRACT_SPECTRAL_HARMONICS_MAGNITUDES,
-     /* N spectral harmonic frequencies */
-     XTRACT_SPECTRAL_HARMONICS_FREQUENCIES,
-     XTRACT_ARBITRARY_SERIES,
-     XTRACT_AUDIO_SAMPLES,
-     XTRACT_MEL_COEFFS, 
-     XTRACT_BARK_COEFFS,
-     XTRACT_NO_DATA
- } xtract_vector_t;
- // Computation
- /** \brief Extract Mel Frequency Cepstral Coefficients based on a method described by Rabiner
-  * 
-  * \param *data: a pointer to the first element in an array of spectral magnitudes, e.g. the first half of the array pointed to by *resul from xtract_spectrum()
-  * \param N: the number of array elements to be considered
-  * \param *argv: a pointer to a data structure of type xtract_mel_filter, containing n_filters coefficient tables to make up a mel-spaced filterbank
-  * \param *result: a pointer to an array containing the resultant MFCC
-  * 
-  * The data structure pointed to by *argv must be obtained by first calling xtract_init_mfcc
-  */
- int aubio_mfcc_do(const float *data, const int N, const void *argv, float *result, aubio_mfft_t *fft_dct, cvec_t *fftgrain_dct);
- /** \brief Extract the Discrete Cosine transform of a time domain signal
-  * \param *data: a pointer to the first element in an array of floats representing an audio vector
-  * \param N: the number of array elements to be considered
-  * \param *argv: a pointer to NULL 
-  * \param *result: a pointer to an array containing resultant dct coefficients
-  */
- int aubio_dct_do(const float *data, const int N, const void *argv, float *result, aubio_mfft_t *fft_dct, cvec_t *fftgrain_dct);
+ typedef struct aubio_mfcc_t_ aubio_mfcc_t;
+ /** create mfcc object
+   \param win_s size of analysis buffer (and length the FFT transform)
+   \param samplerate 
+   \param n_coefs: number of desired coefs
+   \param lowfreq: lowest frequency to use in filterbank
+   \param highfreq highest frequency to use in filterbank
+   \param channels number of channels
+ */
 -aubio_mfcc_t * new_aubio_mfcc (uint_t win_s, uint_t samplerate ,uint_t n_coefs, smpl_t lowfreq, smpl_t highfreq, uint_t channels);
++aubio_mfcc_t * new_aubio_mfcc (uint_t win_s, uint_t samplerate, uint_t n_filters, uint_t n_coefs, smpl_t lowfreq, smpl_t highfreq, uint_t channels);
+ /** delete mfcc object
+   \param mf mfcc object as returned by new_aubio_mfcc
+ */
+ void del_aubio_mfcc(aubio_mfcc_t *mf);
+ /** mfcc object processing
+   \param mf mfcc object as returned by new_aubio_mfcc
+   \param in input spectrum (win_s long)
+   \param out output mel coefficients buffer (n_filters/2 +1 long)
+ */
+ void aubio_mfcc_do(aubio_mfcc_t * mf, cvec_t *in, fvec_t *out);
+ /** intermediate dct involved in aubio_mfcc_do
+   \param mf mfcc object as returned by new_aubio_mfcc
+   \param in input spectrum (n_filters long)
+   \param out output mel coefficients buffer (n_filters/2 +1 long)
+ */
+ void aubio_dct_do(aubio_mfcc_t * mf, fvec_t *in, fvec_t *out);
  
  #ifdef __cplusplus
  }