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
--
⑨