annotate src/init.c @ 38:0ea4d6430cfc

Implemented xtract_harmonics
author Jamie Bullock <jamie@postlude.co.uk>
date Sat, 09 Dec 2006 15:21:35 +0000
parents 6417baefffc8
children 39c76f4db5b7
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@1 27 int xtract_init_mfcc(int N, float nyquist, int style, float freq_max, float freq_min, int freq_bands, float **fft_tables){
jamie@1 28
jamie@1 29 int n,i, *fft_peak, M;
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
jamie@1 34 mel_peak = height_norm = lin_peak = NULL;
jamie@1 35 fft_peak = NULL;
jamie@1 36 norm = 1;
jamie@1 37
jamie@1 38 mel_freq_max = 1127 * log(1 + freq_max / 700);
jamie@1 39 mel_freq_min = 1127 * log(1 + freq_min / 700);
jamie@1 40 freq_bw_mel = (mel_freq_max - mel_freq_min) / freq_bands;
jamie@1 41
jamie@1 42 mel_peak = (float *)malloc((freq_bands + 2) * sizeof(float));
jamie@1 43 /* +2 for zeros at start and end */
jamie@1 44 lin_peak = (float *)malloc((freq_bands + 2) * sizeof(float));
jamie@1 45 fft_peak = (int *)malloc((freq_bands + 2) * sizeof(int));
jamie@1 46 height_norm = (float *)malloc(freq_bands * sizeof(float));
jamie@1 47
jamie@1 48 if(mel_peak == NULL || height_norm == NULL ||
jamie@1 49 lin_peak == NULL || fft_peak == NULL)
jamie@1 50 return MALLOC_FAILED;
jamie@1 51
jamie@1 52 M = N >> 1;
jamie@1 53
jamie@1 54 mel_peak[0] = mel_freq_min;
jamie@1 55 lin_peak[0] = 700 * (exp(mel_peak[0] / 1127) - 1);
jamie@1 56 fft_peak[0] = lin_peak[0] / nyquist * M;
jamie@1 57
jamie@1 58
jamie@1 59 for (n = 1; n <= freq_bands; n++){
jamie@1 60 /*roll out peak locations - mel, linear and linear on fft window scale */
jamie@1 61 mel_peak[n] = mel_peak[n - 1] + freq_bw_mel;
jamie@1 62 lin_peak[n] = 700 * (exp(mel_peak[n] / 1127) -1);
jamie@1 63 fft_peak[n] = lin_peak[n] / nyquist * M;
jamie@1 64 }
jamie@1 65
jamie@1 66 for (n = 0; n < freq_bands; n++){
jamie@1 67 /*roll out normalised gain of each peak*/
jamie@1 68 if (style == EQUAL_GAIN){
jamie@1 69 height = 1;
jamie@1 70 norm_fact = norm;
jamie@1 71 }
jamie@1 72 else{
jamie@1 73 height = 2 / (lin_peak[n + 2] - lin_peak[n]);
jamie@1 74 norm_fact = norm / (2 / (lin_peak[2] - lin_peak[0]));
jamie@1 75 }
jamie@1 76 height_norm[n] = height * norm_fact;
jamie@1 77 }
jamie@1 78
jamie@1 79 i = 0;
jamie@1 80
jamie@1 81 for(n = 0; n < freq_bands; n++){
jamie@1 82 if(n > 0)
jamie@1 83 /*calculate the rise increment*/
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@1 88 for(; i <= fft_peak[n]; i++){
jamie@1 89 /*fill in the 'rise' */
jamie@1 90 fft_tables[n][i] = val;
jamie@1 91 val += inc;
jamie@1 92 }
jamie@1 93 inc = height_norm[n] / (fft_peak[n + 1] - fft_peak[n]);
jamie@1 94 /*calculate the fall increment */
jamie@1 95 val = 0;
jamie@1 96 for(i = fft_peak[n + 1]; i > fft_peak[n]; i--){
jamie@1 97 /*reverse fill the 'fall' */
jamie@1 98 fft_tables[n][i] = val;
jamie@1 99 val += inc;
jamie@1 100 }
jamie@1 101 }
jamie@1 102
jamie@1 103
jamie@1 104 free(mel_peak);
jamie@1 105 free(lin_peak);
jamie@1 106 free(height_norm);
jamie@1 107 free(fft_peak);
jamie@1 108
jamie@1 109 return SUCCESS;
jamie@1 110
jamie@1 111 }
jamie@1 112
jamie@1 113 int xtract_init_bark(int N, float nyquist, int *band_limits){
jamie@1 114
jamie@38 115 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 116
jamie@1 117 int M, bands = BARK_BANDS;
jamie@1 118
jamie@1 119 M = N >> 1;
jamie@1 120
jamie@1 121 while(bands--)
jamie@1 122 band_limits[bands] = edges[bands] / nyquist * M;
jamie@1 123 /*FIX shohuld use rounding, but couldn't get it to work */
jamie@38 124
jamie@38 125 return SUCCESS;
jamie@1 126 }