- Timestamp:
- Sep 8, 2007, 3:59:11 PM (17 years ago)
- Branches:
- feature/autosink, feature/cnn, feature/cnn_org, feature/constantq, feature/crepe, feature/crepe_org, feature/pitchshift, feature/pydocstrings, feature/timestretch, fix/ffmpeg5, master, pitchshift, sampler, timestretch, yinfft+
- Children:
- f14a78d
- Parents:
- 53a7576
- Location:
- src
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/filterbank.c
r53a7576 rb276dee 24 24 25 25 #include "aubio_priv.h" 26 #include "sample.h" 26 27 #include "filterbank.h" 28 29 #define USE_EQUAL_GAIN 1 30 #define VERY_SMALL_NUMBER 2e-42 27 31 28 32 /** \brief A structure to store a set of n_filters filters of lenghts win_s */ … … 30 34 uint_t win_s; 31 35 uint_t n_filters; 32 fvec_t * filters;36 fvec_t **filters; 33 37 }; 34 38 … … 41 45 42 46 /** allocating filter tables */ 43 fb->filters=AUBIO_ARRAY( n_filters,fvec_t);47 fb->filters=AUBIO_ARRAY(fvec_t*,n_filters); 44 48 for (filter_cnt=0; filter_cnt<n_filters; filter_cnt++) 45 49 /* considering one-channel filters */ 46 filters[filter_cnt]=new_fvec(win_s, 1); 50 fb->filters[filter_cnt]=new_fvec(win_s, 1); 51 52 return fb; 53 } 54 55 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){ 56 smpl_t nyquist = samplerate/2.; 57 uint_t style = 1; 58 aubio_filterbank_t * fb = new_aubio_filterbank(n_filters, win_s); 59 60 uint_t n, i, k, *fft_peak, M, next_peak; 61 smpl_t norm, mel_freq_max, mel_freq_min, norm_fact, height, inc, val, 62 freq_bw_mel, *mel_peak, *height_norm, *lin_peak; 63 64 mel_peak = height_norm = lin_peak = NULL; 65 fft_peak = NULL; 66 norm = 1; 67 68 mel_freq_max = 1127 * log(1 + freq_max / 700); 69 mel_freq_min = 1127 * log(1 + freq_min / 700); 70 freq_bw_mel = (mel_freq_max - mel_freq_min) / fb->n_filters; 71 72 mel_peak = (smpl_t *)malloc((fb->n_filters + 2) * sizeof(smpl_t)); 73 /* +2 for zeros at start and end */ 74 lin_peak = (smpl_t *)malloc((fb->n_filters + 2) * sizeof(smpl_t)); 75 fft_peak = (uint_t *)malloc((fb->n_filters + 2) * sizeof(uint_t)); 76 height_norm = (smpl_t *)malloc(fb->n_filters * sizeof(smpl_t)); 77 78 if(mel_peak == NULL || height_norm == NULL || 79 lin_peak == NULL || fft_peak == NULL) 80 return NULL; 81 82 M = fb->win_s >> 1; 83 84 mel_peak[0] = mel_freq_min; 85 lin_peak[0] = 700 * (exp(mel_peak[0] / 1127) - 1); 86 fft_peak[0] = lin_peak[0] / nyquist * M; 87 88 89 for (n = 1; n <= fb->n_filters; n++){ 90 /*roll out peak locations - mel, linear and linear on fft window scale */ 91 mel_peak[n] = mel_peak[n - 1] + freq_bw_mel; 92 lin_peak[n] = 700 * (exp(mel_peak[n] / 1127) -1); 93 fft_peak[n] = lin_peak[n] / nyquist * M; 94 } 95 96 for (n = 0; n < fb->n_filters; n++){ 97 /*roll out normalised gain of each peak*/ 98 if (style == USE_EQUAL_GAIN){ 99 height = 1; 100 norm_fact = norm; 101 } 102 else{ 103 height = 2 / (lin_peak[n + 2] - lin_peak[n]); 104 norm_fact = norm / (2 / (lin_peak[2] - lin_peak[0])); 105 } 106 height_norm[n] = height * norm_fact; 107 } 108 109 i = 0; 110 111 for(n = 0; n < fb->n_filters; n++){ 112 113 /*calculate the rise increment*/ 114 if(n > 0) 115 inc = height_norm[n] / (fft_peak[n] - fft_peak[n - 1]); 116 else 117 inc = height_norm[n] / fft_peak[n]; 118 val = 0; 119 120 /*zero the start of the array*/ 121 for(k = 0; k < i; k++) 122 //fft_tables[n][k] = 0.f; 123 fb->filters[n]->data[0][k]=0.f; 124 125 /*fill in the rise */ 126 for(; i <= fft_peak[n]; i++){ 127 // fft_tables[n][i] = val; 128 fb->filters[n]->data[0][k]=val; 129 val += inc; 130 } 131 132 /*calculate the fall increment */ 133 inc = height_norm[n] / (fft_peak[n + 1] - fft_peak[n]); 134 135 val = 0; 136 next_peak = fft_peak[n + 1]; 137 138 /*reverse fill the 'fall' */ 139 for(i = next_peak; i > fft_peak[n]; i--){ 140 //fft_tables[n][i] = val; 141 fb->filters[n]->data[0][k]=val; 142 val += inc; 143 } 144 145 /*zero the rest of the array*/ 146 for(k = next_peak + 1; k < fb->win_s; k++) 147 //fft_tables[n][k] = 0.f; 148 fb->filters[n]->data[0][k]=0.f; 149 } 150 151 free(mel_peak); 152 free(lin_peak); 153 free(height_norm); 154 free(fft_peak); 155 156 return fb; 47 157 48 158 } 49 159 160 50 161 void del_aubio_filterbank(aubio_filterbank_t * fb){ 51 52 int filter_cnt; 162 uint_t filter_cnt; 53 163 /** deleting filter tables first */ 54 164 for (filter_cnt=0; filter_cnt<fb->n_filters; filter_cnt++) … … 56 166 AUBIO_FREE(fb->filters); 57 167 AUBIO_FREE(fb); 58 59 168 } 60 169 170 void aubio_filterbank_do(aubio_filterbank_t * f, cvec_t * in, fvec_t *out) { 171 uint_t n, filter_cnt; 172 for(filter_cnt = 0; filter_cnt < f->n_filters; filter_cnt++){ 173 out->data[0][filter_cnt] = 0.f; 174 for(n = 0; n < f->win_s; n++){ 175 out->data[0][filter_cnt] += in->norm[0][n] 176 * f->filters[filter_cnt]->data[0][n]; 177 } 178 out->data[0][filter_cnt] = 179 LOG(out->data[0][filter_cnt] < VERY_SMALL_NUMBER ? 180 VERY_SMALL_NUMBER : out->data[0][filter_cnt]); 181 } 182 183 return; 184 } -
src/filterbank.h
r53a7576 rb276dee 44 44 aubio_filterbank_t * new_aubio_filterbank(uint_t n_filters, uint_t win_s); 45 45 46 /** filterbank initialization for mel filters 47 48 \param nyquist nyquist frequency, i.e. half of the sampling rate 49 \param style libxtract style 50 \param freqmin lowest filter frequency 51 \param freqmax highest filter frequency 52 53 */ 54 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); 55 56 46 57 /** destroy filterbank object 47 58 … … 51 62 void del_aubio_filterbank(aubio_filterbank_t * fb); 52 63 53 /** filterbank initialization for mel filters 54 55 \param fb filterbank, as returned by new_aubio_filterbank method 56 \param nyquist nyquist frequency, i.e. half of the sampling rate 57 \param style libxtract style 58 \param freqmin lowest filter frequency 59 \param freqmax highest filter frequency 64 /** compute filterbank 60 65 61 66 */ 62 void aubio_filterbank_mfcc_init(aubio_filterbank_t * fb, smpl_t nyquist, int style, smpl_t freq_min, smpl_t freq_max); 63 64 // Initialization 65 66 /** \brief A function to initialise a mel filter bank 67 * 68 * It is up to the caller to pass in a pointer to memory allocated for freq_bands arrays of length N. This function populates these arrays with magnitude coefficients representing the mel filterbank on a linear scale 69 */ 70 int aubio_mfcc_init(int N, smpl_t nyquist, int style, smpl_t freq_min, smpl_t freq_max, int freq_bands, smpl_t ** fft_tables); 67 void aubio_filterbank_do(aubio_filterbank_t * fb, cvec_t * in, fvec_t *out); 71 68 72 69 #ifdef __cplusplus -
src/mfcc.c
r53a7576 rb276dee 28 28 #include "math.h" 29 29 30 #define VERY_SMALL_NUMBER 2e-4231 #define USE_EQUAL_GAIN 132 33 34 30 /** Internal structure for mfcc object **/ 35 31 … … 48 44 49 45 50 /** filterbank initialization for mel filters51 52 \param fb filterbank, as returned by new_aubio_filterbank method53 \param nyquist nyquist frequency, i.e. half of the sampling rate54 \param style libxtract style55 \param freqmin lowest filter frequency56 \param freqmax highest filter frequency57 58 */59 void aubio_filterbank_mfcc_init(aubio_filterbank_t * fb, smpl_t nyquist, int style, smpl_t freq_min, smpl_t freq_max);60 61 46 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){ 62 47 /** allocating space for mfcc object */ … … 74 59 75 60 /** filterbank allocation */ 76 mfcc->fb = new_aubio_filterbank (n_filters, mfcc->win_s);61 mfcc->fb = new_aubio_filterbank_mfcc(n_filters, mfcc->win_s, samplerate, lowfreq, highfreq); 77 62 78 63 /** allocating space for fft object (used for dct) */ 79 mfcc->fft_dct=new_aubio_mfft( mfcc->win_s, 1);64 mfcc->fft_dct=new_aubio_mfft(n_filters, 1); 80 65 81 66 /** allocating buffers */ … … 83 68 84 69 mfcc->fftgrain_dct=new_cvec(n_filters, 1); 85 86 /** populating the filterbank */87 aubio_filterbank_mfcc_init(mfcc->fb, (mfcc->samplerate)/2, mfcc->lowfreq, mfcc->highfreq);88 70 89 71 return mfcc; … … 104 86 105 87 void aubio_mfcc_do(aubio_mfcc_t * mf, cvec_t *in, fvec_t *out){ 106 107 aubio_filterbank_t *f = mf->fb; 108 uint_t n, filter_cnt; 109 110 for(filter_cnt = 0; filter_cnt < f->n_filters; filter_cnt++){ 111 mf->in_dct->data[0][filter_cnt] = 0.f; 112 for(n = 0; n < mf->win_s; n++){ 113 mf->in_dct->data[0][filter_cnt] += in->norm[0][n] * f->filters[filter_cnt]->data[0][n]; 114 } 115 mf->in_dct->data[0][filter_cnt] = LOG(mf->in_dct->data[0][filter_cnt] < VERY_SMALL_NUMBER ? VERY_SMALL_NUMBER : mf->in_dct->data[0][filter_cnt]); 116 } 117 88 // compute filterbank 89 aubio_filterbank_do(mf->fb, in, mf->in_dct); 118 90 //TODO: check that zero padding 119 91 // the following line seems useless since the in_dct buffer has the correct size … … 126 98 127 99 void aubio_dct_do(aubio_mfcc_t * mf, fvec_t *in, fvec_t *out){ 100 uint_t i; 128 101 //compute mag spectrum 129 102 aubio_mfft_do (mf->fft_dct, in, mf->fftgrain_dct); 130 131 int i;132 103 //extract real part of fft grain 133 for(i=0; i<mf->n_coefs ;i++){ 134 out->data[0][i]= mf->fftgrain_dct->norm[0][i]*COS(mf->fftgrain_dct->phas[0][i]); 104 //for(i=0; i<mf->n_coefs ;i++){ 105 for(i=0; i<out->length;i++){ 106 out->data[0][i]= mf->fftgrain_dct->norm[0][i] 107 *COS(mf->fftgrain_dct->phas[0][i]); 135 108 } 136 137 109 return; 138 110 } 139 111 140 void aubio_filterbank_mfcc_init(aubio_filterbank_t * fb, smpl_t nyquist, int style, smpl_t freq_min, smpl_t freq_max){141 142 int n, i, k, *fft_peak, M, next_peak;143 smpl_t norm, mel_freq_max, mel_freq_min, norm_fact, height, inc, val,144 freq_bw_mel, *mel_peak, *height_norm, *lin_peak;145 146 mel_peak = height_norm = lin_peak = NULL;147 fft_peak = NULL;148 norm = 1;149 150 mel_freq_max = 1127 * log(1 + freq_max / 700);151 mel_freq_min = 1127 * log(1 + freq_min / 700);152 freq_bw_mel = (mel_freq_max - mel_freq_min) / fb->n_filters;153 154 mel_peak = (smpl_t *)malloc((fb->n_filters + 2) * sizeof(smpl_t));155 /* +2 for zeros at start and end */156 lin_peak = (smpl_t *)malloc((fb->n_filters + 2) * sizeof(smpl_t));157 fft_peak = (int *)malloc((fb->n_filters + 2) * sizeof(int));158 height_norm = (smpl_t *)malloc(fb->n_filters * sizeof(smpl_t));159 160 if(mel_peak == NULL || height_norm == NULL ||161 lin_peak == NULL || fft_peak == NULL)162 return NULL;163 164 M = fb->win_s >> 1;165 166 mel_peak[0] = mel_freq_min;167 lin_peak[0] = 700 * (exp(mel_peak[0] / 1127) - 1);168 fft_peak[0] = lin_peak[0] / nyquist * M;169 170 171 for (n = 1; n <= fb->n_filters; n++){172 /*roll out peak locations - mel, linear and linear on fft window scale */173 mel_peak[n] = mel_peak[n - 1] + freq_bw_mel;174 lin_peak[n] = 700 * (exp(mel_peak[n] / 1127) -1);175 fft_peak[n] = lin_peak[n] / nyquist * M;176 }177 178 for (n = 0; n < fb->n_filters; n++){179 /*roll out normalised gain of each peak*/180 if (style == USE_EQUAL_GAIN){181 height = 1;182 norm_fact = norm;183 }184 else{185 height = 2 / (lin_peak[n + 2] - lin_peak[n]);186 norm_fact = norm / (2 / (lin_peak[2] - lin_peak[0]));187 }188 height_norm[n] = height * norm_fact;189 }190 191 i = 0;192 193 for(n = 0; n < fb->n_filters; n++){194 195 /*calculate the rise increment*/196 if(n > 0)197 inc = height_norm[n] / (fft_peak[n] - fft_peak[n - 1]);198 else199 inc = height_norm[n] / fft_peak[n];200 val = 0;201 202 /*zero the start of the array*/203 for(k = 0; k < i; k++)204 //fft_tables[n][k] = 0.f;205 fb->filters[n]->data[0][k]=0.f;206 207 /*fill in the rise */208 for(; i <= fft_peak[n]; i++){209 // fft_tables[n][i] = val;210 fb->filters[n]->data[0][k]=val;211 val += inc;212 }213 214 /*calculate the fall increment */215 inc = height_norm[n] / (fft_peak[n + 1] - fft_peak[n]);216 217 val = 0;218 next_peak = fft_peak[n + 1];219 220 /*reverse fill the 'fall' */221 for(i = next_peak; i > fft_peak[n]; i--){222 //fft_tables[n][i] = val;223 fb->filters[n]->data[0][k]=val;224 val += inc;225 }226 227 /*zero the rest of the array*/228 for(k = next_peak + 1; k < fb->win_s; k++)229 //fft_tables[n][k] = 0.f;230 fb->filters[n]->data[0][k]=0.f;231 }232 233 free(mel_peak);234 free(lin_peak);235 free(height_norm);236 free(fft_peak);237 238 }239 -
src/mfcc.h
r53a7576 rb276dee 30 30 #endif 31 31 32 #include "sample.h" 32 33 #include "filterbank.h" 33 34
Note: See TracChangeset
for help on using the changeset viewer.