shithub: aubio

Download patch

ref: 7a46bf6cec4e3b9ce9f40ff1db3a98933e016c56
parent: 7c6c806dda27c76b03afac7bfeecdaa88371a0ed
parent: 45134c5d80f69a506f3619ce88fbafc1b2a54434
author: Amaury Hazan <mahmoudax@gmail.org>
date: Mon Sep 10 15:29:32 EDT 2007

merged from piem, corrected mffcs coefs/filter number
added some scripts to visualize filterbank and mfccs

--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -10,7 +10,8 @@
 bin_PROGRAMS = \
 	aubioonset \
 	aubiotrack \
-	aubionotes
+	aubionotes \
+	aubiomfcc
 
 noinst_PROGRAMS = \
 	aubioquiet
@@ -22,8 +23,10 @@
 aubionotes_SOURCES = aubionotes.c utils.c
 aubiotrack_SOURCES = aubiotrack.c utils.c
 aubioquiet_SOURCES = aubioquiet.c utils.c
+aubiomfcc_SOURCES = aubiomfcc.c utils.c
 
 aubioonset_LDADD = @JACK_LIBS@
 aubionotes_LDADD = @JACK_LIBS@
 aubiotrack_LDADD = @JACK_LIBS@
 aubioquiet_LDADD = @JACK_LIBS@
+aubiomfcc_LDADD = @JACK_LIBS@
--- a/examples/aubiomfcc.c
+++ b/examples/aubiomfcc.c
@@ -1,5 +1,6 @@
 /*
-   Copyright (C) 2007 Amaury Hazan
+   Copyright (C) 2007 Amaury Hazan <ahazan@iua.upf.edu>
+                  and Paul Brossier <piem@piem.org>
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -18,6 +19,13 @@
 
 #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;
 
@@ -42,21 +50,8 @@
       //compute mag spectrum
       aubio_pvoc_do (pv,ibuf, fftgrain);
      
-      uint_t n_coefs= n_filters/2 +1;
-      uint_t coef_cnt;
-       
-
-      for (coef_cnt=0; coef_cnt<n_coefs ; coef_cnt++)
-        mfcc_outbuf[coef_cnt]=0.f;
-       
       //compute mfccs
-      aubio_mffc_do(fftgrain->norm, nframes, mf, mfcc_outbuf, fft_dct, fftgrain_dct);
-      
-      for (coef_cnt=0; coef_cnt<n_coefs ; coef_cnt++)
-        outmsg("%f ",mfcc_outbuf[coef_cnt]);
-      outmsg("\n");
-      
-      
+      aubio_mfcc_do(mfcc, fftgrain, mfcc_out);
 
       /* end of block loop */
       pos = -1; /* so it will be zero next j loop */
@@ -72,41 +67,46 @@
          write extracted mfccs
       */
       
+      uint_t coef_cnt;
       if (output_filename == NULL) {
-        if(frames >= 4) {
-          outmsg("%f\n",(frames-4)*overlap_size/(float)samplerate);
-        } else if (frames < 4) {
-          outmsg("%f\n",0.);
+//         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");/*/
       }
 }
 
 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);
   
-  //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);
-
-  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));
-  
   //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, n_coefs , lowfreq, highfreq, channels);
 
   //process
   examples_common_process(aubio_process,process_print);
+  
+  //destroying mfcc 
+  del_aubio_mfcc(mfcc);
+  del_fvec(mfcc_out);
+
   examples_common_del();
   debug("End of program.\n");
   fflush(stderr);
-  
-  //destroying filterbank
-  free(mf);
   
   return 0;
 }
--- /dev/null
+++ b/examples/plotfb.py
@@ -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()
\ No newline at end of file
--- /dev/null
+++ b/examples/plotmat.py
@@ -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()
\ No newline at end of file
--- a/examples/tests/test-beattracking.c
+++ b/examples/tests/test-beattracking.c
@@ -12,8 +12,15 @@
 
         uint_t i = 0;
 
+        smpl_t curtempo;
+
         while (i < 10) {
           aubio_beattracking_do(tempo,in,out);
+          curtempo = aubio_beattracking_get_bpm(tempo);
+          if (curtempo != 0.) {
+            fprintf(stdout,"%f\n",curtempo);
+            return 1;
+          }
           i++;
         };
 
--- a/examples/tests/test-tempo.c
+++ b/examples/tests/test-tempo.c
@@ -9,8 +9,14 @@
         aubio_tempo_t * o  = new_aubio_tempo(aubio_onset_complex, win_s, win_s/4, channels);
         uint_t i = 0;
 
