annotate src/vector.c @ 105:f2af1c75e3ed

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