mfcc.c: use a coefficient table for DCT computation, remove unused parameters
authorPaul Brossier <piem@piem.org>
Thu, 17 Sep 2009 17:31:54 +0000 (19:31 +0200)
committerPaul Brossier <piem@piem.org>
Thu, 17 Sep 2009 17:31:54 +0000 (19:31 +0200)
src/spectral/mfcc.c
src/spectral/mfcc.h

index 8d83e705e777afaf8ecdad33dce360321bfb2511..01bf976479c20063e496cf37b8c73f0c16cacef4 100644 (file)
 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; 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]);
+  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;
+}
index 0c873c5414127d883eb6dd86fd4b07ce3687cb53..1a2cbda155d55461345ebb70db153822bb9e9765 100644 (file)
@@ -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