annotate src/vector.c @ 6:3977eb18153b

Fixed AMDF
author Jamie Bullock <jamie@postlude.co.uk>
date Thu, 05 Oct 2006 17:02:33 +0000
parents b8f2448f7207
children 4df9012cebf1
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
jamie@1 22 /* xtract_vector.c: defines functions that extract a feature as a single value from an input vector */
jamie@1 23
jamie@1 24 #include "xtract/libxtract.h"
jamie@1 25 #include <math.h>
jamie@1 26 #include <fftw3.h>
jamie@1 27
jamie@1 28 int xtract_magnitude_spectrum(float *data, int N, void *argv, float *result){
jamie@1 29
jamie@1 30 float *temp;
jamie@1 31 int n , M = N >> 1;
jamie@1 32 fftwf_plan plan;
jamie@1 33
jamie@1 34 temp = (float *)fftwf_malloc(N * sizeof(float));
jamie@1 35
jamie@1 36 plan = fftwf_plan_r2r_1d(N, data, temp, FFTW_R2HC, FFTW_ESTIMATE);
jamie@1 37
jamie@1 38 fftwf_execute(plan);
jamie@1 39
jamie@1 40 for(n = 1; n < M; n++){
jamie@1 41 result[n] = sqrt(SQ(temp[n]) + SQ(temp[N - n])) / N;
jamie@1 42 result[N-n] = 0.0f;
jamie@1 43 }
jamie@1 44
jamie@1 45 result[0] = fabs(temp[0]) / N;
jamie@1 46 result[M] = fabs(temp[M]) / N;
jamie@1 47
jamie@1 48 fftwf_destroy_plan(plan);
jamie@1 49 fftwf_free(temp);
jamie@1 50
jamie@1 51 }
jamie@1 52
jamie@1 53 int xtract_autocorrelation(float *data, int N, void *argv, float *result){
jamie@1 54
jamie@1 55 /* Naive time domain implementation */
jamie@1 56
jamie@1 57 int n = N, i;
jamie@1 58
jamie@1 59 float corr;
jamie@1 60
jamie@1 61 while(n--){
jamie@1 62 corr = 0;
jamie@1 63 for(i = 0; i < N - n; i++){
jamie@1 64 corr += data[i] * data[i + n];
jamie@1 65 }
jamie@1 66 result[n] = corr / N;
jamie@1 67 }
jamie@1 68 }
jamie@1 69
jamie@1 70 int xtract_autocorrelation_fft(float *data, int N, void *argv, float *result){
jamie@1 71
jamie@1 72 float *temp;
jamie@1 73 int n;
jamie@1 74 fftwf_plan plan;
jamie@1 75
jamie@1 76 temp = (float *)fftwf_malloc(N * sizeof(float));
jamie@1 77 plan = fftwf_plan_r2r_1d(N, data, temp, FFTW_HC2R, FFTW_ESTIMATE);
jamie@1 78
jamie@1 79 fftwf_execute(plan);
jamie@1 80
jamie@1 81 for(n = 0; n < N - 1; n++)
jamie@1 82 result[n] = temp[n+1];
jamie@1 83
jamie@1 84 fftwf_destroy_plan(plan);
jamie@1 85 fftwf_free(temp);
jamie@1 86 }
jamie@1 87
jamie@1 88 int xtract_amdf(float *data, int N, void *argv, float *result){
jamie@1 89
jamie@1 90 int n = N, i;
jamie@1 91
jamie@6 92 float md, temp;
jamie@1 93
jamie@1 94 while(n--){
jamie@1 95 md = 0;
jamie@1 96 for(i = 0; i < N - n; i++){
jamie@6 97 temp = data[i] - data[i + n];
jamie@6 98 temp = (temp < 0 ? -temp : temp);
jamie@6 99 md += temp;
jamie@1 100 }
jamie@1 101 result[n] = md / N;
jamie@1 102 }
jamie@1 103 }
jamie@1 104
jamie@1 105 int xtract_asdf(float *data, int N, void *argv, float *result){
jamie@1 106
jamie@1 107 int n = N, i;
jamie@1 108
jamie@1 109 float sd;
jamie@1 110
jamie@1 111 while(n--){
jamie@1 112 sd = 0;
jamie@1 113 for(i = 0; i < N - n; i++){
jamie@6 114 /*sd = 1;*/
jamie@1 115 sd += SQ(data[i] - data[i + n]);
jamie@1 116 }
jamie@1 117 result[n] = sd / N;
jamie@1 118 }
jamie@1 119 }
jamie@1 120
jamie@1 121 int xtract_mfcc(float *data, int N, void *argv, float *result){
jamie@1 122
jamie@1 123 xtract_mel_filter *f;
jamie@1 124 int n, filter;
jamie@1 125 fftwf_plan plan;
jamie@1 126
jamie@1 127 f = (xtract_mel_filter *)argv;
jamie@1 128
jamie@1 129 for(filter = 0; filter < f->n_filters; filter++){
jamie@1 130 for(n = 0; n < N; n++){
jamie@1 131 result[filter] += data[n] * f->filters[filter][n];
jamie@1 132 }
jamie@1 133 if(result[filter] < LOG_LIMIT) result[filter] = LOG_LIMIT;
jamie@1 134 result[filter] = log(result[filter]);
jamie@1 135 }
jamie@1 136
jamie@1 137 for(n = filter + 1; n < N; n++) result[n] = 0;
jamie@1 138
jamie@1 139 xtract_dct(result, f->n_filters, NULL, result);
jamie@1 140
jamie@1 141 }
jamie@1 142
jamie@1 143 int xtract_dct(float *data, int N, void *argv, float *result){
jamie@1 144
jamie@1 145 fftwf_plan plan;
jamie@1 146
jamie@1 147 plan =
jamie@1 148 fftwf_plan_r2r_1d(N, data, result, FFTW_REDFT00, FFTW_ESTIMATE);
jamie@1 149
jamie@1 150 fftwf_execute(plan);
jamie@1 151 fftwf_destroy_plan(plan);
jamie@1 152 }
jamie@1 153
jamie@1 154 int xtract_bark_coefficients(float *data, int N, void *argv, float *result){
jamie@1 155
jamie@1 156 int *limits, band, n;
jamie@1 157
jamie@1 158 limits = (int *)argv;
jamie@1 159
jamie@1 160 for(band = 0; band < BARK_BANDS; band++){
jamie@1 161 for(n = limits[band]; n < limits[band + 1]; n++)
jamie@1 162 result[band] += data[n];
jamie@1 163 }
jamie@1 164 }
jamie@1 165
jamie@1 166 int xtract_peaks(float *data, int N, void *argv, float *result){
jamie@1 167
jamie@1 168 float thresh, max, y, y2, y3, p, width, sr;
jamie@1 169 int n = N, M, return_code;
jamie@1 170
jamie@1 171 if(argv != NULL){
jamie@1 172 thresh = ((float *)argv)[0];
jamie@1 173 sr = ((float *)argv)[1];
jamie@1 174 return_code = BAD_ARGV;
jamie@1 175 }
jamie@1 176 else{
jamie@1 177 thresh = 0;
jamie@1 178 sr = 44100;
jamie@1 179 }
jamie@1 180
jamie@1 181 M = N >> 1;
jamie@1 182 width = sr / N;
jamie@1 183
jamie@1 184 y = y2 = y3 = p = max = 0;
jamie@1 185
jamie@1 186 if(thresh < 0 || thresh > 100){
jamie@1 187 thresh = 0;
jamie@1 188 return_code = BAD_ARGV;
jamie@1 189 }
jamie@1 190
jamie@1 191 if(!sr){
jamie@1 192 sr = 44100;
jamie@1 193 return_code = BAD_ARGV;
jamie@1 194 }
jamie@1 195
jamie@1 196 while(n--){
jamie@1 197 max = MAX(max, data[n]);
jamie@1 198 /* ensure we never take log10(0) */
jamie@1 199 /*data[n] = (data[n] < LOG_LIMIT ? LOG_LIMIT : data[n]);*/
jamie@1 200 if ((data[n] * 100000) <= 1)
jamie@1 201 /* We get a more stable peak this way */
jamie@1 202 data[n] = 1;
jamie@1 203
jamie@1 204 }
jamie@1 205
jamie@1 206 thresh *= .01 * max;
jamie@1 207
jamie@1 208 result[0] = 0;
jamie@1 209 result[M] = 0;
jamie@1 210
jamie@1 211 for(n = 1; n < M; n++){
jamie@1 212 if(data[n] >= thresh){
jamie@1 213 if(data[n] > data[n - 1] && data[n] > data[n + 1]){
jamie@1 214 result[n] = width * (n + (p = .5 * (y = 20 * log10(data[n-1]) - (y3 = 20 * log10(data[n+1]))) / (20 * log10(data[n - 1]) - 2 * (y2 = 20 * log10(data[n])) + 20 * log10(data[n + 1]))));
jamie@1 215 result[M + n] = y2 - .25 * (y - y3) * p;
jamie@1 216 }
jamie@1 217 else{
jamie@1 218 result[n] = 0;
jamie@1 219 result[M + n] = 0;
jamie@1 220 }
jamie@1 221 }
jamie@1 222 else{
jamie@1 223 result[n] = 0;
jamie@1 224 result[M + n] = 0;
jamie@1 225 }
jamie@1 226 }
jamie@1 227
jamie@1 228 return (return_code ? return_code : SUCCESS);
jamie@1 229 }
jamie@1 230