annotate src/vector.c @ 49:4e931b464278

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