annotate src/vector.c @ 30:4df9012cebf1

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