From f72ceebbdb0c649e8dd8e8dc95f066aed5746cd4 Mon Sep 17 00:00:00 2001 From: Amaury Hazan Date: Tue, 11 Sep 2007 21:25:43 +0200 Subject: [PATCH] aubiomfcc.c: added a dump filterbank funcion filterbank: written mfcc filterbank init according to slaney auditory toolbox (90%) plotfb.py: added x log scale option #some hacks and debug test --- examples/aubiomfcc.c | 19 +++-- examples/plotfb.py | 11 ++- examples/utils.c | 6 +- src/filterbank.c | 198 ++++++++++++++++++++----------------------- src/filterbank.h | 4 +- src/mfcc.c | 3 +- 6 files changed, 120 insertions(+), 121 deletions(-) diff --git a/examples/aubiomfcc.c b/examples/aubiomfcc.c index 7dabc2fa..d1cd64dd 100644 --- a/examples/aubiomfcc.c +++ b/examples/aubiomfcc.c @@ -23,8 +23,8 @@ fvec_t * mfcc_out; aubio_mfcc_t * mfcc; -uint_t n_filters = 20; -uint_t n_coefs = 11; +uint_t n_filters = 40; +uint_t n_coefs = 20; unsigned int pos = 0; /*frames%dspblocksize*/ uint_t usepitch = 0; @@ -52,7 +52,13 @@ int aubio_process(float **input, float **output, int nframes) { //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,10 +83,7 @@ void process_print (void) { // } //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");/*/ + } } @@ -92,10 +95,12 @@ int main(int argc, char **argv) { 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); diff --git a/examples/plotfb.py b/examples/plotfb.py index a715dda7..4592c139 100755 --- a/examples/plotfb.py +++ b/examples/plotfb.py @@ -4,8 +4,14 @@ import pylab 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 @@ pylab.hold(True) 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) diff --git a/examples/utils.c b/examples/utils.c index 51a6da6a..fff16abd 100644 --- a/examples/utils.c +++ b/examples/utils.c @@ -39,8 +39,10 @@ aubio_onsetdetection_type type_onset = aubio_onset_kl; 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; diff --git a/src/filterbank.c b/src/filterbank.c index d2ba90f2..14c0e45b 100644 --- a/src/filterbank.c +++ b/src/filterbank.c @@ -54,7 +54,7 @@ aubio_filterbank_t * new_aubio_filterbank(uint_t n_filters, uint_t win_s){ 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){ smpl_t nyquist = samplerate/2.; uint_t style = 1; @@ -159,7 +159,10 @@ aubio_filterbank_t * new_aubio_filterbank_mfcc(uint_t n_filters, uint_t win_s, s } -aubio_filterbank_t * new_aubio_filterbank_mfcc2(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_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; @@ -177,142 +180,121 @@ aubio_filterbank_t * new_aubio_filterbank_mfcc2(uint_t n_filters, uint_t win_s, fvec_t * center_freqs=new_fvec( allFilters, 1); fvec_t * triangle_heights=new_fvec( allFilters, 1); //lookup table of each bin frequency in hz - fvec_t * fft_freqs=(win_s, 1); + 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_cntdata[0][filter_cnt]=lowestFrequency+ filter_cnt*linearSpacing; } - smpl_t lastlinearCF=freqs[0][filter_cnt-1]; + smpl_t lastlinearCF=freqs->data[0][filter_cnt-1]; //second: filling all the log filter frequencies for(filter_cnt=0; filter_cntdata[0][filter_cnt+linearFilters]=lastlinearCF*(pow(logSpacing,filter_cnt+1)); } - //TODO: check if the referencing above works! + + + //TODO: Check how these f_vec will be freed lower_freqs->data=freqs->data; - center_freqs->data=&(freqs->data[1]); - upper_freqs->data=&(freqs->data[2]); + 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_cntdata[0][filter_cnt]=2./(upper_freqs->data[0][filter_cnt]-lower_freqs->data[0][filter_cnt]); } - //filling the lookup table, which assign the frequency in hz to each bin + //debug + for(filter_cnt=0; filter_cntdata[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_cntdata[0][bin_cnt]= (smpl_t)samplerate* (smpl_t)bin_cnt/ (smpl_t)win_s; + } - //building each filter + + //building each filter table for(filter_cnt=0; filter_cntdata[0][filter_cnt]/(center_freqs->data[0][filter_cnt]-lower_freqs->data[0][filter_cnt]); + + //zeroing begining of filter + //printf("\nfilter %d",filter_cnt); + + //printf("\nzero begin\n"); + + for(bin_cnt=0; bin_cntfilters[filter_cnt]->data[0][bin_cnt]=0.f; - } - - // xtract - smpl_t nyquist = samplerate/2.; - uint_t style = 1; - aubio_filterbank_t * fb = new_aubio_filterbank(n_filters, win_s); - - 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 = 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; - - 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; - } - - 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])); + //printf("."); + //printf("%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; + } } - 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; + bin_cnt++; + + //printf("\npos slope\n"); + //positive slope + for(; bin_cntfilters[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; } - - /*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; + //bin_cnt++; + + //printf("\nneg slope\n"); + //negative slope + for(; bin_cntdata[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; } - - /*zero the rest of the array*/ - for(k = next_peak + 1; k < fb->win_s; k++) - fb->filters[n]->data[0][k]=0.f; - + //bin_cnt++; + + //printf("\nzero end\n"); + //zeroing tail + for(; bin_cntfilters[filter_cnt]->data[0][bin_cnt]=0.f; } + + + del_fvec(freqs); + //TODO: Check how to do a proper free for the following f_vec - free(mel_peak); - free(lin_peak); - free(height_norm); - free(fft_peak); + //del_fvec(lower_freqs); + //del_fvec(upper_freqs); + //del_fvec(center_freqs); + del_fvec(triangle_heights); + del_fvec(fft_freqs); + return fb; diff --git a/src/filterbank.h b/src/filterbank.h index 362b4ec6..44db5106 100644 --- a/src/filterbank.h +++ b/src/filterbank.h @@ -53,7 +53,7 @@ aubio_filterbank_t * new_aubio_filterbank(uint_t n_filters, uint_t win_s); \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 @@ -64,7 +64,7 @@ aubio_filterbank_t * new_aubio_filterbank_mfcc(uint_t n_filters, uint_t win_s, s \param freq_max highest filter frequency */ -aubio_filterbank_t * new_aubio_filterbank_mfcc_2(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_2(uint_t n_filters, uint_t win_s, uint_t samplerate, smpl_t freq_min, smpl_t freq_max); /** destroy filterbank object diff --git a/src/mfcc.c b/src/mfcc.c index 7588a931..9ea21e57 100644 --- a/src/mfcc.c +++ b/src/mfcc.c @@ -59,8 +59,9 @@ aubio_mfcc_t * new_aubio_mfcc (uint_t win_s, uint_t samplerate, uint_t n_filters 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); -- 2.26.2