+        smpl_t curtempo;
+
         while (i < 1000) {
           aubio_tempo(o,in,out);
+          curtempo = aubio_tempo_get_bpm(o);
+          if (curtempo != 0.) {
+            fprintf(stdout,"%f\n",curtempo);
+          }
           i++;
         };
 
--- a/examples/utils.c
+++ b/examples/utils.c
@@ -60,21 +60,6 @@
 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;
-
-// DCT mfft and result storage
-aubio_mfft * fft_dct;
-cvec_t * fftgrain_dct;
-smpl_t mfcc_outbuf[11];
-
-
 /* pitch objects */
 smpl_t pitch               = 0.;
 aubio_pitchdetection_t * pitchdet;
@@ -314,9 +299,7 @@
   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);
@@ -330,10 +313,6 @@
   /* 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);
@@ -367,10 +346,6 @@
   del_cvec(fftgrain);
   del_fvec(onset);
   del_fvec(woodblock);
-  
-  //mffc related
-  del_aubio_mfft(fft_dct);
-  del_cvec(fftgrain_dct);
   
   aubio_cleanup();
 }
--- a/examples/utils.h
+++ b/examples/utils.h
@@ -97,19 +97,6 @@
 extern int isonset;
 extern aubio_pickpeak_t * parms;
 
-/* mfcc objects */
-// params
-extern uint_t n_filters;
-extern uint_t nyquist; 
-extern smpl_t lowfreq;
-extern smpl_t highfreq;
-// filterbank object
-extern aubio_mel_filter * mf;
-// DCT pvoc and result storage
-extern aubio_mfft_t * fft_dct;
-extern cvec_t * fftgrain_dct;
-extern smpl_t mfcc_outbuf[20];
-
 /* pitch objects */
 extern smpl_t pitch;
 extern aubio_pitchdetection_t * pitchdet;
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -22,6 +22,7 @@
 	onset.h \
 	tempo.h \
 	filter.h \
+	filterbank.h \
 	mfcc.h
 
 nodist_pkginclude_HEADERS = config.h
@@ -71,6 +72,8 @@
 	tempo.h \
 	filter.c \
 	filter.h \
+	filterbank.c \
+	filterbank.h \
 	mfcc.h \
 	mfcc.c 
 
--- a/src/aubio.h
+++ b/src/aubio.h
@@ -79,6 +79,7 @@
 #include "beattracking.h"
 #include "onset.h"
 #include "tempo.h"
+#include "filterbank.h"
 #include "mfcc.h"
 
 #ifdef __cplusplus
--- a/src/beattracking.c
+++ b/src/beattracking.c
@@ -452,3 +452,11 @@
         bt->rp2 = rp2;
 
 }
+
+smpl_t aubio_beattracking_get_bpm(aubio_beattracking_t * bt) {
+        if (bt->timesig != 0 && bt->counter == 0 && bt->flagstep == 0) {
+          return 5168. / (smpl_t)bt->gp;
+        } else {
+          return 0.;
+        }
+}
--- a/src/beattracking.h
+++ b/src/beattracking.h
@@ -59,6 +59,15 @@
 
 */
 void aubio_beattracking_do(aubio_beattracking_t * bt, fvec_t * dfframes, fvec_t * out);
+/** get current tempo in bpm
+
+  \param bt beat tracking object
+
+  Returns the currently observed tempo, in beats per minutes, or 0 if no
+  consistent value is found.
+
+*/
+smpl_t aubio_beattracking_get_bpm(aubio_beattracking_t * bt);
 /** delete beat tracking object
 
   \param p beat tracking object
--- a/src/filterbank.c
+++ b/src/filterbank.c
@@ -1,8 +1,6 @@
 /*
-   Copyright (C) 2007 Amaury Hazan
-   Ported to aubio from LibXtract
-   http://libxtract.sourceforge.net/
-   
+   Copyright (C) 2007 Amaury Hazan <ahazan@iua.upf.edu>
+                  and Paul Brossier <piem@piem.org>
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -20,114 +18,184 @@
 
 */
 
+/* part of this mfcc implementation were inspired from LibXtract
+   http://libxtract.sourceforge.net/
+*/
+
 #include "aubio_priv.h"
+#include "sample.h"
 #include "filterbank.h"
 
+#include "stdio.h"
 
-// Struct Declaration
+#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;
+}
 
-    mel_peak = height_norm = lin_peak = NULL;
-    fft_peak = NULL;
-    norm = 1; 
+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;
 
-    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;
+  FILE * mlog;
+  if(writelog==1) mlog=fopen("filterbank.txt","w");
+  
 
-    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));
+  smpl_t nyquist = samplerate/2.;
+  uint_t style = 1;
+  aubio_filterbank_t * fb = new_aubio_filterbank(n_filters, win_s);
 
