annotate src/vector.c @ 120:d9c5cd78abaa

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