annotate src/init.c @ 52:45c585bb7996

Rationalised spectral data format. Added spectral_mean et al
author Jamie Bullock <jamie@postlude.co.uk>
date Wed, 10 Jan 2007 13:16:55 +0000
parents 4a36f70a76e9
children 450712b21565
rev   line source
jamie@1 1 /* libxtract feature extraction library
jamie@1 2 *
jamie@1 3 * Copyright (C) 2006 Jamie Bullock
jamie@1 4 *
jamie@1 5 * This program is free software; you can redistribute it and/or modify
jamie@1 6 * it under the terms of the GNU General Public License as published by
jamie@1 7 * the Free Software Foundation; either version 2 of the License, or
jamie@1 8 * (at your option) any later version.
jamie@1 9 *
jamie@1 10 * This program is distributed in the hope that it will be useful,
jamie@1 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
jamie@1 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
jamie@1 13 * GNU General Public License for more details.
jamie@1 14 *
jamie@1 15 * You should have received a copy of the GNU General Public License
jamie@1 16 * along with this program; if not, write to the Free Software
jamie@1 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
jamie@1 18 * USA.
jamie@1 19 */
jamie@1 20
jamie@1 21 /* init.c: defines functions that extract a feature as a single value from an input vector */
jamie@1 22
jamie@1 23 #include "xtract/libxtract.h"
jamie@1 24 #include <math.h>
jamie@26 25 #include <stdlib.h>
jamie@1 26
jamie@43 27 int xtract_init_mfcc(int N, float nyquist, int style, float freq_min, float freq_max, int freq_bands, float **fft_tables){
jamie@1 28
jamie@39 29 int n, i, k, *fft_peak, M, next_peak;
jamie@1 30 float norm, mel_freq_max, mel_freq_min, norm_fact, height, inc, val,
jamie@1 31 freq_bw_mel, *mel_peak, *height_norm, *lin_peak;
jamie@1 32
jamie@1 33 mel_peak = height_norm = lin_peak = NULL;
jamie@1 34 fft_peak = NULL;
jamie@1 35 norm = 1;
jamie@1 36
jamie@1 37 mel_freq_max = 1127 * log(1 + freq_max / 700);
jamie@1 38 mel_freq_min = 1127 * log(1 + freq_min / 700);
jamie@1 39 freq_bw_mel = (mel_freq_max - mel_freq_min) / freq_bands;
jamie@1 40
jamie@1 41 mel_peak = (float *)malloc((freq_bands + 2) * sizeof(float));
jamie@1 42 /* +2 for zeros at start and end */
jamie@1 43 lin_peak = (float *)malloc((freq_bands + 2) * sizeof(float));
jamie@1 44 fft_peak = (int *)malloc((freq_bands + 2) * sizeof(int));
jamie@1 45 height_norm = (float *)malloc(freq_bands * sizeof(float));
jamie@1 46
jamie@1 47 if(mel_peak == NULL || height_norm == NULL ||
jamie@1 48 lin_peak == NULL || fft_peak == NULL)
jamie@1 49 return MALLOC_FAILED;
jamie@39 50
jamie@1 51 M = N >> 1;
jamie@1 52
jamie@1 53 mel_peak[0] = mel_freq_min;
jamie@1 54 lin_peak[0] = 700 * (exp(mel_peak[0] / 1127) - 1);
jamie@1 55 fft_peak[0] = lin_peak[0] / nyquist * M;
jamie@1 56
jamie@1 57
jamie@1 58 for (n = 1; n <= freq_bands; n++){
jamie@1 59 /*roll out peak locations - mel, linear and linear on fft window scale */
jamie@1 60 mel_peak[n] = mel_peak[n - 1] + freq_bw_mel;
jamie@1 61 lin_peak[n] = 700 * (exp(mel_peak[n] / 1127) -1);
jamie@1 62 fft_peak[n] = lin_peak[n] / nyquist * M;
jamie@1 63 }
jamie@1 64
jamie@1 65 for (n = 0; n < freq_bands; n++){
jamie@1 66 /*roll out normalised gain of each peak*/
jamie@1 67 if (style == EQUAL_GAIN){
jamie@1 68 height = 1;
jamie@1 69 norm_fact = norm;
jamie@1 70 }
jamie@1 71 else{
jamie@1 72 height = 2 / (lin_peak[n + 2] - lin_peak[n]);
jamie@1 73 norm_fact = norm / (2 / (lin_peak[2] - lin_peak[0]));
jamie@1 74 }
jamie@1 75 height_norm[n] = height * norm_fact;
jamie@1 76 }
jamie@1 77
jamie@1 78 i = 0;
jamie@1 79
jamie@1 80 for(n = 0; n < freq_bands; n++){
jamie@39 81
jamie@39 82 /*calculate the rise increment*/
jamie@1 83 if(n > 0)
jamie@1 84 inc = height_norm[n] / (fft_peak[n] - fft_peak[n - 1]);
jamie@1 85 else
jamie@1 86 inc = height_norm[n] / fft_peak[n];
jamie@1 87 val = 0;
jamie@39 88
jamie@39 89 /*zero the start of the array*/
jamie@39 90 for(k = 0; k < i; k++)
jamie@39 91 fft_tables[n][k] = 0.f;
jamie@39 92
jamie@39 93 /*fill in the rise */
jamie@1 94 for(; i <= fft_peak[n]; i++){
jamie@1 95 fft_tables[n][i] = val;
jamie@1 96 val += inc;
jamie@1 97 }
jamie@39 98
jamie@39 99 /*calculate the fall increment */
jamie@1 100 inc = height_norm[n] / (fft_peak[n + 1] - fft_peak[n]);
jamie@39 101
jamie@1 102 val = 0;
jamie@39 103 next_peak = fft_peak[n + 1];
jamie@39 104
jamie@39 105 /*reverse fill the 'fall' */
jamie@39 106 for(i = next_peak; i > fft_peak[n]; i--){
jamie@1 107 fft_tables[n][i] = val;
jamie@1 108 val += inc;
jamie@1 109 }
jamie@39 110
jamie@39 111 /*zero the rest of the array*/
jamie@39 112 for(k = next_peak + 1; k < N; k++)
jamie@39 113 fft_tables[n][k] = 0.f;
jamie@1 114 }
jamie@1 115
jamie@1 116 free(mel_peak);
jamie@1 117 free(lin_peak);
jamie@1 118 free(height_norm);
jamie@1 119 free(fft_peak);
jamie@1 120
jamie@1 121 return SUCCESS;
jamie@1 122
jamie@1 123 }
jamie@1 124
jamie@1 125 int xtract_init_bark(int N, float nyquist, int *band_limits){
jamie@1 126
jamie@38 127 float 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)*/
jamie@1 128
jamie@1 129 int M, bands = BARK_BANDS;
jamie@1 130
jamie@1 131 M = N >> 1;
jamie@1 132
jamie@1 133 while(bands--)
jamie@1 134 band_limits[bands] = edges[bands] / nyquist * M;
jamie@1 135 /*FIX shohuld use rounding, but couldn't get it to work */
jamie@38 136
jamie@38 137 return SUCCESS;
jamie@1 138 }