annotate src/vector.c @ 45:e8f4c56de591

Added new features: sum, highest_value, crest and noisiness
author Jamie Bullock <jamie@postlude.co.uk>
date Wed, 20 Dec 2006 15:34:56 +0000
parents 4a36f70a76e9
children 4725bee447c2
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@43 26 #include <string.h>
jamie@43 27 #include <stdlib.h>
jamie@30 28
jamie@30 29 #ifdef XTRACT_FFT
jamie@30 30
jamie@1 31 #include <fftw3.h>
jamie@1 32
jamie@43 33 int xtract_magnitude_spectrum(const float *data, const int N, const void *argv, float *result){
jamie@1 34
jamie@43 35 float *temp, *input;
jamie@43 36 size_t bytes;
jamie@1 37 int n , M = N >> 1;
jamie@1 38 fftwf_plan plan;
jamie@1 39
jamie@1 40 temp = (float *)fftwf_malloc(N * sizeof(float));
jamie@43 41 input = (float *)malloc(bytes = N * sizeof(float));
jamie@43 42 input = memcpy(input, data, bytes);
jamie@1 43
jamie@43 44 plan = fftwf_plan_r2r_1d(N, input, temp, FFTW_R2HC, FFTW_ESTIMATE);
jamie@1 45
jamie@1 46 fftwf_execute(plan);
jamie@1 47
jamie@1 48 for(n = 1; n < M; n++){
jamie@1 49 result[n] = sqrt(SQ(temp[n]) + SQ(temp[N - n])) / N;
jamie@1 50 result[N-n] = 0.0f;
jamie@1 51 }
jamie@1 52
jamie@1 53 result[0] = fabs(temp[0]) / N;
jamie@1 54 result[M] = fabs(temp[M]) / N;
jamie@1 55
jamie@1 56 fftwf_destroy_plan(plan);
jamie@1 57 fftwf_free(temp);
jamie@43 58 free(input);
jamie@1 59
jamie@38 60 return SUCCESS;
jamie@1 61 }
jamie@1 62
jamie@43 63 int xtract_autocorrelation_fft(const float *data, const int N, const void *argv, float *result){
jamie@1 64
jamie@43 65 float *temp, *input;
jamie@43 66 size_t bytes;
jamie@1 67 int n;
jamie@1 68 fftwf_plan plan;
jamie@1 69
jamie@1 70 temp = (float *)fftwf_malloc(N * sizeof(float));
jamie@43 71 input = (float *)malloc(bytes = N * sizeof(float));
jamie@43 72 input = memcpy(input, data, bytes);
jamie@43 73
jamie@43 74 plan = fftwf_plan_r2r_1d(N, input, temp, FFTW_HC2R, FFTW_ESTIMATE);
jamie@1 75
jamie@1 76 fftwf_execute(plan);
jamie@1 77
jamie@1 78 for(n = 0; n < N - 1; n++)
jamie@1 79 result[n] = temp[n+1];
jamie@1 80
jamie@1 81 fftwf_destroy_plan(plan);
jamie@1 82 fftwf_free(temp);
jamie@43 83 free(input);
jamie@38 84
jamie@38 85 return SUCCESS;
jamie@1 86 }
jamie@1 87
jamie@43 88 int xtract_mfcc(const float *data, const int N, const void *argv, float *result){
jamie@30 89
jamie@30 90 xtract_mel_filter *f;
jamie@43 91 float *input;
jamie@43 92 size_t bytes;
jamie@30 93 int n, filter;
jamie@30 94
jamie@30 95 f = (xtract_mel_filter *)argv;
jamie@39 96
jamie@43 97 input = (float *)malloc(bytes = N * sizeof(float));
jamie@43 98 input = memcpy(input, data, bytes);
jamie@43 99
jamie@30 100 for(filter = 0; filter < f->n_filters; filter++){
jamie@30 101 for(n = 0; n < N; n++){
jamie@43 102 result[filter] += input[n] * f->filters[filter][n];
jamie@30 103 }
jamie@30 104 if(result[filter] < LOG_LIMIT) result[filter] = LOG_LIMIT;
jamie@30 105 result[filter] = log(result[filter]);
jamie@30 106 }
jamie@30 107
jamie@30 108 for(n = filter + 1; n < N; n++) result[n] = 0;
jamie@30 109
jamie@30 110 xtract_dct(result, f->n_filters, NULL, result);
jamie@30 111
jamie@43 112 free(input);
jamie@43 113
jamie@38 114 return SUCCESS;
jamie@30 115 }
jamie@30 116
jamie@43 117 int xtract_dct(const float *data, const int N, const void *argv, float *result){
jamie@30 118
jamie@30 119 fftwf_plan plan;
jamie@43 120 float *input;
jamie@43 121 size_t bytes;
jamie@30 122
jamie@43 123 input = (float *)malloc(bytes = N * sizeof(float));
jamie@43 124 input = memcpy(input, data, bytes);
jamie@43 125
jamie@30 126 plan =
jamie@43 127 fftwf_plan_r2r_1d(N, input, result, FFTW_REDFT00, FFTW_ESTIMATE);
jamie@30 128
jamie@30 129 fftwf_execute(plan);
jamie@30 130 fftwf_destroy_plan(plan);
jamie@43 131 free(input);
jamie@38 132
jamie@38 133 return SUCCESS;
jamie@30 134 }
jamie@30 135
jamie@30 136 #else
jamie@30 137
jamie@43 138 int xtract_magnitude_spectrum(const float *data, const int N, const void *argv, float *result){
jamie@30 139
jamie@34 140 NEEDS_FFTW;
jamie@30 141
jamie@30 142 }
jamie@30 143
jamie@43 144 int xtract_autocorrelation_fft(const float *data, const int N, const void *argv, float *result){
jamie@30 145
jamie@34 146 NEEDS_FFTW;
jamie@30 147
jamie@30 148 }
jamie@30 149
jamie@43 150 int xtract_mfcc(const float *data, const int N, const void *argv, float *result){
jamie@30 151
jamie@34 152 NEEDS_FFTW;
jamie@30 153
jamie@30 154 }
jamie@30 155
jamie@43 156 int xtract_dct(const float *data, const int N, const void *argv, float *result){
jamie@30 157
jamie@34 158 NEEDS_FFTW;
jamie@30 159
jamie@30 160 }
jamie@30 161
jamie@30 162 #endif
jamie@30 163
jamie@43 164 int xtract_autocorrelation(const float *data, const int N, const void *argv, float *result){
jamie@30 165
jamie@30 166 /* Naive time domain implementation */
jamie@30 167
jamie@30 168 int n = N, i;
jamie@30 169
jamie@30 170 float corr;
jamie@30 171
jamie@30 172 while(n--){
jamie@30 173 corr = 0;
jamie@30 174 for(i = 0; i < N - n; i++){
jamie@30 175 corr += data[i] * data[i + n];
jamie@30 176 }
jamie@30 177 result[n] = corr / N;
jamie@30 178 }
jamie@38 179
jamie@38 180 return SUCCESS;
jamie@30 181 }
jamie@30 182
jamie@43 183 int xtract_amdf(const float *data, const int N, const void *argv, float *result){
jamie@1 184
jamie@1 185 int n = N, i;
jamie@1 186
jamie@6 187 float md, temp;
jamie@1 188
jamie@1 189 while(n--){
jamie@1 190 md = 0;
jamie@1 191 for(i = 0; i < N - n; i++){
jamie@6 192 temp = data[i] - data[i + n];
jamie@6 193 temp = (temp < 0 ? -temp : temp);
jamie@6 194 md += temp;
jamie@1 195 }
jamie@1 196 result[n] = md / N;
jamie@1 197 }
jamie@38 198
jamie@38 199 return SUCCESS;
jamie@1 200 }
jamie@1 201
jamie@43 202 int xtract_asdf(const float *data, const int N, const void *argv, float *result){
jamie@1 203
jamie@1 204 int n = N, i;
jamie@1 205
jamie@1 206 float sd;
jamie@1 207
jamie@1 208 while(n--){
jamie@1 209 sd = 0;
jamie@1 210 for(i = 0; i < N - n; i++){
jamie@6 211 /*sd = 1;*/
jamie@1 212 sd += SQ(data[i] - data[i + n]);
jamie@1 213 }
jamie@1 214 result[n] = sd / N;
jamie@1 215 }
jamie@38 216
jamie@38 217 return SUCCESS;
jamie@1 218 }
jamie@1 219
jamie@43 220 int xtract_bark_coefficients(const float *data, const int N, const void *argv, float *result){
jamie@1 221
jamie@1 222 int *limits, band, n;
jamie@1 223
jamie@1 224 limits = (int *)argv;
jamie@1 225
jamie@1 226 for(band = 0; band < BARK_BANDS; band++){
jamie@1 227 for(n = limits[band]; n < limits[band + 1]; n++)
jamie@1 228 result[band] += data[n];
jamie@1 229 }
jamie@38 230
jamie@38 231 return SUCCESS;
jamie@1 232 }
jamie@1 233
jamie@43 234 int xtract_peaks(const float *data, const int N, const void *argv, float *result){
jamie@1 235
jamie@43 236 float thresh, max, y, y2,
jamie@43 237 y3, p, width, sr,
jamie@43 238 *input = NULL;
jamie@43 239 size_t bytes;
jamie@38 240 int n = N, M, return_code = SUCCESS;
jamie@1 241
jamie@1 242 if(argv != NULL){
jamie@1 243 thresh = ((float *)argv)[0];
jamie@1 244 sr = ((float *)argv)[1];
jamie@1 245 return_code = BAD_ARGV;
jamie@1 246 }
jamie@1 247 else{
jamie@45 248 thresh = 0.f;
jamie@45 249 sr = 44100.f;
jamie@1 250 }
jamie@1 251
jamie@43 252 input = (float *)malloc(bytes = N * sizeof(float));
jamie@43 253
jamie@43 254 if(input != NULL)
jamie@43 255 input = memcpy(input, data, bytes);
jamie@43 256 else
jamie@43 257 return MALLOC_FAILED;
jamie@43 258
jamie@1 259 M = N >> 1;
jamie@1 260 width = sr / N;
jamie@1 261
jamie@45 262 y = y2 = y3 = p = max = 0.f;
jamie@1 263
jamie@1 264 if(thresh < 0 || thresh > 100){
jamie@1 265 thresh = 0;
jamie@1 266 return_code = BAD_ARGV;
jamie@1 267 }
jamie@1 268
jamie@1 269 if(!sr){
jamie@45 270 sr = 44100.f;
jamie@1 271 return_code = BAD_ARGV;
jamie@1 272 }
jamie@1 273
jamie@45 274 while(n--)
jamie@43 275 max = MAX(max, input[n]);
jamie@1 276
jamie@1 277 thresh *= .01 * max;
jamie@1 278
jamie@1 279 result[0] = 0;
jamie@1 280 result[M] = 0;
jamie@1 281
jamie@1 282 for(n = 1; n < M; n++){
jamie@43 283 if(input[n] >= thresh){
jamie@43 284 if(input[n] > input[n - 1] && input[n] > input[n + 1]){
jamie@45 285 result[n] = width * (n + (p = .5 * (y = input[n-1] - (y3 = input[n+1])) / (input[n - 1] - 2 * (y2 = input[n]) + input[n + 1])));
jamie@1 286 result[M + n] = y2 - .25 * (y - y3) * p;
jamie@1 287 }
jamie@1 288 else{
jamie@1 289 result[n] = 0;
jamie@1 290 result[M + n] = 0;
jamie@1 291 }
jamie@1 292 }
jamie@1 293 else{
jamie@1 294 result[n] = 0;
jamie@1 295 result[M + n] = 0;
jamie@1 296 }
jamie@1 297 }
jamie@1 298
jamie@43 299 free(input);
jamie@1 300 return (return_code ? return_code : SUCCESS);
jamie@1 301 }
jamie@41 302
jamie@43 303 int xtract_harmonics(const float *data, const int N, const void *argv, float *result){
jamie@38 304
jamie@38 305 int n = (N >> 1), M = n;
jamie@38 306
jamie@43 307 const float *freqs, *amps;
jamie@43 308 float f0, thresh, ratio, nearest, distance;
jamie@38 309
jamie@38 310 freqs = data;
jamie@38 311 amps = data + n;
jamie@38 312 f0 = *((float *)argv);
jamie@38 313 thresh = *((float *)argv+1);
jamie@38 314
jamie@38 315 ratio = nearest = distance = 0.f;
jamie@38 316
jamie@38 317 while(n--){
jamie@38 318 if(freqs[n]){
jamie@38 319 ratio = freqs[n] / f0;
jamie@38 320 nearest = round(ratio);
jamie@38 321 distance = fabs(nearest - ratio);
jamie@38 322 if(distance > thresh)
jamie@38 323 result[n] = result[M + n] = 0.f;
jamie@42 324 else {
jamie@42 325 result[n] = freqs[n];
jamie@42 326 result[M + n] = amps[n];
jamie@42 327 }
jamie@38 328 }
jamie@38 329 else
jamie@38 330 result[n] = result[M + n] = 0.f;
jamie@38 331 }
jamie@38 332 return SUCCESS;
jamie@38 333 }
jamie@38 334