annotate src/vector.c @ 140:67f6b6e63d45

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