Changeset 06cae6c for src/spectral/filterbank.c
- Timestamp:
- Sep 17, 2009, 1:20:54 AM (15 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:
- 3b3b03e
- Parents:
- 7bf3dcb
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/spectral/filterbank.c
r7bf3dcb r06cae6c 1 1 /* 2 Copyright (C) 2007 Amaury Hazan <ahazan@iua.upf.edu>3 and Paul Brossier <piem@piem.org>2 Copyright (C) 2007-2009 Paul Brossier <piem@aubio.org> 3 and Amaury Hazan <ahazan@iua.upf.edu> 4 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. 5 This file is part of Aubio. 9 6 10 This program is distributed in the hope that it will be useful,11 but WITHOUT ANY WARRANTY; without even the implied warranty of12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13 GNU General Public License for more details.7 Aubio 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 3 of the License, or 10 (at your option) any later version. 14 11 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software 17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 12 Aubio 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 Aubio. If not, see <http://www.gnu.org/licenses/>. 18 19 19 20 */ 20 21 21 22 22 #include "aubio_priv.h" … … 32 32 uint_t win_s; 33 33 uint_t n_filters; 34 fvec_t * *filters;34 fvec_t *filters; 35 35 }; 36 36 37 37 aubio_filterbank_t * new_aubio_filterbank(uint_t n_filters, uint_t win_s){ 38 /* * allocatingspace for filterbank object */38 /* allocate space for filterbank object */ 39 39 aubio_filterbank_t * fb = AUBIO_NEW(aubio_filterbank_t); 40 uint_t filter_cnt;41 40 fb->win_s=win_s; 42 41 fb->n_filters=n_filters; 43 42 44 /** allocating filter tables */ 45 fb->filters=AUBIO_ARRAY(fvec_t*,n_filters); 46 for (filter_cnt=0; filter_cnt<n_filters; filter_cnt++) 47 /* considering one-channel filters */ 48 fb->filters[filter_cnt]=new_fvec(win_s, 1); 43 /* allocate filter tables, an fvec of length win_s and of filter_cnt channel */ 44 fb->filters = new_fvec(win_s, n_filters); 49 45 50 46 return fb; 51 47 } 52 48 53 /*54 FB initialization based on Slaney's auditory toolbox55 TODO:56 *solve memory leak problems while57 *solve quantization issues when constructing signal:58 *bug for win_s=51259 *corrections for win_s=1024 -> why even filters with smaller amplitude60 61 */62 63 aubio_filterbank_t * new_aubio_filterbank_mfcc(uint_t n_filters, uint_t win_s, uint_t samplerate, smpl_t freq_min, smpl_t freq_max){64 65 aubio_filterbank_t * fb = new_aubio_filterbank(n_filters, win_s);66 67 68 //slaney params69 smpl_t lowestFrequency = 133.3333;70 smpl_t linearSpacing = 66.66666666;71 smpl_t logSpacing = 1.0711703;72 73 uint_t linearFilters = 13;74 uint_t logFilters = 27;75 uint_t allFilters = linearFilters + logFilters;76 77 //buffers for computing filter frequencies78 fvec_t * freqs=new_fvec(allFilters+2 , 1);79 80 fvec_t * lower_freqs=new_fvec( allFilters, 1);81 fvec_t * upper_freqs=new_fvec( allFilters, 1);82 fvec_t * center_freqs=new_fvec( allFilters, 1);83 84 fvec_t * triangle_heights=new_fvec( allFilters, 1);85 //lookup table of each bin frequency in hz86 fvec_t * fft_freqs=new_fvec(win_s, 1);87 88 uint_t filter_cnt, bin_cnt;89 90 //first step: filling all the linear filter frequencies91 for(filter_cnt=0; filter_cnt<linearFilters; filter_cnt++){92 freqs->data[0][filter_cnt]=lowestFrequency+ filter_cnt*linearSpacing;93 }94 smpl_t lastlinearCF=freqs->data[0][filter_cnt-1];95 96 //second step: filling all the log filter frequencies97 for(filter_cnt=0; filter_cnt<logFilters+2; filter_cnt++){98 freqs->data[0][filter_cnt+linearFilters] =99 lastlinearCF*(pow(logSpacing,filter_cnt+1));100 }101 102 //Option 1. copying interesting values to lower_freqs, center_freqs and upper freqs arrays103 //TODO: would be nicer to have a reference to freqs->data, anyway we do not care in this init step104 105 for(filter_cnt=0; filter_cnt<allFilters; filter_cnt++){106 lower_freqs->data[0][filter_cnt]=freqs->data[0][filter_cnt];107 center_freqs->data[0][filter_cnt]=freqs->data[0][filter_cnt+1];108 upper_freqs->data[0][filter_cnt]=freqs->data[0][filter_cnt+2];109 }110 111 //computing triangle heights so that each triangle has unit area112 for(filter_cnt=0; filter_cnt<allFilters; filter_cnt++){113 triangle_heights->data[0][filter_cnt] = 2./(upper_freqs->data[0][filter_cnt]114 - lower_freqs->data[0][filter_cnt]);115 }116 117 //AUBIO_DBG("filter tables frequencies\n");118 //for(filter_cnt=0; filter_cnt<allFilters; filter_cnt++)119 // AUBIO_DBG("filter n. %d %f %f %f %f\n",120 // filter_cnt, lower_freqs->data[0][filter_cnt],121 // center_freqs->data[0][filter_cnt], upper_freqs->data[0][filter_cnt],122 // triangle_heights->data[0][filter_cnt]);123 124 //filling the fft_freqs lookup table, which assigns the frequency in hz to each bin125 for(bin_cnt=0; bin_cnt<win_s; bin_cnt++){126 fft_freqs->data[0][bin_cnt]= aubio_bintofreq(bin_cnt, samplerate, win_s);127 }128 129 //building each filter table130 for(filter_cnt=0; filter_cnt<allFilters; filter_cnt++){131 132 //TODO:check special case : lower freq =0133 //calculating rise increment in mag/Hz134 smpl_t riseInc= triangle_heights->data[0][filter_cnt]/(center_freqs->data[0][filter_cnt]-lower_freqs->data[0][filter_cnt]);135 136 //zeroing begining of filter137 for(bin_cnt=0; bin_cnt<win_s-1; bin_cnt++){138 fb->filters[filter_cnt]->data[0][bin_cnt]=0.f;139 if( fft_freqs->data[0][bin_cnt] <= lower_freqs->data[0][filter_cnt] &&140 fft_freqs->data[0][bin_cnt+1] > lower_freqs->data[0][filter_cnt]) {141 break;142 }143 }144 bin_cnt++;145 146 //positive slope147 for(; bin_cnt<win_s-1; bin_cnt++){148 fb->filters[filter_cnt]->data[0][bin_cnt]=(fft_freqs->data[0][bin_cnt]-lower_freqs->data[0][filter_cnt])*riseInc;149 //if(fft_freqs->data[0][bin_cnt]<= center_freqs->data[0][filter_cnt] && fft_freqs->data[0][bin_cnt+1]> center_freqs->data[0][filter_cnt])150 if(fft_freqs->data[0][bin_cnt+1]> center_freqs->data[0][filter_cnt])151 break;152 }153 //bin_cnt++;154 155 //negative slope156 for(; bin_cnt<win_s-1; bin_cnt++){157 158 //checking whether last value is less than 0...159 smpl_t val=triangle_heights->data[0][filter_cnt]-(fft_freqs->data[0][bin_cnt]-center_freqs->data[0][filter_cnt])*riseInc;160 if(val>=0)161 fb->filters[filter_cnt]->data[0][bin_cnt]=val;162 else fb->filters[filter_cnt]->data[0][bin_cnt]=0.f;163 164 //if(fft_freqs->data[0][bin_cnt]<= upper_freqs->data[0][bin_cnt] && fft_freqs->data[0][bin_cnt+1]> upper_freqs->data[0][filter_cnt])165 //TODO: CHECK whether bugfix correct166 if(fft_freqs->data[0][bin_cnt+1]> upper_freqs->data[0][filter_cnt])167 break;168 }169 //bin_cnt++;170 171 //zeroing tail172 for(; bin_cnt<win_s; bin_cnt++)173 fb->filters[filter_cnt]->data[0][bin_cnt]=0.f;174 175 }176 177 178 del_fvec(freqs);179 del_fvec(lower_freqs);180 del_fvec(upper_freqs);181 del_fvec(center_freqs);182 183 del_fvec(triangle_heights);184 del_fvec(fft_freqs);185 186 return fb;187 188 }189 190 49 void del_aubio_filterbank(aubio_filterbank_t * fb){ 191 uint_t filter_cnt; 192 /** deleting filter tables first */ 193 for (filter_cnt=0; filter_cnt<fb->n_filters; filter_cnt++) 194 del_fvec(fb->filters[filter_cnt]); 195 AUBIO_FREE(fb->filters); 50 del_fvec(fb->filters); 196 51 AUBIO_FREE(fb); 197 52 } 198 53 199 54 void aubio_filterbank_do(aubio_filterbank_t * f, cvec_t * in, fvec_t *out) { 200 uint_t n, filter_cnt; 201 for(filter_cnt = 0; (filter_cnt < f->n_filters) 202 && (filter_cnt < out->length); filter_cnt++){ 203 out->data[0][filter_cnt] = 0.f; 204 for(n = 0; n < in->length; n++){ 205 out->data[0][filter_cnt] += in->norm[0][n] 206 * f->filters[filter_cnt]->data[0][n]; 55 uint_t i, j, fn; 56 57 /* apply filter to all input channel, provided out has enough channels */ 58 uint_t max_channels = MIN(in->channels, out->channels); 59 uint_t max_filters = MIN(f->n_filters, out->length); 60 61 /* reset all values in output vector */ 62 fvec_zeros(out); 63 64 /* apply filters on all channels */ 65 for (i = 0; i < max_channels; i++) { 66 67 /* for each filter */ 68 for(fn = 0; fn < max_filters; fn++) { 69 70 /* for each sample */ 71 for(j = 0; j < in->length; j++) { 72 out->data[i][fn] += in->norm[i][j] * f->filters->data[fn][j]; 207 73 } 208 out->data[0][filter_cnt] = 209 LOG(out->data[0][filter_cnt] < VERY_SMALL_NUMBER ? 210 VERY_SMALL_NUMBER : out->data[0][filter_cnt]); 74 75 /* threshold to VERY_SMALL_NUMBER to avoid log oveflow */ 76 out->data[i][fn] = MAX(VERY_SMALL_NUMBER, out->data[i][fn]); 77 78 /* compute logarithm */ 79 out->data[i][fn] = LOG(out->data[i][fn]); 80 } 211 81 } 212 82 … … 214 84 } 215 85 216 fvec_t * aubio_filterbank_getchannel(aubio_filterbank_t * f, uint_t channel) { 217 if ( (channel < f->n_filters) ) { return f->filters[channel]; } 218 else { return NULL; } 86 fvec_t * aubio_filterbank_get_coeffs(aubio_filterbank_t * f) { 87 return f->filters; 219 88 }
Note: See TracChangeset
for help on using the changeset viewer.