annotate src/vector.c @ 148:e899c3a708ad

fixed bug in xtract_dct where data wasn't being copied to result vector
author Jamie Bullock <jamie@jamiebullock.com>
date Wed, 09 Jan 2013 15:59:48 +0000
parents 805ee2abcd5f
children 9283aaf1ffb8
rev   line source
jamie@141 1 /*
jamie@141 2 * Copyright (C) 2012 Jamie Bullock
jamie@140 3 *
jamie@141 4 * Permission is hereby granted, free of charge, to any person obtaining a copy
jamie@141 5 * of this software and associated documentation files (the "Software"), to
jamie@141 6 * deal in the Software without restriction, including without limitation the
jamie@141 7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
jamie@141 8 * sell copies of the Software, and to permit persons to whom the Software is
jamie@141 9 * furnished to do so, subject to the following conditions:
jamie@1 10 *
jamie@141 11 * The above copyright notice and this permission notice shall be included in
jamie@141 12 * all copies or substantial portions of the Software.
jamie@1 13 *
jamie@141 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
jamie@141 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
jamie@141 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
jamie@141 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
jamie@141 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
jamie@141 19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
jamie@141 20 * IN THE SOFTWARE.
jamie@1 21 *
jamie@1 22 */
jamie@1 23
jamie@1 24 /* xtract_vector.c: defines functions that extract a feature as a single value from an input vector */
jamie@1 25
jamie@1 26 #include <math.h>
jamie@43 27 #include <string.h>
jamie@43 28 #include <stdlib.h>
jamie@30 29
jamie@148 30 #include "fft.h"
jamie@140 31
jamie@98 32 #include "xtract/libxtract.h"
jamie@98 33 #include "xtract_macros_private.h"
jamie@146 34 #include "xtract_globals_private.h"
jamie@98 35
jamie@146 36 int xtract_spectrum(const double *data, const int N, const void *argv, double *result)
jamie@140 37 {
jamie@1 38
jamie@140 39 int vector = 0;
jamie@140 40 int withDC = 0;
jamie@140 41 int normalise = 0;
jamie@146 42 double q = 0.0;
jamie@146 43 double temp = 0.0;
jamie@146 44 double max = 0.0;
jamie@146 45 double NxN = XTRACT_SQ(N);
jamie@146 46 double *marker = NULL;
jamie@140 47 size_t bytes = N * sizeof(double);
jamie@140 48 unsigned int n = 0;
jamie@140 49 unsigned int m = 0;
jamie@140 50 unsigned int nx2 = 0;
jamie@140 51 unsigned int M = N >> 1;
jamie@98 52
jamie@146 53 q = *(double *)argv;
jamie@146 54 vector = (int)*((double *)argv+1);
jamie@146 55 withDC = (int)*((double *)argv+2);
jamie@146 56 normalise = (int)*((double *)argv+3);
jamie@105 57
jamie@56 58 XTRACT_CHECK_q;
jamie@46 59
jamie@140 60 if(!ooura_data_spectrum.initialised)
jamie@140 61 {
jamie@140 62 fprintf(stderr,
jamie@140 63 "libxtract: error: xtract_spectrum() failed, "
jamie@140 64 "fft data unitialised.\n");
jamie@98 65 return XTRACT_NO_RESULT;
jamie@98 66 }
jamie@98 67
jamie@140 68 /* ooura is in-place
jamie@147 69 * the output format is
jamie@140 70 * a[0] - DC, a[1] - nyquist, a[2...N-1] - remaining bins
jamie@140 71 */
jamie@147 72 rdft(N, 1, data, ooura_data_spectrum.ooura_ip,
jamie@140 73 ooura_data_spectrum.ooura_w);
jamie@54 74
jamie@140 75 switch(vector)
jamie@140 76 {
jamie@67 77
jamie@120 78 case XTRACT_LOG_MAGNITUDE_SPECTRUM:
jamie@140 79 for(n = 0, m = 0; m < M; ++n, ++m)
jamie@140 80 {
jamie@140 81 if(!withDC && n == 0)
jamie@140 82 {
jamie@140 83 continue;
jamie@140 84 }
jamie@140 85 nx2 = n * 2;
jamie@147 86 temp = XTRACT_SQ(data[nx2]) + XTRACT_SQ(data[nx2+1]);
jamie@140 87 if (temp > XTRACT_LOG_LIMIT)
jamie@140 88 {
jamie@146 89 temp = log(sqrt(temp) / (double)N);
jamie@140 90 }
jamie@140 91 else
jamie@140 92 {
jamie@140 93 temp = XTRACT_LOG_LIMIT_DB;
jamie@140 94 }
jamie@140 95 result[m] =
jamie@140 96 /* Scaling */
jamie@140 97 (temp + XTRACT_DB_SCALE_OFFSET) /
jamie@140 98 XTRACT_DB_SCALE_OFFSET;
jamie@111 99
jamie@140 100 XTRACT_SET_FREQUENCY;
jamie@140 101 XTRACT_GET_MAX;
jamie@140 102 }
jamie@140 103 break;
jamie@67 104
jamie@140 105 case XTRACT_POWER_SPECTRUM:
jamie@140 106 for(n = 0, m = 0; m < M; ++n, ++m)
jamie@140 107 {
jamie@140 108 if(!withDC && n == 0)
jamie@140 109 {
jamie@140 110 ++n;
jamie@120 111 }
jamie@147 112 result[m] = (XTRACT_SQ(data[n]) + XTRACT_SQ(data[N - n])) / NxN;
jamie@140 113 XTRACT_SET_FREQUENCY;
jamie@140 114 XTRACT_GET_MAX;
jamie@140 115 }
jamie@140 116 break;
jamie@120 117
jamie@140 118 case XTRACT_LOG_POWER_SPECTRUM:
jamie@140 119 for(n = 0, m = 0; m < M; ++n, ++m)
jamie@140 120 {
jamie@140 121 if(!withDC && n == 0)
jamie@140 122 {
jamie@140 123 ++n;
jamie@120 124 }
jamie@147 125 if ((temp = XTRACT_SQ(data[n]) + XTRACT_SQ(data[N - n])) >
jamie@140 126 XTRACT_LOG_LIMIT)
jamie@146 127 temp = log(temp / NxN);
jamie@140 128 else
jamie@140 129 temp = XTRACT_LOG_LIMIT_DB;
jamie@67 130
jamie@140 131 result[m] = (temp + XTRACT_DB_SCALE_OFFSET) /
jamie@140 132 XTRACT_DB_SCALE_OFFSET;
jamie@140 133 XTRACT_SET_FREQUENCY;
jamie@140 134 XTRACT_GET_MAX;
jamie@140 135 }
jamie@140 136 break;
jamie@111 137
jamie@140 138 default:
jamie@140 139 /* MAGNITUDE_SPECTRUM */
jamie@140 140 for(n = 0, m = 0; m < M; ++n, ++m)
jamie@140 141 {
jamie@140 142 marker = &result[m];
jamie@140 143
jamie@140 144 if(n==0 && !withDC) /* discard DC and keep Nyquist */
jamie@140 145 {
jamie@140 146 ++n;
jamie@140 147 marker = &result[M-1];
jamie@120 148 }
jamie@140 149 if(n==1 && withDC) /* discard Nyquist */
jamie@140 150 {
jamie@140 151 ++n;
jamie@140 152 }
jamie@120 153
jamie@147 154 *marker = (double)(sqrt(XTRACT_SQ(data[n*2]) +
jamie@147 155 XTRACT_SQ(data[n*2+1])) / (double)N);
jamie@111 156
jamie@140 157 XTRACT_SET_FREQUENCY;
jamie@140 158 XTRACT_GET_MAX;
jamie@140 159
jamie@140 160 }
jamie@140 161 break;
jamie@70 162 }
jamie@105 163
jamie@140 164 if(normalise)
jamie@140 165 {
jamie@105 166 for(n = 0; n < M; n++)
jamie@105 167 result[n] /= max;
jamie@105 168 }
jamie@105 169
jamie@56 170 return XTRACT_SUCCESS;
jamie@1 171 }
jamie@1 172
jamie@146 173 int xtract_autocorrelation_fft(const double *data, const int N, const void *argv, double *result)
jamie@140 174 {
jamie@120 175
jamie@140 176 double *rfft = NULL;
jamie@140 177 int n = 0;
jamie@140 178 int M = 0;
jamie@1 179
jamie@75 180 M = N << 1;
jamie@43 181
jamie@75 182 /* Zero pad the input vector */
jamie@140 183 rfft = (double *)calloc(M, sizeof(double));
jamie@146 184 memcpy(rfft, data, N * sizeof(double));
jamie@75 185
jamie@140 186 rdft(M, 1, rfft, ooura_data_autocorrelation_fft.ooura_ip,
jamie@140 187 ooura_data_autocorrelation_fft.ooura_w);
jamie@1 188
jamie@140 189 for(n = 2; n < M; n++)
jamie@140 190 {
jamie@140 191 rfft[n*2] = XTRACT_SQ(rfft[n*2]) + XTRACT_SQ(rfft[n*2+1]);
jamie@146 192 rfft[n*2+1] = 0.0;
jamie@75 193 }
jamie@120 194
jamie@140 195 rfft[0] = XTRACT_SQ(rfft[0]);
jamie@140 196 rfft[1] = XTRACT_SQ(rfft[1]);
jamie@75 197
jamie@140 198 rdft(M, -1, rfft, ooura_data_autocorrelation_fft.ooura_ip,
jamie@140 199 ooura_data_autocorrelation_fft.ooura_w);
jamie@120 200
jamie@75 201 /* Normalisation factor */
jamie@75 202 M = M * N;
jamie@75 203
jamie@75 204 for(n = 0; n < N; n++)
jamie@146 205 result[n] = rfft[n] / (double)M;
jamie@75 206
jamie@140 207 free(rfft);
jamie@38 208
jamie@56 209 return XTRACT_SUCCESS;
jamie@1 210 }
jamie@1 211
jamie@146 212 int xtract_mfcc(const double *data, const int N, const void *argv, double *result)
jamie@140 213 {
jamie@30 214
jamie@30 215 xtract_mel_filter *f;
jamie@30 216 int n, filter;
jamie@30 217
jamie@30 218 f = (xtract_mel_filter *)argv;
jamie@120 219
jamie@140 220 for(filter = 0; filter < f->n_filters; filter++)
jamie@140 221 {
jamie@146 222 result[filter] = 0.0;
jamie@140 223 for(n = 0; n < N; n++)
jamie@140 224 {
jamie@71 225 result[filter] += data[n] * f->filters[filter][n];
jamie@30 226 }
jamie@146 227 result[filter] = log(result[filter] < XTRACT_LOG_LIMIT ? XTRACT_LOG_LIMIT : result[filter]);
jamie@30 228 }
jamie@30 229
jamie@30 230 xtract_dct(result, f->n_filters, NULL, result);
jamie@120 231
jamie@56 232 return XTRACT_SUCCESS;
jamie@30 233 }
jamie@30 234
jamie@146 235 int xtract_dct(const double *data, const int N, const void *argv, double *result)
jamie@140 236 {
jamie@120 237
jamie@148 238 int n;
jamie@148 239 int m;
jamie@148 240 double *temp = calloc(N, sizeof(double));
jamie@120 241
jamie@148 242 for (n = 0; n < N; ++n)
jamie@148 243 {
jamie@148 244 for(m = 1; m <= N; ++m) {
jamie@148 245 temp[n] += data[m - 1] * cos(M_PI * (n / (double)N) * (m - 0.5));
jamie@140 246 }
jamie@148 247 }
jamie@120 248
jamie@148 249 memcpy(result, temp, N * sizeof(double));
jamie@148 250 free(temp);
jamie@148 251
jamie@148 252 return XTRACT_SUCCESS;
jamie@30 253 }
jamie@30 254
jamie@146 255 int xtract_autocorrelation(const double *data, const int N, const void *argv, double *result)
jamie@140 256 {
jamie@30 257
jamie@30 258 /* Naive time domain implementation */
jamie@120 259
jamie@30 260 int n = N, i;
jamie@120 261
jamie@146 262 double corr;
jamie@30 263
jamie@140 264 while(n--)
jamie@140 265 {
jamie@120 266 corr = 0;
jamie@140 267 for(i = 0; i < N - n; i++)
jamie@140 268 {
jamie@30 269 corr += data[i] * data[i + n];
jamie@30 270 }
jamie@30 271 result[n] = corr / N;
jamie@30 272 }
jamie@38 273
jamie@56 274 return XTRACT_SUCCESS;
jamie@30 275 }
jamie@30 276
jamie@146 277 int xtract_amdf(const double *data, const int N, const void *argv, double *result)
jamie@140 278 {
jamie@1 279
jamie@1 280 int n = N, i;
jamie@120 281
jamie@146 282 double md, temp;
jamie@1 283
jamie@140 284 while(n--)
jamie@140 285 {
jamie@146 286 md = 0.0;
jamie@140 287 for(i = 0; i < N - n; i++)
jamie@140 288 {
jamie@6 289 temp = data[i] - data[i + n];
jamie@120 290 temp = (temp < 0 ? -temp : temp);
jamie@120 291 md += temp;
jamie@1 292 }
jamie@146 293 result[n] = md / (double)N;
jamie@1 294 }
jamie@38 295
jamie@56 296 return XTRACT_SUCCESS;
jamie@1 297 }
jamie@1 298
jamie@146 299 int xtract_asdf(const double *data, const int N, const void *argv, double *result)
jamie@140 300 {
jamie@120 301
jamie@1 302 int n = N, i;
jamie@120 303
jamie@146 304 double sd;
jamie@1 305
jamie@140 306 while(n--)
jamie@140 307 {
jamie@146 308 sd = 0.0;
jamie@140 309 for(i = 0; i < N - n; i++)
jamie@140 310 {
jamie@6 311 /*sd = 1;*/
jamie@56 312 sd += XTRACT_SQ(data[i] - data[i + n]);
jamie@1 313 }
jamie@146 314 result[n] = sd / (double)N;
jamie@1 315 }
jamie@38 316
jamie@56 317 return XTRACT_SUCCESS;
jamie@1 318 }
jamie@1 319
jamie@146 320 int xtract_bark_coefficients(const double *data, const int N, const void *argv, double *result)
jamie@140 321 {
jamie@1 322
jamie@1 323 int *limits, band, n;
jamie@1 324
jamie@1 325 limits = (int *)argv;
jamie@120 326
jamie@140 327 for(band = 0; band < XTRACT_BARK_BANDS - 1; band++)
jamie@140 328 {
jamie@146 329 result[band] = 0.0;
jamie@1 330 for(n = limits[band]; n < limits[band + 1]; n++)
jamie@1 331 result[band] += data[n];
jamie@1 332 }
jamie@38 333
jamie@56 334 return XTRACT_SUCCESS;
jamie@1 335 }
jamie@1 336
jamie@146 337 int xtract_peak_spectrum(const double *data, const int N, const void *argv, double *result)
jamie@140 338 {
jamie@1 339
jamie@146 340 double threshold, max, y, y2, y3, p, q, *input = NULL;
jamie@43 341 size_t bytes;
jamie@59 342 int n = N, rv = XTRACT_SUCCESS;
jamie@49 343
jamie@146 344 threshold = max = y = y2 = y3 = p = q = 0.0;
jamie@120 345
jamie@140 346 if(argv != NULL)
jamie@140 347 {
jamie@146 348 q = ((double *)argv)[0];
jamie@146 349 threshold = ((double *)argv)[1];
jamie@1 350 }
jamie@49 351 else
jamie@56 352 rv = XTRACT_BAD_ARGV;
jamie@49 353
jamie@140 354 if(threshold < 0 || threshold > 100)
jamie@140 355 {
jamie@55 356 threshold = 0;
jamie@56 357 rv = XTRACT_BAD_ARGV;
jamie@1 358 }
jamie@1 359
jamie@56 360 XTRACT_CHECK_q;
jamie@49 361
jamie@146 362 input = (double *)calloc(N, sizeof(double));
jamie@98 363
jamie@146 364 bytes = N * sizeof(double);
jamie@43 365
jamie@43 366 if(input != NULL)
jamie@120 367 input = memcpy(input, data, bytes);
jamie@43 368 else
jamie@120 369 return XTRACT_MALLOC_FAILED;
jamie@43 370
jamie@45 371 while(n--)
jamie@56 372 max = XTRACT_MAX(max, input[n]);
jamie@120 373
jamie@55 374 threshold *= .01 * max;
jamie@1 375
jamie@1 376 result[0] = 0;
jamie@59 377 result[N] = 0;
jamie@1 378
jamie@140 379 for(n = 1; n < N; n++)
jamie@140 380 {
jamie@140 381 if(input[n] >= threshold)
jamie@140 382 {
jamie@140 383 if(input[n] > input[n - 1] && n + 1 < N && input[n] > input[n + 1])
jamie@140 384 {
jamie@140 385 result[N + n] = q * (n + (p = .5 * ((y = input[n-1]) -
jamie@140 386 (y3 = input[n+1])) / (input[n - 1] - 2 *
jamie@140 387 (y2 = input[n]) + input[n + 1])));
jamie@52 388 result[n] = y2 - .25 * (y - y3) * p;
jamie@1 389 }
jamie@140 390 else
jamie@140 391 {
jamie@1 392 result[n] = 0;
jamie@59 393 result[N + n] = 0;
jamie@1 394 }
jamie@1 395 }
jamie@140 396 else
jamie@140 397 {
jamie@1 398 result[n] = 0;
jamie@59 399 result[N + n] = 0;
jamie@1 400 }
jamie@140 401 }
jamie@120 402
jamie@43 403 free(input);
jamie@56 404 return (rv ? rv : XTRACT_SUCCESS);
jamie@1 405 }
jamie@120 406
jamie@146 407 int xtract_harmonic_spectrum(const double *data, const int N, const void *argv, double *result)
jamie@140 408 {
jamie@120 409
jamie@140 410 int n = (N >> 1), M = n;
jamie@38 411
jamie@146 412 const double *freqs, *amps;
jamie@146 413 double f0, threshold, ratio, nearest, distance;
jamie@38 414
jamie@52 415 amps = data;
jamie@52 416 freqs = data + n;
jamie@146 417 f0 = *((double *)argv);
jamie@146 418 threshold = *((double *)argv+1);
jamie@38 419
jamie@146 420 ratio = nearest = distance = 0.0;
jamie@38 421
jamie@140 422 while(n--)
jamie@140 423 {
jamie@140 424 if(freqs[n])
jamie@140 425 {
jamie@120 426 ratio = freqs[n] / f0;
jamie@146 427 nearest = round(ratio);
jamie@120 428 distance = fabs(nearest - ratio);
jamie@120 429 if(distance > threshold)
jamie@146 430 result[n] = result[M + n] = 0.0;
jamie@140 431 else
jamie@140 432 {
jamie@120 433 result[n] = amps[n];
jamie@120 434 result[M + n] = freqs[n];
jamie@120 435 }
jamie@120 436 }
jamie@120 437 else
jamie@146 438 result[n] = result[M + n] = 0.0;
jamie@38 439 }
jamie@56 440 return XTRACT_SUCCESS;
jamie@38 441 }
jamie@120 442
jamie@146 443 int xtract_lpc(const double *data, const int N, const void *argv, double *result)
jamie@140 444 {
jamie@104 445
jamie@104 446 int i, j, k, M, L;
jamie@146 447 double r = 0.0,
jamie@146 448 error = 0.0;
jamie@104 449
jamie@146 450 double *ref = NULL,
jamie@140 451 *lpc = NULL ;
jamie@104 452
jamie@104 453 error = data[0];
jamie@104 454 k = N; /* The length of *data */
jamie@104 455 L = N - 1; /* The number of LPC coefficients */
jamie@104 456 M = L * 2; /* The length of *result */
jamie@104 457 ref = result;
jamie@104 458 lpc = result+L;
jamie@113 459
jamie@140 460 if(error == 0.0)
jamie@140 461 {
jamie@146 462 memset(result, 0, M * sizeof(double));
jamie@104 463 return XTRACT_NO_RESULT;
jamie@104 464 }
jamie@113 465
jamie@146 466 memset(result, 0, M * sizeof(double));
jamie@104 467
jamie@140 468 for (i = 0; i < L; i++)
jamie@140 469 {
jamie@104 470
jamie@104 471 /* Sum up this iteration's reflection coefficient. */
jamie@104 472 r = -data[i + 1];
jamie@140 473 for (j = 0; j < i; j++)
jamie@104 474 r -= lpc[j] * data[i - j];
jamie@104 475 ref[i] = r /= error;
jamie@104 476
jamie@104 477 /* Update LPC coefficients and total error. */
jamie@104 478 lpc[i] = r;
jamie@140 479 for (j = 0; j < i / 2; j++)
jamie@140 480 {
jamie@146 481 double tmp = lpc[j];
jamie@104 482 lpc[j] = r * lpc[i - 1 - j];
jamie@104 483 lpc[i - 1 - j] += r * tmp;
jamie@104 484 }
jamie@104 485 if (i % 2) lpc[j] += lpc[j] * r;
jamie@104 486
jamie@104 487 error *= 1 - r * r;
jamie@104 488 }
jamie@104 489
jamie@104 490 return XTRACT_SUCCESS;
jamie@104 491 }
jamie@104 492
jamie@146 493 int xtract_lpcc(const double *data, const int N, const void *argv, double *result)
jamie@140 494 {
jamie@104 495
jamie@104 496 /* Given N lpc coefficients extract an LPC cepstrum of size argv[0] */
jamie@104 497 /* Based on an an algorithm by rabiner and Juang */
jamie@104 498
jamie@104 499 int n, k;
jamie@146 500 double sum;
jamie@104 501 int order = N - 1; /* Eventually change this to Q = 3/2 p as suggested in Rabiner */
jamie@140 502 int cep_length;
jamie@120 503
jamie@104 504 if(argv == NULL)
jamie@115 505 cep_length = N - 1; /* FIX: if we're going to have default values, they should come from the descriptor */
jamie@104 506 else
jamie@115 507 cep_length = *(int *)argv;
jamie@146 508 //cep_length = (int)((double *)argv)[0];
jamie@104 509
jamie@146 510 memset(result, 0, cep_length * sizeof(double));
jamie@104 511
jamie@140 512 for (n = 1; n <= order && n <= cep_length; n++)
jamie@140 513 {
jamie@146 514 sum = 0.0;
jamie@104 515 for (k = 1; k < n; k++)
jamie@104 516 sum += k * result[k-1] * data[n - k];
jamie@104 517 result[n-1] = data[n] + sum / n;
jamie@104 518 }
jamie@104 519
jamie@104 520 /* be wary of these interpolated values */
jamie@140 521 for(n = order + 1; n <= cep_length; n++)
jamie@140 522 {
jamie@146 523 sum = 0.0;
jamie@104 524 for (k = n - (order - 1); k < n; k++)
jamie@104 525 sum += k * result[k-1] * data[n - k];
jamie@104 526 result[n-1] = sum / n;
jamie@104 527 }
jamie@104 528
jamie@104 529 return XTRACT_SUCCESS;
jamie@104 530
jamie@104 531 }
jamie@146 532 //int xtract_lpcc_s(const double *data, const int N, const void *argv, double *result){
jamie@104 533 // return XTRACT_SUCCESS;
jamie@104 534 //}
jamie@104 535
jamie@146 536 int xtract_subbands(const double *data, const int N, const void *argv, double *result)
jamie@140 537 {
jamie@104 538
jamie@114 539 int n, bw, xtract_func, nbands, scale, start, lower, *argi, rv;
jamie@114 540
jamie@114 541 argi = (int *)argv;
jamie@114 542
jamie@114 543 xtract_func = argi[0];
jamie@114 544 nbands = argi[1];
jamie@114 545 scale = argi[2];
jamie@114 546 start = argi[3];
jamie@114 547
jamie@114 548 if(scale == XTRACT_LINEAR_SUBBANDS)
jamie@114 549 bw = floorf((N - start) / nbands);
jamie@114 550 else
jamie@114 551 bw = start;
jamie@114 552
jamie@114 553 lower = start;
jamie@115 554 rv = XTRACT_SUCCESS;
jamie@114 555
jamie@140 556 for(n = 0; n < nbands; n++)
jamie@140 557 {
jamie@114 558
jamie@114 559 /* Bounds sanity check */
jamie@140 560 if(lower >= N || lower + bw >= N)
jamie@140 561 {
jamie@120 562 // printf("n: %d\n", n);
jamie@146 563 result[n] = 0.0;
jamie@114 564 continue;
jamie@115 565 }
jamie@114 566
jamie@114 567 rv = xtract[xtract_func](data+lower, bw, NULL, &result[n]);
jamie@114 568
jamie@114 569 if(rv != XTRACT_SUCCESS)
jamie@114 570 return rv;
jamie@114 571
jamie@140 572 switch(scale)
jamie@140 573 {
jamie@140 574 case XTRACT_OCTAVE_SUBBANDS:
jamie@140 575 lower += bw;
jamie@140 576 bw = lower;
jamie@140 577 break;
jamie@140 578 case XTRACT_LINEAR_SUBBANDS:
jamie@140 579 lower += bw;
jamie@140 580 break;
jamie@114 581 }
jamie@114 582
jamie@114 583 }
jamie@114 584
jamie@114 585 return rv;
jamie@114 586
jamie@114 587 }
jamie@114 588
jamie@114 589
jamie@114 590