-    if(mel_peak == NULL || height_norm == NULL || 
-                    lin_peak == NULL || fft_peak == NULL)
-                    return XTRACT_MALLOC_FAILED;
-    
-    M = N >> 1;
+  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[0] = mel_freq_min;
-    lin_peak[0] = 700 * (exp(mel_peak[0] / 1127) - 1);
-    fft_peak[0] = lin_peak[0] / nyquist * M;
+  mel_peak = height_norm = lin_peak = NULL;
+  fft_peak = NULL;
+  norm = 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;
 
-    for (n = 1; n <= freq_bands; n++){  
+  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;
+
+  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;
+  }
 
-    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;
+  i = 0;
+
+  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;
-        }
+    /*calculate the fall increment */
+    inc = height_norm[n] / (fft_peak[n + 1] - fft_peak[n]);
 
-  /*zero the rest of the array*/
-  for(k = next_peak + 1; k < N; k++)
-      fft_tables[n][k] = 0.f;
+    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;
     }
 
-    free(mel_peak);
-    free(lin_peak);
-    free(height_norm);
-    free(fft_peak);
+    /*zero the rest of the array*/
+    for(k = next_peak + 1; k < fb->win_s; k++)
+      fb->filters[n]->data[0][k]=0.f;
 
-    return XTRACT_SUCCESS;
+    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);
+
+  if(mlog) fclose(mlog);
+
+  return fb;
+
+}
+
+
+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;
 }
--- a/src/filterbank.h
+++ b/src/filterbank.h
@@ -1,8 +1,6 @@
 /*
-   Copyright (C) 2007 Amaury Hazan
-   Ported to aubio from LibXtract
-   http://libxtract.sourceforge.net/
-   
+   Copyright (C) 2007 Amaury Hazan <ahazan@iua.upf.edu>
+                  and Paul Brossier <piem@piem.org>
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -19,27 +17,57 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#ifndef AUBIOFILTERBANK_H
-#define AUBIOFILTERBANK_H
+/** \file
 
+  Filterbank object
+
+  General-purpose spectral filterbank object. Comes with mel-filter initialization function.
+
+*/
+
+#ifndef FILTERBANK_H
+#define FILTERBANK_H
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+typedef struct aubio_filterbank_t_ aubio_filterbank_t;
 
+/** create filterbank object
 
-typedef struct aubio_mel_filter_ aubio_mel_filter;
+  \param win_s size of analysis buffer (and length the FFT transform)
+  \param n_filters number of filters to create
 
-// Initialization
+*/
 
-/** \brief A function to initialise a mel filter bank 
- * 
- * It is up to the caller to pass in a pointer to memory allocated for freq_bands arrays of length N. This function populates these arrays with magnitude coefficients representing the mel filterbank on a linear scale 
- */
-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);
+aubio_filterbank_t * new_aubio_filterbank(uint_t n_filters, uint_t win_s);
 
+/** 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
+
+*/
+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);
+
+
+/** destroy filterbank object
+
+  \param fb filterbank, as returned by new_aubio_filterbank method
+
+*/
+void del_aubio_filterbank(aubio_filterbank_t * fb);
+
+/** compute filterbank
+
+*/
+void aubio_filterbank_do(aubio_filterbank_t * fb, cvec_t * in, fvec_t *out);
+
 #ifdef __cplusplus
 }
 #endif
 
-#endif
+#endif // FILTERBANK_H
--- a/src/mfcc.c
+++ b/src/mfcc.c
@@ -23,64 +23,91 @@
 #include "aubio_priv.h"
 #include "sample.h"
 #include "fft.h"
+#include "filterbank.h"
 #include "mfcc.h"
 #include "math.h"
 
-/*
-new_aubio_mfcc
-aubio_mfcc_do
-del_aubio_mfcc
-*/
+/** Internal structure for mfcc object **/
 
-// Computation
-// Added last two arguments to be able to pass from example
+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_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_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);
 
-int aubio_mfcc_do(const float *data, const int N, const void *argv, float *result, aubio_mfft_t * fft_dct, cvec_t * fftgrain_dct){
+  //we need (n_coefs-1)*2 filters to obtain n_coefs coefficients after dct
+  //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;
 
-    aubio_mel_filter *f;
-    int n, filter;
+  /** filterbank allocation */
+  mfcc->fb = new_aubio_filterbank_mfcc(n_filters, mfcc->win_s, samplerate, lowfreq, highfreq);
 
-    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]);
-    }
+  /** allocating space for fft object (used for dct) */
+  mfcc->fft_dct=new_aubio_mfft(n_filters, 1);
 
