src/spectral/filterbank_mel.c: move Slaney's specific code to _slaney function
[aubio.git] / src / spectral / mfcc.c
1 /*
2    Copyright (C) 2006 Amaury Hazan
3    Ported to aubio from LibXtract
4    http://libxtract.sourceforge.net/
5    
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 */
22
23 #include "aubio_priv.h"
24 #include "fvec.h"
25 #include "cvec.h"
26 #include "spectral/fft.h"
27 #include "spectral/filterbank_mel.h"
28 #include "spectral/mfcc.h"
29
30 /** Internal structure for mfcc object **/
31
32 struct aubio_mfcc_t_{
33   uint_t win_s;             /** grain length */
34   uint_t samplerate;        /** sample rate (needed?) */
35   uint_t channels;          /** number of channels */
36   uint_t n_filters;         /** number of  *filters */
37   uint_t n_coefs;           /** number of coefficients (<= n_filters/2 +1) */
38   smpl_t lowfreq;           /** lowest frequency for filters */ 
39   smpl_t highfreq;          /** highest frequency for filters */
40   aubio_filterbank_t * fb;  /** filter bank */
41   fvec_t * in_dct;          /** input buffer for dct * [fb->n_filters] */
42   aubio_fft_t * fft_dct;   /** fft object for dct */
43   cvec_t * fftgrain_dct;    /** output buffer for dct */
44 };
45
46
47 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){
48   /** allocating space for mfcc object */
49   aubio_mfcc_t * mfcc = AUBIO_NEW(aubio_mfcc_t);
50
51   //we need (n_coefs-1)*2 filters to obtain n_coefs coefficients after dct
52   //uint_t n_filters = (n_coefs-1)*2;
53   
54   mfcc->win_s=win_s;
55   mfcc->samplerate=samplerate;
56   mfcc->channels=channels;
57   mfcc->n_filters=n_filters;
58   mfcc->n_coefs=n_coefs;
59   mfcc->lowfreq=lowfreq;
60   mfcc->highfreq=highfreq;
61
62   
63   /** filterbank allocation */
64   mfcc->fb = new_aubio_filterbank(n_filters, mfcc->win_s);
65   aubio_filterbank_set_mel_coeffs_slaney(mfcc->fb, samplerate);
66
67   /** allocating space for fft object (used for dct) */
68   mfcc->fft_dct=new_aubio_fft(n_filters, 1);
69
70   /** allocating buffers */
71   mfcc->in_dct=new_fvec(mfcc->win_s, 1);
72   
73   mfcc->fftgrain_dct=new_cvec(n_filters, 1);
74
75   return mfcc;
76 };
77
78 void del_aubio_mfcc(aubio_mfcc_t *mf){
79   /** deleting filterbank */
80   del_aubio_filterbank(mf->fb);
81   /** deleting fft object */
82   del_aubio_fft(mf->fft_dct);
83   /** deleting buffers */
84   del_fvec(mf->in_dct);
85   del_cvec(mf->fftgrain_dct);
86   
87   /** deleting mfcc object */
88   AUBIO_FREE(mf);
89 }
90
91
92 /** intermediate dct involved in aubio_mfcc_do
93
94   \param mf mfcc object as returned by new_aubio_mfcc
95   \param in input spectrum (n_filters long)
96   \param out output mel coefficients buffer (n_filters/2 +1 long)
97
98 */
99 void aubio_dct_do(aubio_mfcc_t * mf, fvec_t *in, fvec_t *out);
100
101 void aubio_mfcc_do(aubio_mfcc_t * mf, cvec_t *in, fvec_t *out){
102     // compute filterbank
103     aubio_filterbank_do(mf->fb, in, mf->in_dct);
104     //TODO: check that zero padding 
105     // the following line seems useless since the in_dct buffer has the correct size
106     //for(n = filter + 1; n < N; n++) result[n] = 0; 
107     
108     aubio_dct_do(mf, mf->in_dct, out);
109
110     return;
111 }
112
113 void aubio_dct_do(aubio_mfcc_t * mf, fvec_t *in, fvec_t *out){
114     uint_t i;
115     //compute mag spectrum
116     aubio_fft_do (mf->fft_dct, in, mf->fftgrain_dct);
117     //extract real part of fft grain
118     for(i=0; i<mf->n_coefs ;i++){
119     //for(i=0; i<out->length;i++){
120       out->data[0][i]= mf->fftgrain_dct->norm[0][i]
121         *COS(mf->fftgrain_dct->phas[0][i]);
122     }
123     return;
124 }
125