diff options
author | Jamie Bullock <jamie@postlude.co.uk> | 2006-10-02 14:18:15 +0000 |
---|---|---|
committer | Jamie Bullock <jamie@postlude.co.uk> | 2006-10-02 14:18:15 +0000 |
commit | 6d00829a8ccef20c0ce7eeecc54cd3bb5f94b3bd (patch) | |
tree | 60022374029d12df117e549132637968e7dcca43 /src/init.c | |
parent | 0e94c12896dde9bb525a617ed680c6da82b2ed52 (diff) | |
download | LibXtract-6d00829a8ccef20c0ce7eeecc54cd3bb5f94b3bd.tar.gz LibXtract-6d00829a8ccef20c0ce7eeecc54cd3bb5f94b3bd.tar.bz2 LibXtract-6d00829a8ccef20c0ce7eeecc54cd3bb5f94b3bd.zip |
Initial import
Diffstat (limited to 'src/init.c')
-rw-r--r-- | src/init.c | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/src/init.c b/src/init.c new file mode 100644 index 0000000..5b7bdf2 --- /dev/null +++ b/src/init.c @@ -0,0 +1,124 @@ +/* libxtract feature extraction library + * + * Copyright (C) 2006 Jamie Bullock + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +/* init.c: defines functions that extract a feature as a single value from an input vector */ + +#include "xtract/libxtract.h" +#include <math.h> +#include <string.h> + +int xtract_init_mfcc(int N, float nyquist, int style, float freq_max, float freq_min, int freq_bands, float **fft_tables){ + + int n,i, *fft_peak, M; + float norm, mel_freq_max, mel_freq_min, norm_fact, height, inc, val, + freq_bw_mel, *mel_peak, *height_norm, *lin_peak; + + + mel_peak = height_norm = lin_peak = NULL; + fft_peak = NULL; + norm = 1; + + mel_freq_max = 1127 * log(1 + freq_max / 700); + mel_freq_min = 1127 * log(1 + freq_min / 700); + freq_bw_mel = (mel_freq_max - mel_freq_min) / freq_bands; + + mel_peak = (float *)malloc((freq_bands + 2) * sizeof(float)); + /* +2 for zeros at start and end */ + lin_peak = (float *)malloc((freq_bands + 2) * sizeof(float)); + fft_peak = (int *)malloc((freq_bands + 2) * sizeof(int)); + height_norm = (float *)malloc(freq_bands * sizeof(float)); + + if(mel_peak == NULL || height_norm == NULL || + lin_peak == NULL || fft_peak == NULL) + return MALLOC_FAILED; + + M = N >> 1; + + mel_peak[0] = mel_freq_min; + lin_peak[0] = 700 * (exp(mel_peak[0] / 1127) - 1); + fft_peak[0] = lin_peak[0] / nyquist * M; + + + for (n = 1; n <= freq_bands; n++){ + /*roll out peak locations - mel, linear and linear on fft window scale */ + mel_peak[n] = mel_peak[n - 1] + freq_bw_mel; + lin_peak[n] = 700 * (exp(mel_peak[n] / 1127) -1); + fft_peak[n] = lin_peak[n] / nyquist * M; + } + + for (n = 0; n < freq_bands; n++){ + /*roll out normalised gain of each peak*/ + if (style == EQUAL_GAIN){ + height = 1; + norm_fact = norm; + } + else{ + height = 2 / (lin_peak[n + 2] - lin_peak[n]); + norm_fact = norm / (2 / (lin_peak[2] - lin_peak[0])); + } + height_norm[n] = height * norm_fact; + } + + i = 0; + + for(n = 0; n < freq_bands; n++){ + if(n > 0) + /*calculate the rise increment*/ + inc = height_norm[n] / (fft_peak[n] - fft_peak[n - 1]); + else + inc = height_norm[n] / fft_peak[n]; + val = 0; + for(; i <= fft_peak[n]; i++){ + /*fill in the 'rise' */ + fft_tables[n][i] = val; + val += inc; + } + inc = height_norm[n] / (fft_peak[n + 1] - fft_peak[n]); + /*calculate the fall increment */ + val = 0; + for(i = fft_peak[n + 1]; i > fft_peak[n]; i--){ + /*reverse fill the 'fall' */ + fft_tables[n][i] = val; + val += inc; + } + } + + + free(mel_peak); + free(lin_peak); + free(height_norm); + free(fft_peak); + + return SUCCESS; + +} + +int xtract_init_bark(int N, float nyquist, int *band_limits){ + + float bark_freq_max, bark_freq_min, freq_bw_bark, temp, edges[] = {0, 100, 200, 300, 400, 510, 630, 770, 920, 1080, 1270, 1480, 1720, 2000, 2320, 2700, 3150, 3700, 4400, 5300, 6400, 7700, 9500, 12000, 15500, 20500, 27000}; /* Takes us up to sr = 54kHz (CCRMA: JOS)*/ + + int M, bands = BARK_BANDS; + + M = N >> 1; + + while(bands--) + band_limits[bands] = edges[bands] / nyquist * M; + /*FIX shohuld use rounding, but couldn't get it to work */ +} |