-    //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;
-}
+  /** allocating buffers */
+  mfcc->in_dct=new_fvec(mfcc->win_s, 1);
+  
+  mfcc->fftgrain_dct=new_cvec(n_filters, 1);
 
-// Added last two arguments to be able to pass from example
+  return mfcc;
+};
 
-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 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);
+}
+
+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++){
+      out->data[0][i]= mf->fftgrain_dct->norm[0][i]
+        *COS(mf->fftgrain_dct->phas[0][i]);
     }
-
-
-    return XTRACT_SUCCESS;
+    return;
 }
+
--- a/src/mfcc.h
+++ b/src/mfcc.h
@@ -1,8 +1,6 @@
 /*
-   Copyright (C) 2006 Amaury Hazan
-   Ported to aubio from LibXtract
-   http://libxtract.sourceforge.net/
-   
+   Copyright (C) 2007 Amaury Hazan <ahazan@iua.upf.edu>
+                  and Paul Brossier <piem@piem.org>
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -20,6 +18,10 @@
 
 */
 
+/* part of this mfcc implementation were inspired from LibXtract
+   http://libxtract.sourceforge.net/
+*/
+
 #ifndef MFCC_H 
 #define MFCC_H 
 
@@ -27,153 +29,48 @@
 extern "C" {
 #endif
 
+#include "sample.h"
 #include "filterbank.h"
 
-//libXtract constants and enums
-// TODO: remove them 
+typedef struct aubio_mfcc_t_ aubio_mfcc_t;
 
-#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 */
+/** create mfcc object
 
-/** \brief Enumeration of feature initialisation functions */
-enum xtract_feature_init_ {
-    XTRACT_INIT_MFCC = 100,
-    XTRACT_INIT_BARK
-};
+  \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
 
-/** \brief Enumeration of feature types */
-enum xtract_feature_types_ {
-    XTRACT_SCALAR,
-    XTRACT_VECTOR,
-    XTRACT_DELTA
-};
+*/
+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
 
-/** \brief Enumeration of mfcc types */
-enum xtract_mfcc_types_ {
-    XTRACT_EQUAL_GAIN,
-    XTRACT_EQUAL_AREA
-};
+  \param mf mfcc object as returned by new_aubio_mfcc
 
-/** \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
-};
+*/
+void del_aubio_mfcc(aubio_mfcc_t *mf);
+/** mfcc object processing
 
-/** \brief Enumeration of spectrum types */
-enum xtract_spectrum_ {
-    XTRACT_MAGNITUDE_SPECTRUM,
-    XTRACT_LOG_MAGNITUDE_SPECTRUM,
-    XTRACT_POWER_SPECTRUM,
-    XTRACT_LOG_POWER_SPECTRUM
-};
+  \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)
 
-/** \brief Enumeration of data types*/
-typedef enum type_ {
-    XTRACT_FLOAT,
-    XTRACT_FLOATARRAY,
-    XTRACT_INT,
-    XTRACT_MEL_FILTER
-} xtract_type_t;
+*/
+void aubio_mfcc_do(aubio_mfcc_t * mf, cvec_t *in, fvec_t *out);
 
-/** \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;
+/** intermediate dct involved in aubio_mfcc_do
 
-/** \brief Boolean */
-typedef enum {
-    XTRACT_FALSE,
-    XTRACT_TRUE
-} xtract_bool_t;
+  \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)
 
-/** \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;
+*/
+void aubio_dct_do(aubio_mfcc_t * mf, fvec_t *in, fvec_t *out);
 
-
-
-
-// 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);
-
 #ifdef __cplusplus
 }
 #endif
 
-#endif
+#endif // MFCC_H
--- a/src/tempo.c
+++ b/src/tempo.c
@@ -123,6 +123,10 @@
   return o;
 }
 
+smpl_t aubio_tempo_get_bpm(aubio_tempo_t *o) {
+  return aubio_beattracking_get_bpm(o->bt);
+}
+
 void del_aubio_tempo (aubio_tempo_t *o)
 {
   del_aubio_onsetdetection(o->od);
--- a/src/tempo.h
+++ b/src/tempo.h
@@ -49,6 +49,15 @@
 /** set tempo detection peak picking threshold  */
 void aubio_tempo_set_threshold(aubio_tempo_t * o, smpl_t threshold);
 
+/** get current tempo
+
+  \param bt beat tracking object
+
+  Returns the currently observed tempo, or 0 if no consistent value is found
+
+*/
+smpl_t aubio_tempo_get_bpm(aubio_tempo_t * bt);
+
 /** delete tempo detection object */
 void del_aubio_tempo(aubio_tempo_t * o);