[88199ce] | 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 | |
---|
[7c6c806d] | 23 | #include "aubio_priv.h" |
---|
| 24 | #include "sample.h" |
---|
| 25 | #include "fft.h" |
---|
[8708556] | 26 | #include "filterbank.h" |
---|
[7c6c806d] | 27 | #include "mfcc.h" |
---|
| 28 | #include "math.h" |
---|
[88199ce] | 29 | |
---|
| 30 | |
---|
[7c6c806d] | 31 | |
---|
[8708556] | 32 | /** Internal structure for mfcc object **/ |
---|
[88199ce] | 33 | |
---|
[8708556] | 34 | struct aubio_mfcc_t_{ |
---|
[7c6c806d] | 35 | |
---|
[8708556] | 36 | /** grain length */ |
---|
| 37 | uint_t win_s; |
---|
| 38 | |
---|
| 39 | /** sample rate (needed?) */ |
---|
| 40 | uint_t samplerate; |
---|
[88199ce] | 41 | |
---|
[8708556] | 42 | /** number of channels */ |
---|
| 43 | uint_t channels; |
---|
| 44 | |
---|
| 45 | /** filter bank */ |
---|
| 46 | aubio_filterbank_t * fb; |
---|
[88199ce] | 47 | |
---|
[8708556] | 48 | /** number of coefficients (= fb->n_filters/2 +1) */ |
---|
| 49 | uint_t n_coefs; |
---|
| 50 | |
---|
| 51 | /** lowest frequency for filters */ |
---|
| 52 | smpl_t lowfreq; |
---|
| 53 | |
---|
| 54 | /** highest frequency for filters */ |
---|
| 55 | smpl_t highfreq; |
---|
| 56 | |
---|
| 57 | /** input buffer for dct * [fb->n_filters] */ |
---|
| 58 | fvec_t * in_dct; |
---|
| 59 | |
---|
| 60 | /** fft object for dct */ |
---|
| 61 | aubio_mfft_t * fft_dct; |
---|
| 62 | |
---|
| 63 | /** output buffer for dct */ |
---|
| 64 | cvec_t * fftgrain_dct; |
---|
| 65 | |
---|
| 66 | }; |
---|
| 67 | |
---|
| 68 | |
---|
| 69 | aubio_mfcc_t * new_aubio_mfcc (uint_t win_s, uint_t samplerate ,uint_t n_coefs, smpl_t lowfreq, smpl_t highfreq, uint_t channels){ |
---|
| 70 | |
---|
| 71 | |
---|
| 72 | /** allocating space for mfcc object */ |
---|
| 73 | |
---|
| 74 | aubio_mfcc_t * mfcc = AUBIO_NEW(aubio_mfcc_t); |
---|
| 75 | |
---|
| 76 | mfcc->win_s=win_s; |
---|
| 77 | mfcc->samplerate=samplerate; |
---|
| 78 | mfcc->channels=channels; |
---|
| 79 | mfcc->n_coefs=n_coefs; |
---|
| 80 | mfcc->lowfreq=lowfreq; |
---|
| 81 | mfcc->highfreq=highfreq; |
---|
| 82 | |
---|
| 83 | /** filterbank allocation */ |
---|
| 84 | //we need (n_coefs-1)*2 filters to obtain n_coefs coefficients after dct |
---|
| 85 | mfcc->fb=new_aubio_filterbank((n_coefs-1)*2, mfcc->win_s); |
---|
| 86 | |
---|
| 87 | /** allocating space for fft object (used for dct) */ |
---|
| 88 | mfcc->fft_dct=new_aubio_mfft(mfcc->win_s, 1); |
---|
| 89 | |
---|
| 90 | /** allocating buffers */ |
---|
| 91 | |
---|
| 92 | mfcc->in_dct=new_fvec(mfcc->win_s, 1); |
---|
| 93 | |
---|
| 94 | mfcc->fftgrain_dct=new_cvec(mfcc->fb->n_filters, 1); |
---|
| 95 | |
---|
| 96 | /** populating the filterbank */ |
---|
| 97 | |
---|
| 98 | aubio_filterbank_mfcc_init(mfcc->fb, (mfcc->samplerate)/2, XTRACT_EQUAL_GAIN, mfcc->lowfreq, mfcc->highfreq); |
---|
| 99 | |
---|
| 100 | return mfcc; |
---|
| 101 | |
---|
| 102 | }; |
---|
| 103 | |
---|
| 104 | |
---|
| 105 | void del_aubio_mfcc(aubio_mfcc_t *mf){ |
---|
| 106 | |
---|
| 107 | /** deleting filterbank */ |
---|
| 108 | del_aubio_filterbank(mf->fb); |
---|
| 109 | /** deleting mfft object */ |
---|
| 110 | del_aubio_mfft(mf->fft_dct); |
---|
| 111 | /** deleting buffers */ |
---|
| 112 | del_fvec(mf->in_dct); |
---|
| 113 | del_cvec(mf->fftgrain_dct); |
---|
| 114 | |
---|
| 115 | /** deleting mfcc object */ |
---|
| 116 | AUBIO_FREE(mf); |
---|
| 117 | |
---|
| 118 | } |
---|
| 119 | |
---|
| 120 | |
---|
| 121 | // Computation |
---|
| 122 | |
---|
| 123 | void aubio_mfcc_do(aubio_mfcc_t * mf, cvec_t *in, fvec_t *out){ |
---|
| 124 | |
---|
| 125 | aubio_filterbank_t *f = mf->fb; |
---|
| 126 | uint_t n, filter_cnt; |
---|
| 127 | |
---|
| 128 | for(filter_cnt = 0; filter_cnt < f->n_filters; filter_cnt++){ |
---|
| 129 | mf->in_dct->data[0][filter_cnt] = 0.f; |
---|
| 130 | for(n = 0; n < mf->win_s; n++){ |
---|
| 131 | mf->in_dct->data[0][filter_cnt] += in->norm[0][n] * f->filters[filter_cnt]->data[0][n]; |
---|
[88199ce] | 132 | } |
---|
[8708556] | 133 | mf->in_dct->data[0][filter_cnt] = LOG(mf->in_dct->data[0][filter_cnt] < XTRACT_LOG_LIMIT ? XTRACT_LOG_LIMIT : mf->in_dct->data[0][filter_cnt]); |
---|
[88199ce] | 134 | } |
---|
| 135 | |
---|
[7c6c806d] | 136 | //TODO: check that zero padding |
---|
[8708556] | 137 | // the following line seems useless since the in_dct buffer has the correct size |
---|
| 138 | //for(n = filter + 1; n < N; n++) result[n] = 0; |
---|
[88199ce] | 139 | |
---|
[8708556] | 140 | aubio_dct_do(mf, mf->in_dct, out); |
---|
[88199ce] | 141 | |
---|
[8708556] | 142 | //return XTRACT_SUCCESS; |
---|
[88199ce] | 143 | } |
---|
| 144 | |
---|
[8708556] | 145 | void aubio_dct_do(aubio_mfcc_t * mf, fvec_t *in, fvec_t *out){ |
---|
[88199ce] | 146 | |
---|
[97886fa] | 147 | |
---|
[8708556] | 148 | |
---|
| 149 | //fvec_t * momo = new_fvec(20, 1); |
---|
| 150 | //momo->data = data; |
---|
[7c6c806d] | 151 | |
---|
[97886fa] | 152 | //compute mag spectrum |
---|
[8708556] | 153 | aubio_mfft_do (mf->fft_dct, in, mf->fftgrain_dct); |
---|
[97886fa] | 154 | |
---|
| 155 | int i; |
---|
| 156 | //extract real part of fft grain |
---|
[8708556] | 157 | for(i=0; i<mf->n_coefs ;i++){ |
---|
| 158 | out->data[0][i]= mf->fftgrain_dct->norm[0][i]*COS(mf->fftgrain_dct->phas[0][i]); |
---|
[97886fa] | 159 | } |
---|
[7c6c806d] | 160 | |
---|
[88199ce] | 161 | |
---|
[8708556] | 162 | //return XTRACT_SUCCESS; |
---|
[71d3bf0] | 163 | } |
---|
[8708556] | 164 | |
---|
| 165 | |
---|
| 166 | ///////// OLD CODE |
---|
| 167 | |
---|
| 168 | // int aubio_mfcc_do(const float *data, const int N, const void *argv, float *result, aubio_mfft_t * fft_dct, cvec_t * fftgrain_dct){ |
---|
| 169 | // |
---|
| 170 | // aubio_mel_filter *f; |
---|
| 171 | // uint_t n, filter; |
---|
| 172 | // |
---|
| 173 | // f = (aubio_mel_filter *)argv; |
---|
| 174 | // printf("%d",f->n_filters); |
---|
| 175 | // |
---|
| 176 | // for(filter = 0; filter < f->n_filters; filter++){ |
---|
| 177 | // result[filter] = 0.f; |
---|
| 178 | // for(n = 0; n < N; n++){ |
---|
| 179 | // result[filter] += data[n] * f->filters[filter][n]; |
---|
| 180 | // } |
---|
| 181 | // result[filter] = LOG(result[filter] < XTRACT_LOG_LIMIT ? XTRACT_LOG_LIMIT : result[filter]); |
---|
| 182 | // } |
---|
| 183 | // |
---|
| 184 | // //TODO: check that zero padding |
---|
| 185 | // for(n = filter + 1; n < N; n++) result[n] = 0; |
---|
| 186 | // |
---|
| 187 | // aubio_dct_do(result, f->n_filters, NULL, result, fft_dct, fftgrain_dct); |
---|
| 188 | // |
---|
| 189 | // return XTRACT_SUCCESS; |
---|
| 190 | // } |
---|
| 191 | |
---|
| 192 | // Added last two arguments to be able to pass from example |
---|
| 193 | |
---|
| 194 | // int aubio_dct_do(const float *data, const int N, const void *argv, float *result, aubio_mfft_t * fft_dct, cvec_t * fftgrain_dct){ |
---|
| 195 | // |
---|
| 196 | // |
---|
| 197 | // //call aubio p_voc in dct setting |
---|
| 198 | // |
---|
| 199 | // //TODO: fvec as input? Remove data length, N? |
---|
| 200 | // |
---|
| 201 | // fvec_t * momo = new_fvec(20, 1); |
---|
| 202 | // momo->data = data; |
---|
| 203 | // |
---|
| 204 | // //compute mag spectrum |
---|
| 205 | // aubio_mfft_do (fft_dct, data, fftgrain_dct); |
---|
| 206 | // |
---|
| 207 | // int i; |
---|
| 208 | // //extract real part of fft grain |
---|
| 209 | // for(i=0; i<N ;i++){ |
---|
| 210 | // result[i]= fftgrain_dct->norm[0][i]*COS(fftgrain_dct->phas[0][i]); |
---|
| 211 | // } |
---|
| 212 | // |
---|
| 213 | // |
---|
| 214 | // return XTRACT_SUCCESS; |
---|
| 215 | // } |
---|