annotate src/vector.c @ 146:baaa9d8b4d10

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