annotate src/vector.c @ 114:f5040ed4e555

Added new extraction function: xtract_subbands()
author Jamie Bullock <jamie@postlude.co.uk>
date Fri, 15 Feb 2008 15:49:49 +0000
parents 72a9a393d5bd
children 6c5ece9cba3a
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 <math.h>
jamie@43 25 #include <string.h>
jamie@43 26 #include <stdlib.h>
jamie@30 27
jamie@98 28 #include "xtract/libxtract.h"
jamie@98 29 #include "xtract_macros_private.h"
jamie@98 30
jamie@85 31 #ifndef roundf
jamie@85 32 float roundf(float f){
jamie@85 33 if (f - (int)f >= 0.5)
jamie@85 34 return (float)((int)f + 1);
jamie@85 35 else
jamie@85 36 return (float)((int)f);
jamie@85 37 }
jamie@85 38 #endif
jamie@85 39
jamie@113 40 #ifndef powf
jamie@113 41 #define powf pow
jamie@113 42 #endif
jamie@113 43
jamie@113 44 #ifndef expf
jamie@113 45 #define expf exp
jamie@113 46 #endif
jamie@113 47
jamie@113 48 #ifndef sqrtf
jamie@113 49 #define sqrtf sqrt
jamie@113 50 #endif
jamie@113 51
jamie@113 52 #ifndef fabsf
jamie@113 53 #define fabsf fabs
jamie@113 54 #endif
jamie@113 55
jamie@30 56 #ifdef XTRACT_FFT
jamie@30 57
jamie@1 58 #include <fftw3.h>
jamie@98 59 #include "xtract_globals_private.h"
jamie@98 60 #include "xtract_macros_private.h"
jamie@1 61
jamie@54 62 int xtract_spectrum(const float *data, const int N, const void *argv, float *result){
jamie@1 63
jamie@113 64 float *input, *rfft, q, temp, max, NxN;
jamie@43 65 size_t bytes;
jamie@111 66 int n,
jamie@111 67 m,
jamie@105 68 M,
jamie@105 69 vector,
jamie@105 70 withDC,
jamie@105 71 argc,
jamie@105 72 normalise;
jamie@98 73
jamie@105 74 vector = argc = withDC = normalise = 0;
jamie@1 75
jamie@54 76 M = N >> 1;
jamie@56 77 NxN = XTRACT_SQ(N);
jamie@54 78
jamie@54 79 rfft = (float *)fftwf_malloc(N * sizeof(float));
jamie@43 80 input = (float *)malloc(bytes = N * sizeof(float));
jamie@43 81 input = memcpy(input, data, bytes);
jamie@1 82
jamie@56 83 q = *(float *)argv;
jamie@54 84 vector = (int)*((float *)argv+1);
jamie@70 85 withDC = (int)*((float *)argv+2);
jamie@105 86 normalise = (int)*((float *)argv+3);
jamie@105 87
jamie@105 88 temp = 0.f;
jamie@105 89 max = 0.f;
jamie@46 90
jamie@56 91 XTRACT_CHECK_q;
jamie@46 92
jamie@102 93 if(fft_plans.spectrum_plan == NULL){
jamie@98 94 fprintf(stderr,
jamie@98 95 "libxtract: Error: xtract_spectrum() has uninitialised plan\n");
jamie@98 96 return XTRACT_NO_RESULT;
jamie@98 97 }
jamie@98 98
jamie@102 99 fftwf_execute_r2r(fft_plans.spectrum_plan, input, rfft);
jamie@54 100
jamie@54 101 switch(vector){
jamie@67 102
jamie@56 103 case XTRACT_LOG_MAGNITUDE_SPECTRUM:
jamie@67 104 for(n = 1; n < M; n++){
jamie@67 105 if ((temp = XTRACT_SQ(rfft[n]) +
jamie@70 106 XTRACT_SQ(rfft[N - n])) > XTRACT_LOG_LIMIT)
jamie@113 107 temp = logf(sqrtf(temp) / (float)N);
jamie@54 108 else
jamie@56 109 temp = XTRACT_LOG_LIMIT_DB;
jamie@111 110
jamie@111 111 if(withDC){
jamie@111 112 m = n;
jamie@111 113 result[M + m + 1] = n * q;
jamie@111 114 }
jamie@111 115 else{
jamie@111 116 m = n - 1;
jamie@111 117 result[M + m] = n * q;
jamie@111 118 }
jamie@111 119
jamie@111 120 result[m] =
jamie@111 121 /* Scaling */
jamie@111 122 (temp + XTRACT_DB_SCALE_OFFSET) /
jamie@111 123 XTRACT_DB_SCALE_OFFSET;
jamie@111 124
jamie@111 125 max = result[m] > max ? result[m] : max;
jamie@54 126 }
jamie@54 127 break;
jamie@67 128
jamie@56 129 case XTRACT_POWER_SPECTRUM:
jamie@67 130 for(n = 1; n < M; n++){
jamie@111 131 if(withDC){
jamie@111 132 m = n;
jamie@111 133 result[M + m + 1] = n * q;
jamie@111 134 }
jamie@111 135 else{
jamie@111 136 m = n - 1;
jamie@111 137 result[M + m] = n * q;
jamie@111 138 }
jamie@111 139 result[m] = (XTRACT_SQ(rfft[n]) + XTRACT_SQ(rfft[N - n])) / NxN;
jamie@111 140 max = result[m] > max ? result[m] : max;
jamie@54 141 }
jamie@54 142 break;
jamie@67 143
jamie@56 144 case XTRACT_LOG_POWER_SPECTRUM:
jamie@67 145 for(n = 1; n < M; n++){
jamie@70 146 if ((temp = XTRACT_SQ(rfft[n]) + XTRACT_SQ(rfft[N - n])) >
jamie@67 147 XTRACT_LOG_LIMIT)
jamie@113 148 temp = logf(temp / NxN);
jamie@54 149 else
jamie@56 150 temp = XTRACT_LOG_LIMIT_DB;
jamie@111 151
jamie@111 152 if(withDC){
jamie@111 153 m = n;
jamie@111 154 result[M + m + 1] = n * q;
jamie@111 155 }
jamie@111 156 else{
jamie@111 157 m = n - 1;
jamie@111 158 result[M + m] = n * q;
jamie@111 159 }
jamie@111 160
jamie@111 161 result[m] = (temp + XTRACT_DB_SCALE_OFFSET) /
jamie@70 162 XTRACT_DB_SCALE_OFFSET;
jamie@111 163 max = result[m] > max ? result[m] : max;
jamie@54 164 }
jamie@54 165 break;
jamie@67 166
jamie@54 167 default:
jamie@54 168 /* MAGNITUDE_SPECTRUM */
jamie@67 169 for(n = 1; n < M; n++){
jamie@111 170 if(withDC){
jamie@111 171 m = n;
jamie@111 172 result[M + m + 1] = n * q;
jamie@111 173 }
jamie@111 174 else{
jamie@111 175 m = n - 1;
jamie@111 176 result[M + m] = n * q;
jamie@111 177 }
jamie@111 178
jamie@113 179 result[m] = sqrtf(XTRACT_SQ(rfft[n]) +
jamie@113 180 XTRACT_SQ(rfft[N - n])) / (float)N;
jamie@111 181 max = result[m] > max ? result[m] : max;
jamie@54 182 }
jamie@54 183 break;
jamie@1 184 }
jamie@1 185
jamie@70 186 if(withDC){
jamie@70 187 /* The DC component */
jamie@70 188 result[0] = XTRACT_SQ(rfft[0]);
jamie@70 189 result[M + 1] = 0.f;
jamie@105 190 max = result[0] > max ? result[0] : max;
jamie@70 191 /* The Nyquist */
jamie@70 192 result[M] = XTRACT_SQ(rfft[M]);
jamie@70 193 result[N + 1] = q * M;
jamie@105 194 max = result[M] > max ? result[M] : max;
jamie@70 195 }
jamie@70 196 else {
jamie@70 197 /* The Nyquist */
jamie@98 198 result[M - 1] = (float)XTRACT_SQ(rfft[M]);
jamie@70 199 result[N - 1] = q * M;
jamie@105 200 max = result[M - 1] > max ? result[M - 1] : max;
jamie@70 201 }
jamie@105 202
jamie@105 203 if(normalise){
jamie@105 204 for(n = 0; n < M; n++)
jamie@105 205 result[n] /= max;
jamie@105 206 }
jamie@105 207
jamie@54 208 fftwf_free(rfft);
jamie@43 209 free(input);
jamie@1 210
jamie@56 211 return XTRACT_SUCCESS;
jamie@1 212 }
jamie@1 213
jamie@43 214 int xtract_autocorrelation_fft(const float *data, const int N, const void *argv, float *result){
jamie@1 215
jamie@75 216 float *freq, *time;
jamie@75 217 int n, M;
jamie@98 218 //fftwf_plan plan;
jamie@1 219
jamie@75 220 M = N << 1;
jamie@43 221
jamie@75 222 freq = (float *)fftwf_malloc(M * sizeof(float));
jamie@75 223 /* Zero pad the input vector */
jamie@75 224 time = (float *)calloc(M, sizeof(float));
jamie@75 225 time = memcpy(time, data, N * sizeof(float));
jamie@75 226
jamie@102 227 fftwf_execute_r2r(fft_plans.autocorrelation_fft_plan_1, time, freq);
jamie@98 228 //plan = fftwf_plan_r2r_1d(M, time, freq, FFTW_R2HC, FFTW_ESTIMATE);
jamie@1 229
jamie@98 230 //fftwf_execute(plan);
jamie@75 231
jamie@76 232 for(n = 1; n < N; n++){
jamie@75 233 freq[n] = XTRACT_SQ(freq[n]) + XTRACT_SQ(freq[M - n]);
jamie@75 234 freq[M - n] = 0.f;
jamie@75 235 }
jamie@1 236
jamie@75 237 freq[0] = XTRACT_SQ(freq[0]);
jamie@75 238 freq[N] = XTRACT_SQ(freq[N]);
jamie@75 239
jamie@98 240 //plan = fftwf_plan_r2r_1d(M, freq, time, FFTW_HC2R, FFTW_ESTIMATE);
jamie@75 241
jamie@98 242 //fftwf_execute(plan);
jamie@98 243
jamie@102 244 fftwf_execute_r2r(fft_plans.autocorrelation_fft_plan_2, freq, time);
jamie@75 245
jamie@75 246 /* Normalisation factor */
jamie@75 247 M = M * N;
jamie@75 248
jamie@75 249 for(n = 0; n < N; n++)
jamie@75 250 result[n] = time[n] / (float)M;
jamie@75 251 /* result[n] = time[n+1] / (float)M; */
jamie@75 252
jamie@98 253 //fftwf_destroy_plan(plan);
jamie@75 254 fftwf_free(freq);
jamie@75 255 free(time);
jamie@38 256
jamie@56 257 return XTRACT_SUCCESS;
jamie@1 258 }
jamie@1 259
jamie@43 260 int xtract_mfcc(const float *data, const int N, const void *argv, float *result){
jamie@30 261
jamie@30 262 xtract_mel_filter *f;
jamie@30 263 int n, filter;
jamie@30 264
jamie@30 265 f = (xtract_mel_filter *)argv;
jamie@39 266
jamie@30 267 for(filter = 0; filter < f->n_filters; filter++){
danstowell@68 268 result[filter] = 0.f;
jamie@30 269 for(n = 0; n < N; n++){
jamie@71 270 result[filter] += data[n] * f->filters[filter][n];
jamie@30 271 }
jamie@113 272 result[filter] = logf(result[filter] < XTRACT_LOG_LIMIT ? XTRACT_LOG_LIMIT : result[filter]);
jamie@30 273 }
jamie@30 274
jamie@30 275 xtract_dct(result, f->n_filters, NULL, result);
jamie@43 276
jamie@56 277 return XTRACT_SUCCESS;
jamie@30 278 }
jamie@30 279
jamie@43 280 int xtract_dct(const float *data, const int N, const void *argv, float *result){
jamie@30 281
jamie@98 282 //fftwf_plan plan;
jamie@43 283
jamie@98 284 //plan =
jamie@98 285 // fftwf_plan_r2r_1d(N, (float *) data, result, FFTW_REDFT00, FFTW_ESTIMATE);
jamie@30 286
jamie@102 287 fftwf_execute_r2r(fft_plans.dct_plan, (float *)data, result);
jamie@98 288 //fftwf_execute(plan);
jamie@98 289 //fftwf_destroy_plan(plan);
jamie@38 290
jamie@56 291 return XTRACT_SUCCESS;
jamie@30 292 }
jamie@30 293
jamie@30 294 #else
jamie@30 295
jamie@67 296 int xtract_spectrum(const float *data, const int N, const void *argv, float *result){
jamie@30 297
danstowell@66 298 XTRACT_NEEDS_FFTW;
danstowell@66 299 return XTRACT_NO_RESULT;
jamie@30 300
jamie@30 301 }
jamie@30 302
jamie@43 303 int xtract_autocorrelation_fft(const float *data, const int N, const void *argv, float *result){
jamie@30 304
danstowell@66 305 XTRACT_NEEDS_FFTW;
danstowell@66 306 return XTRACT_NO_RESULT;
jamie@30 307
jamie@30 308 }
jamie@30 309
jamie@43 310 int xtract_mfcc(const float *data, const int N, const void *argv, float *result){
jamie@30 311
danstowell@66 312 XTRACT_NEEDS_FFTW;
danstowell@66 313 return XTRACT_NO_RESULT;
jamie@30 314
jamie@30 315 }
jamie@30 316
jamie@43 317 int xtract_dct(const float *data, const int N, const void *argv, float *result){
jamie@30 318
danstowell@66 319 XTRACT_NEEDS_FFTW;
danstowell@66 320 return XTRACT_NO_RESULT;
jamie@30 321
jamie@30 322 }
jamie@30 323
jamie@30 324 #endif
jamie@30 325
jamie@43 326 int xtract_autocorrelation(const float *data, const int N, const void *argv, float *result){
jamie@30 327
jamie@30 328 /* Naive time domain implementation */
jamie@30 329
jamie@30 330 int n = N, i;
jamie@30 331
jamie@30 332 float corr;
jamie@30 333
jamie@30 334 while(n--){
jamie@30 335 corr = 0;
jamie@30 336 for(i = 0; i < N - n; i++){
jamie@30 337 corr += data[i] * data[i + n];
jamie@30 338 }
jamie@30 339 result[n] = corr / N;
jamie@30 340 }
jamie@38 341
jamie@56 342 return XTRACT_SUCCESS;
jamie@30 343 }
jamie@30 344
jamie@43 345 int xtract_amdf(const float *data, const int N, const void *argv, float *result){
jamie@1 346
jamie@1 347 int n = N, i;
jamie@1 348
jamie@6 349 float md, temp;
jamie@1 350
jamie@1 351 while(n--){
jamie@113 352 md = 0.f;
jamie@1 353 for(i = 0; i < N - n; i++){
jamie@6 354 temp = data[i] - data[i + n];
jamie@6 355 temp = (temp < 0 ? -temp : temp);
jamie@6 356 md += temp;
jamie@1 357 }
jamie@113 358 result[n] = md / (float)N;
jamie@1 359 }
jamie@38 360
jamie@56 361 return XTRACT_SUCCESS;
jamie@1 362 }
jamie@1 363
jamie@43 364 int xtract_asdf(const float *data, const int N, const void *argv, float *result){
jamie@1 365
jamie@1 366 int n = N, i;
jamie@1 367
jamie@1 368 float sd;
jamie@1 369
jamie@1 370 while(n--){
jamie@113 371 sd = 0.f;
jamie@1 372 for(i = 0; i < N - n; i++){
jamie@6 373 /*sd = 1;*/
jamie@56 374 sd += XTRACT_SQ(data[i] - data[i + n]);
jamie@1 375 }
jamie@113 376 result[n] = sd / (float)N;
jamie@1 377 }
jamie@38 378
jamie@56 379 return XTRACT_SUCCESS;
jamie@1 380 }
jamie@1 381
jamie@43 382 int xtract_bark_coefficients(const float *data, const int N, const void *argv, float *result){
jamie@1 383
jamie@1 384 int *limits, band, n;
jamie@1 385
jamie@1 386 limits = (int *)argv;
jamie@1 387
jamie@59 388 for(band = 0; band < XTRACT_BARK_BANDS - 1; band++){
jamie@110 389 result[band] = 0.f;
jamie@1 390 for(n = limits[band]; n < limits[band + 1]; n++)
jamie@1 391 result[band] += data[n];
jamie@1 392 }
jamie@38 393
jamie@56 394 return XTRACT_SUCCESS;
jamie@1 395 }
jamie@1 396
jamie@52 397 int xtract_peak_spectrum(const float *data, const int N, const void *argv, float *result){
jamie@1 398
jamie@56 399 float threshold, max, y, y2, y3, p, q, *input = NULL;
jamie@43 400 size_t bytes;
jamie@59 401 int n = N, rv = XTRACT_SUCCESS;
jamie@49 402
jamie@56 403 threshold = max = y = y2 = y3 = p = q = 0.f;
jamie@1 404
jamie@1 405 if(argv != NULL){
jamie@56 406 q = ((float *)argv)[0];
jamie@55 407 threshold = ((float *)argv)[1];
jamie@1 408 }
jamie@49 409 else
jamie@56 410 rv = XTRACT_BAD_ARGV;
jamie@49 411
jamie@55 412 if(threshold < 0 || threshold > 100){
jamie@55 413 threshold = 0;
jamie@56 414 rv = XTRACT_BAD_ARGV;
jamie@1 415 }
jamie@1 416
jamie@56 417 XTRACT_CHECK_q;
jamie@49 418
jamie@98 419 input = (float *)calloc(N, sizeof(float));
jamie@98 420
jamie@98 421 bytes = N * sizeof(float);
jamie@43 422
jamie@43 423 if(input != NULL)
jamie@43 424 input = memcpy(input, data, bytes);
jamie@43 425 else
jamie@56 426 return XTRACT_MALLOC_FAILED;
jamie@43 427
jamie@45 428 while(n--)
jamie@56 429 max = XTRACT_MAX(max, input[n]);
jamie@1 430
jamie@55 431 threshold *= .01 * max;
jamie@1 432
jamie@1 433 result[0] = 0;
jamie@59 434 result[N] = 0;
jamie@1 435
jamie@59 436 for(n = 1; n < N; n++){
jamie@55 437 if(input[n] >= threshold){
jamie@43 438 if(input[n] > input[n - 1] && input[n] > input[n + 1]){
jamie@59 439 result[N + n] = q * (n + (p = .5 * (y = input[n-1] -
jamie@52 440 (y3 = input[n+1])) / (input[n - 1] - 2 *
jamie@52 441 (y2 = input[n]) + input[n + 1])));
jamie@52 442 result[n] = y2 - .25 * (y - y3) * p;
jamie@1 443 }
jamie@1 444 else{
jamie@1 445 result[n] = 0;
jamie@59 446 result[N + n] = 0;
jamie@1 447 }
jamie@1 448 }
jamie@1 449 else{
jamie@1 450 result[n] = 0;
jamie@59 451 result[N + n] = 0;
jamie@1 452 }
jamie@1 453 }
jamie@1 454
jamie@43 455 free(input);
jamie@56 456 return (rv ? rv : XTRACT_SUCCESS);
jamie@1 457 }
jamie@41 458
jamie@52 459 int xtract_harmonic_spectrum(const float *data, const int N, const void *argv, float *result){
jamie@38 460
jamie@38 461 int n = (N >> 1), M = n;
jamie@38 462
jamie@43 463 const float *freqs, *amps;
jamie@55 464 float f0, threshold, ratio, nearest, distance;
jamie@38 465
jamie@52 466 amps = data;
jamie@52 467 freqs = data + n;
jamie@38 468 f0 = *((float *)argv);
jamie@55 469 threshold = *((float *)argv+1);
jamie@38 470
jamie@38 471 ratio = nearest = distance = 0.f;
jamie@38 472
jamie@38 473 while(n--){
jamie@38 474 if(freqs[n]){
jamie@38 475 ratio = freqs[n] / f0;
jamie@85 476 nearest = roundf(ratio);
jamie@38 477 distance = fabs(nearest - ratio);
jamie@55 478 if(distance > threshold)
jamie@38 479 result[n] = result[M + n] = 0.f;
jamie@42 480 else {
jamie@52 481 result[n] = amps[n];
jamie@52 482 result[M + n] = freqs[n];
jamie@42 483 }
jamie@38 484 }
jamie@38 485 else
jamie@38 486 result[n] = result[M + n] = 0.f;
jamie@38 487 }
jamie@56 488 return XTRACT_SUCCESS;
jamie@38 489 }
jamie@38 490
jamie@104 491 int xtract_lpc(const float *data, const int N, const void *argv, float *result){
jamie@104 492
jamie@104 493 int i, j, k, M, L;
jamie@104 494 float r = 0.f,
jamie@104 495 error = 0.f;
jamie@104 496
jamie@104 497 float *ref = NULL,
jamie@104 498 *lpc = NULL ;
jamie@104 499
jamie@104 500 error = data[0];
jamie@104 501 k = N; /* The length of *data */
jamie@104 502 L = N - 1; /* The number of LPC coefficients */
jamie@104 503 M = L * 2; /* The length of *result */
jamie@104 504 ref = result;
jamie@104 505 lpc = result+L;
jamie@113 506
jamie@104 507 if(error == 0.0){
jamie@113 508 memset(result, 0, M * sizeof(float));
jamie@104 509 return XTRACT_NO_RESULT;
jamie@104 510 }
jamie@113 511
jamie@104 512 memset(result, 0, M * sizeof(float));
jamie@104 513
jamie@104 514 for (i = 0; i < L; i++) {
jamie@104 515
jamie@104 516 /* Sum up this iteration's reflection coefficient. */
jamie@104 517 r = -data[i + 1];
jamie@104 518 for (j = 0; j < i; j++)
jamie@104 519 r -= lpc[j] * data[i - j];
jamie@104 520 ref[i] = r /= error;
jamie@104 521
jamie@104 522 /* Update LPC coefficients and total error. */
jamie@104 523 lpc[i] = r;
jamie@104 524 for (j = 0; j < i / 2; j++) {
jamie@104 525 float tmp = lpc[j];
jamie@104 526 lpc[j] = r * lpc[i - 1 - j];
jamie@104 527 lpc[i - 1 - j] += r * tmp;
jamie@104 528 }
jamie@104 529 if (i % 2) lpc[j] += lpc[j] * r;
jamie@104 530
jamie@104 531 error *= 1 - r * r;
jamie@104 532 }
jamie@104 533
jamie@104 534 return XTRACT_SUCCESS;
jamie@104 535 }
jamie@104 536
jamie@104 537 int xtract_lpcc(const float *data, const int N, const void *argv, float *result){
jamie@104 538
jamie@104 539 /* Given N lpc coefficients extract an LPC cepstrum of size argv[0] */
jamie@104 540 /* Based on an an algorithm by rabiner and Juang */
jamie@104 541
jamie@104 542 int n, k;
jamie@104 543 float sum;
jamie@104 544 int order = N - 1; /* Eventually change this to Q = 3/2 p as suggested in Rabiner */
jamie@104 545 int cep_length;
jamie@104 546
jamie@104 547 if(argv == NULL)
jamie@104 548 cep_length = N - 1;
jamie@104 549 else
jamie@104 550 cep_length = (int)((float *)argv)[0];
jamie@104 551
jamie@104 552 memset(result, 0, cep_length * sizeof(float));
jamie@104 553
jamie@104 554 for (n = 1; n <= order && n <= cep_length; n++){
jamie@104 555 sum = 0.f;
jamie@104 556 for (k = 1; k < n; k++)
jamie@104 557 sum += k * result[k-1] * data[n - k];
jamie@104 558 result[n-1] = data[n] + sum / n;
jamie@104 559 }
jamie@104 560
jamie@104 561 /* be wary of these interpolated values */
jamie@104 562 for(n = order + 1; n <= cep_length; n++){
jamie@104 563 sum = 0.f;
jamie@104 564 for (k = n - (order - 1); k < n; k++)
jamie@104 565 sum += k * result[k-1] * data[n - k];
jamie@104 566 result[n-1] = sum / n;
jamie@104 567 }
jamie@104 568
jamie@104 569 return XTRACT_SUCCESS;
jamie@104 570
jamie@104 571 }
jamie@104 572 //int xtract_lpcc_s(const float *data, const int N, const void *argv, float *result){
jamie@104 573 // return XTRACT_SUCCESS;
jamie@104 574 //}
jamie@104 575
jamie@114 576 int xtract_subbands(const float *data, const int N, const void *argv, float *result){
jamie@104 577
jamie@114 578 int n, bw, xtract_func, nbands, scale, start, lower, *argi, rv;
jamie@114 579
jamie@114 580 argi = (int *)argv;
jamie@114 581
jamie@114 582 xtract_func = argi[0];
jamie@114 583 nbands = argi[1];
jamie@114 584 scale = argi[2];
jamie@114 585 start = argi[3];
jamie@114 586
jamie@114 587
jamie@114 588 if(scale == XTRACT_LINEAR_SUBBANDS)
jamie@114 589 bw = floorf((N - start) / nbands);
jamie@114 590 else
jamie@114 591 bw = start;
jamie@114 592
jamie@114 593 lower = start;
jamie@114 594
jamie@114 595 for(n = 0; n < nbands; n++){
jamie@114 596
jamie@114 597 /* Bounds sanity check */
jamie@114 598 if(lower + bw >= N)
jamie@114 599 result[n] = 0.f
jamie@114 600 continue;
jamie@114 601
jamie@114 602 rv = xtract[xtract_func](data+lower, bw, NULL, &result[n]);
jamie@114 603
jamie@114 604 if(rv != XTRACT_SUCCESS)
jamie@114 605 return rv;
jamie@114 606
jamie@114 607 switch(scale){
jamie@114 608 case XTRACT_OCTAVE_SUBBANDS:
jamie@114 609 lower += bw;
jamie@114 610 bw = lower;
jamie@114 611 break;
jamie@114 612 case XTRACT_LINEAR_SUBBANDS:
jamie@114 613 lower += bw;
jamie@114 614 break;
jamie@114 615 }
jamie@114 616
jamie@114 617 }
jamie@114 618
jamie@114 619 return rv;
jamie@114 620
jamie@114 621 }
jamie@114 622
jamie@114 623
jamie@114 624