From: Paul Brossier Date: Thu, 17 Sep 2009 17:31:54 +0000 (+0200) Subject: mfcc.c: use a coefficient table for DCT computation, remove unused parameters X-Git-Tag: bzr2git~340 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=c185ebbaa67e1e02220327d3275c6f58356656e3;p=aubio.git mfcc.c: use a coefficient table for DCT computation, remove unused parameters --- diff --git a/src/spectral/mfcc.c b/src/spectral/mfcc.c index 8d83e705..01bf9764 100644 --- a/src/spectral/mfcc.c +++ b/src/spectral/mfcc.c @@ -32,19 +32,18 @@ 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_fft_t * fft_dct; /** fft object for dct */ - cvec_t * fftgrain_dct; /** output buffer for dct */ + fvec_t * dct_coeffs; /** DCT transform n_filters * n_coeffs */ }; -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){ +aubio_mfcc_t * new_aubio_mfcc (uint_t win_s, uint_t samplerate, uint_t n_filters, uint_t n_coefs){ + + uint_t i, j; + /** allocating space for mfcc object */ aubio_mfcc_t * mfcc = AUBIO_NEW(aubio_mfcc_t); @@ -53,24 +52,31 @@ aubio_mfcc_t * new_aubio_mfcc (uint_t win_s, uint_t samplerate, uint_t n_filters 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(n_filters, mfcc->win_s); aubio_filterbank_set_mel_coeffs_slaney(mfcc->fb, samplerate); - /** allocating space for fft object (used for dct) */ - mfcc->fft_dct=new_aubio_fft(n_filters, 1); - /** allocating buffers */ - mfcc->in_dct=new_fvec(mfcc->win_s, 1); + mfcc->in_dct=new_fvec(n_filters, 1); - mfcc->fftgrain_dct=new_cvec(n_filters, 1); + mfcc->dct_coeffs = new_fvec(n_coefs, n_filters); + + + /* compute DCT transform dct_coeffs[i][j] as + cos ( j * (i+.5) * PI / n_filters ) + */ + smpl_t scaling = 1./SQRT(n_filters/2.); + for (i = 0; i < n_filters; i++) { + for (j = 0; j < n_coefs; j++) { + mfcc->dct_coeffs->data[i][j] = + scaling * COS (j * (i + 0.5) * PI / n_filters); + } + mfcc->dct_coeffs->data[i][0] *= SQRT(2.)/2.; + } return mfcc; }; @@ -78,48 +84,26 @@ aubio_mfcc_t * new_aubio_mfcc (uint_t win_s, uint_t samplerate, uint_t n_filters void del_aubio_mfcc(aubio_mfcc_t *mf){ /** deleting filterbank */ del_aubio_filterbank(mf->fb); - /** deleting fft object */ - del_aubio_fft(mf->fft_dct); /** deleting buffers */ del_fvec(mf->in_dct); - del_cvec(mf->fftgrain_dct); /** deleting mfcc object */ AUBIO_FREE(mf); } -/** 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); - 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; - - aubio_dct_do(mf, mf->in_dct, out); - - return; -} - -void aubio_dct_do(aubio_mfcc_t * mf, fvec_t *in, fvec_t *out){ - uint_t i; - //compute mag spectrum - aubio_fft_do (mf->fft_dct, in, mf->fftgrain_dct); - //extract real part of fft grain - for(i=0; in_coefs ;i++){ - //for(i=0; ilength;i++){ - out->data[0][i]= mf->fftgrain_dct->norm[0][i] - *COS(mf->fftgrain_dct->phas[0][i]); + uint_t i, j; + // compute filterbank + aubio_filterbank_do(mf->fb, in, mf->in_dct); + + //extract real part of fft grain + for (i = 0; i < mf->n_filters; i++) { + for (j = 0; j < mf->n_coefs; j++) { + out->data[0][j] += mf->in_dct->data[0][i] + * mf->dct_coeffs->data[i][j]; } - return; -} + } + return; +} diff --git a/src/spectral/mfcc.h b/src/spectral/mfcc.h index 0c873c54..1a2cbda1 100644 --- a/src/spectral/mfcc.h +++ b/src/spectral/mfcc.h @@ -36,12 +36,9 @@ typedef struct aubio_mfcc_t_ aubio_mfcc_t; \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_filters, 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); /** delete mfcc object \param mf mfcc object as returned by new_aubio_mfcc