annotate src/scalar.c @ 88:525bfdf936c6

Added java bindings. Everything seems to work OK, except test.java won't compile. Some kind of path error, but I can't work out how to fix it.
author Jamie Bullock <jamie@postlude.co.uk>
date Wed, 05 Sep 2007 14:32:17 +0000
parents 0df00d5c9269
children 35a3bb5c3ffd
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_scalar.c: defines functions that extract a feature as a single value from an input vector */
jamie@1 23
jamie@1 24 #include "xtract/libxtract.h"
jamie@56 25 #include "xtract_macros_private.h"
jamie@1 26 #include "math.h"
jamie@5 27 #include <stdlib.h>
jamie@43 28 #include <string.h>
jamie@78 29 #include <stdio.h>
jamie@1 30
jamie@85 31 #ifndef powf
jamie@85 32 #define powf pow
jamie@85 33 #endif
jamie@85 34
jamie@85 35 #ifndef expf
jamie@85 36 #define expf exp
jamie@85 37 #endif
jamie@85 38
jamie@88 39 int test(void){
jamie@88 40 printf("Hello world");
jamie@88 41 }
jamie@88 42
jamie@43 43 int xtract_mean(const float *data, const int N, const void *argv, float *result){
jamie@25 44
jamie@1 45 int n = N;
jamie@87 46
jamie@87 47 *result = 0.f;
jamie@1 48
jamie@1 49 while(n--)
jamie@42 50 *result += data[n];
jamie@87 51
jamie@1 52 *result /= N;
jamie@38 53
jamie@56 54 return XTRACT_SUCCESS;
jamie@1 55 }
jamie@1 56
jamie@43 57 int xtract_variance(const float *data, const int N, const void *argv, float *result){
jamie@25 58
jamie@1 59 int n = N;
jamie@1 60
jamie@1 61 while(n--)
jamie@43 62 *result += pow(data[n] - *(float *)argv, 2);
jamie@25 63
jamie@43 64 *result = *result / (N - 1);
jamie@44 65
jamie@56 66 return XTRACT_SUCCESS;
jamie@1 67 }
jamie@1 68
jamie@43 69 int xtract_standard_deviation(const float *data, const int N, const void *argv, float *result){
jamie@25 70
jamie@61 71 *result = sqrt(*(float *)argv);
jamie@25 72
jamie@56 73 return XTRACT_SUCCESS;
jamie@1 74 }
jamie@1 75
jamie@43 76 int xtract_average_deviation(const float *data, const int N, const void *argv, float *result){
jamie@25 77
jamie@1 78 int n = N;
jamie@44 79
jamie@1 80 while(n--)
jamie@42 81 *result += fabs(data[n] - *(float *)argv);
jamie@25 82
jamie@1 83 *result /= N;
jamie@1 84
jamie@56 85 return XTRACT_SUCCESS;
jamie@1 86 }
jamie@1 87
jamie@43 88 int xtract_skewness(const float *data, const int N, const void *argv, float *result){
jamie@25 89
jamie@1 90 int n = N;
jamie@1 91
jamie@59 92 float temp = 0.f;
jamie@25 93
jamie@42 94 while(n--){
jamie@42 95 temp = (data[n] - ((float *)argv)[0]) / ((float *)argv)[1];
jamie@42 96 *result += pow(temp, 3);
jamie@42 97 }
jamie@1 98
jamie@42 99 *result /= N;
jamie@44 100
jamie@59 101
jamie@56 102 return XTRACT_SUCCESS;
jamie@1 103 }
jamie@1 104
jamie@43 105 int xtract_kurtosis(const float *data, const int N, const void *argv, float *result){
jamie@25 106
jamie@1 107 int n = N;
jamie@1 108
jamie@42 109 float temp;
jamie@25 110
jamie@42 111 while(n--){
jamie@42 112 temp = (data[n] - ((float *)argv)[0]) / ((float *)argv)[1];
jamie@42 113 *result += pow(temp, 4);
jamie@42 114 }
jamie@25 115
jamie@42 116 *result /= N;
jamie@42 117 *result -= 3.0f;
jamie@44 118
jamie@56 119 return XTRACT_SUCCESS;
jamie@1 120 }
jamie@1 121
jamie@52 122 int xtract_spectral_centroid(const float *data, const int N, const void *argv, float *result){
jamie@25 123
jamie@37 124 int n = (N >> 1);
jamie@11 125
jamie@43 126 const float *freqs, *amps;
jamie@43 127 float FA = 0.f, A = 0.f;
jamie@11 128
jamie@52 129 amps = data;
jamie@52 130 freqs = data + n;
jamie@25 131
jamie@11 132 while(n--){
jamie@25 133 FA += freqs[n] * amps[n];
jamie@25 134 A += amps[n];
jamie@25 135 }
jamie@25 136
jamie@25 137 *result = FA / A;
jamie@11 138
jamie@56 139 return XTRACT_SUCCESS;
jamie@11 140 }
jamie@11 141
jamie@52 142 int xtract_spectral_mean(const float *data, const int N, const void *argv, float *result){
jamie@52 143
jamie@52 144 return xtract_spectral_centroid(data, N, argv, result);
jamie@52 145
jamie@52 146 }
jamie@52 147
jamie@52 148 int xtract_spectral_variance(const float *data, const int N, const void *argv, float *result){
jamie@52 149
jamie@53 150 int m;
jamie@53 151 float A = 0.f;
jamie@53 152 const float *freqs, *amps;
jamie@52 153
jamie@53 154 m = N >> 1;
jamie@52 155
jamie@53 156 amps = data;
jamie@53 157 freqs = data + m;
jamie@52 158
jamie@53 159 while(m--){
jamie@53 160 A += amps[m];
jamie@59 161 *result += powf((freqs[m] - *(float *)argv) * amps[m], 2);
jamie@53 162 }
jamie@53 163
jamie@59 164 *result = *result / (A /*- 1*/);
jamie@52 165
jamie@56 166 return XTRACT_SUCCESS;
jamie@52 167 }
jamie@52 168
jamie@52 169 int xtract_spectral_standard_deviation(const float *data, const int N, const void *argv, float *result){
jamie@52 170
jamie@59 171 *result = sqrt(*(float *)argv);
jamie@52 172
jamie@56 173 return XTRACT_SUCCESS;
jamie@52 174 }
jamie@52 175
jamie@52 176 int xtract_spectral_average_deviation(const float *data, const int N, const void *argv, float *result){
jamie@52 177
jamie@53 178 int m;
jamie@53 179 float A = 0.f;
jamie@53 180 const float *freqs, *amps;
jamie@52 181
jamie@53 182 m = N >> 1;
jamie@52 183
jamie@53 184 amps = data;
jamie@53 185 freqs = data + m;
jamie@52 186
jamie@53 187 while(m--){
jamie@53 188 A += amps[m];
jamie@53 189 *result += fabs((amps[m] * freqs[m]) - *(float *)argv);
jamie@53 190 }
jamie@53 191
jamie@53 192 *result /= A;
jamie@52 193
jamie@56 194 return XTRACT_SUCCESS;
jamie@52 195 }
jamie@52 196
jamie@52 197 int xtract_spectral_skewness(const float *data, const int N, const void *argv, float *result){
jamie@52 198
jamie@53 199 int m;
jamie@53 200 float temp, A = 0.f;
jamie@53 201 const float *freqs, *amps;
jamie@52 202
jamie@53 203 m = N >> 1;
jamie@53 204
jamie@53 205 amps = data;
jamie@53 206 freqs = data + m;
jamie@52 207
jamie@52 208 while(m--){
jamie@53 209 A += amps[m];
jamie@53 210 temp = ((amps[m] * freqs[m]) -
jamie@52 211 ((float *)argv)[0]) / ((float *)argv)[1];
jamie@52 212 *result += pow(temp, 3);
jamie@52 213 }
jamie@52 214
jamie@53 215 *result /= A;
jamie@52 216
jamie@56 217 return XTRACT_SUCCESS;
jamie@52 218 }
jamie@52 219
jamie@52 220 int xtract_spectral_kurtosis(const float *data, const int N, const void *argv, float *result){
jamie@52 221
jamie@53 222 int m;
jamie@53 223 float temp, A = 0.f;
jamie@53 224 const float *freqs, *amps;
jamie@52 225
jamie@53 226 m = N >> 1;
jamie@53 227
jamie@53 228 amps = data;
jamie@53 229 freqs = data + m;
jamie@52 230
jamie@52 231 while(m--){
jamie@53 232 A += amps[m];
jamie@53 233 temp = ((amps[m] * freqs[m]) -
jamie@52 234 ((float *)argv)[0]) / ((float *)argv)[1];
jamie@52 235 *result += pow(temp, 4);
jamie@52 236 }
jamie@52 237
jamie@53 238 *result /= A;
jamie@52 239 *result -= 3.0f;
jamie@52 240
jamie@56 241 return XTRACT_SUCCESS;
jamie@52 242 }
jamie@52 243
jamie@43 244 int xtract_irregularity_k(const float *data, const int N, const void *argv, float *result){
jamie@25 245
jamie@1 246 int n,
jamie@37 247 M = N - 1;
danstowell@84 248
danstowell@84 249 *result = 0.f;
danstowell@84 250
jamie@1 251 for(n = 1; n < M; n++)
jamie@42 252 *result += fabs(data[n] - (data[n-1] + data[n] + data[n+1]) / 3);
jamie@1 253
jamie@56 254 return XTRACT_SUCCESS;
jamie@1 255 }
jamie@1 256
jamie@43 257 int xtract_irregularity_j(const float *data, const int N, const void *argv, float *result){
jamie@25 258
jamie@1 259 int n = N;
jamie@1 260
jamie@59 261 double num = 0.f, den = 0.f;
jamie@1 262
jamie@1 263 while(n--){
jamie@42 264 num += pow(data[n] - data[n+1], 2);
jamie@42 265 den += pow(data[n], 2);
jamie@1 266 }
jamie@25 267
jamie@59 268 *result = (float)(num / den);
jamie@1 269
jamie@56 270 return XTRACT_SUCCESS;
jamie@1 271 }
jamie@1 272
jamie@43 273 int xtract_tristimulus_1(const float *data, const int N, const void *argv, float *result){
jamie@1 274
jamie@1 275 int n = N;
jamie@1 276
jamie@42 277 float den, p1, temp;
jamie@1 278
jamie@42 279 den = p1 = temp = 0.f;
jamie@1 280
jamie@42 281 for(n = 0; n < N; n++){
jamie@42 282 if((temp = data[n])){
jamie@42 283 den += temp;
jamie@42 284 if(!p1)
jamie@42 285 p1 = temp;
jamie@42 286 }
jamie@42 287 }
jamie@42 288
jamie@42 289 *result = p1 / den;
jamie@1 290
jamie@56 291 return XTRACT_SUCCESS;
jamie@1 292 }
jamie@1 293
jamie@43 294 int xtract_tristimulus_2(const float *data, const int N, const void *argv, float *result){
jamie@25 295
jamie@1 296 int n = N;
jamie@1 297
jamie@42 298 float den, p2, p3, p4, temp;
jamie@1 299
jamie@42 300 den = p2 = p3 = p4 = temp = 0.f;
jamie@1 301
jamie@42 302 for(n = 0; n < N; n++){
jamie@42 303 if((temp = data[n])){
jamie@42 304 den += temp;
jamie@42 305 if(!p2)
jamie@42 306 p2 = temp;
jamie@42 307 else if(!p3)
jamie@42 308 p3 = temp;
jamie@42 309 else if(!p4)
jamie@42 310 p4 = temp;
jamie@42 311 }
jamie@42 312 }
jamie@42 313
jamie@42 314 *result = (p2 + p3 + p4) / den;
jamie@25 315
jamie@56 316 return XTRACT_SUCCESS;
jamie@1 317 }
jamie@1 318
jamie@43 319 int xtract_tristimulus_3(const float *data, const int N, const void *argv, float *result){
jamie@25 320
jamie@42 321 int n = N, count = 0;
jamie@1 322
jamie@42 323 float den, num, temp;
jamie@1 324
jamie@42 325 den = num = temp = 0.f;
jamie@1 326
jamie@42 327 for(n = 0; n < N; n++){
jamie@42 328 if((temp = data[n])){
jamie@42 329 den += temp;
jamie@42 330 if(count >= 5)
jamie@42 331 num += temp;
jamie@42 332 count++;
jamie@42 333 }
jamie@42 334 }
jamie@25 335
jamie@1 336 *result = num / den;
jamie@25 337
jamie@56 338 return XTRACT_SUCCESS;
jamie@1 339 }
jamie@1 340
jamie@43 341 int xtract_smoothness(const float *data, const int N, const void *argv, float *result){
jamie@25 342
jamie@59 343 int n, M;
jamie@1 344
jamie@43 345 float *input;
jamie@43 346
jamie@43 347 input = (float *)malloc(N * sizeof(float));
jamie@59 348 memcpy(input, data, N * sizeof(float));
jamie@43 349
jamie@43 350 if (input[0] <= 0) input[0] = 1;
jamie@25 351
jamie@59 352 M = N - 1;
jamie@59 353
jamie@59 354 for(n = 1; n < M; n++){
jamie@43 355 if(input[n] <= 0) input[n] = 1;
jamie@59 356 *result += fabs(20 * log(input[n]) - (20 * log(input[n-1]) +
jamie@59 357 20 * log(input[n]) + 20 * log(input[n+1])) / 3);
jamie@25 358 }
jamie@43 359
jamie@43 360 free(input);
jamie@44 361
jamie@56 362 return XTRACT_SUCCESS;
jamie@1 363 }
jamie@1 364
jamie@43 365 int xtract_spread(const float *data, const int N, const void *argv, float *result){
jamie@1 366
jamie@1 367 int n = N;
jamie@1 368
jamie@83 369 float num = 0.f, den = 0.f, temp = 0.f;
jamie@83 370
jamie@83 371 if(argv == NULL)
jamie@83 372 return XTRACT_BAD_ARGV;
jamie@1 373
jamie@1 374 while(n--){
jamie@48 375 temp = n - *(float *)argv;
jamie@56 376 num += XTRACT_SQ(temp) * data[n];
jamie@25 377 den += data[n];
jamie@1 378 }
jamie@1 379
jamie@1 380 *result = sqrt(num / den);
jamie@25 381
jamie@56 382 return XTRACT_SUCCESS;
jamie@1 383 }
jamie@1 384
jamie@43 385 int xtract_zcr(const float *data, const int N, const void *argv, float *result){
jamie@1 386
jamie@1 387 int n = N;
jamie@25 388
jamie@1 389 for(n = 1; n < N; n++)
jamie@25 390 if(data[n] * data[n-1] < 0) (*result)++;
jamie@25 391
jamie@1 392 *result /= N;
jamie@25 393
jamie@56 394 return XTRACT_SUCCESS;
jamie@1 395 }
jamie@1 396
jamie@43 397 int xtract_rolloff(const float *data, const int N, const void *argv, float *result){
jamie@1 398
jamie@1 399 int n = N;
jamie@55 400 float pivot, temp, percentile;
jamie@42 401
jamie@42 402 pivot = temp = 0.f;
jamie@55 403 percentile = ((float *)argv)[1];
jamie@25 404
jamie@1 405 while(n--) pivot += data[n];
jamie@25 406
jamie@55 407 pivot *= percentile / 100.f;
jamie@25 408
jamie@42 409 for(n = 0; temp < pivot; n++)
jamie@42 410 temp += data[n];
jamie@1 411
jamie@55 412 *result = n * ((float *)argv)[0];
jamie@55 413 /* *result = (n / (float)N) * (((float *)argv)[1] * .5); */
jamie@25 414
jamie@56 415 return XTRACT_SUCCESS;
jamie@1 416 }
jamie@1 417
jamie@43 418 int xtract_loudness(const float *data, const int N, const void *argv, float *result){
jamie@25 419
jamie@47 420 int n = N, rv;
jamie@25 421
jamie@56 422 if(n > XTRACT_BARK_BANDS)
jamie@56 423 rv = XTRACT_BAD_VECTOR_SIZE;
jamie@47 424 else
jamie@56 425 rv = XTRACT_SUCCESS;
jamie@1 426
jamie@1 427 while(n--)
jamie@59 428 *result += powf(data[n], 0.23);
jamie@38 429
jamie@47 430 return rv;
jamie@1 431 }
jamie@1 432
jamie@43 433 int xtract_flatness(const float *data, const int N, const void *argv, float *result){
jamie@1 434
jamie@42 435 int n;
jamie@1 436
jamie@44 437 double num, den, temp;
jamie@25 438
jamie@44 439 den = data[0];
jamie@44 440 num = (data[0] == 0.f ? 1.f : data[0]);
jamie@43 441
jamie@44 442 for(n = 1; n < N; n++){
jamie@44 443 if((temp = data[n]) != 0.f) {
jamie@44 444 num *= temp;
jamie@44 445 den += temp;
jamie@25 446 }
jamie@1 447 }
jamie@44 448
jamie@59 449 num = powf(num, 1.f / N);
jamie@1 450 den /= N;
jamie@25 451
jamie@56 452 if(num < XTRACT_VERY_SMALL_NUMBER)
jamie@56 453 num = XTRACT_VERY_SMALL_NUMBER;
jamie@44 454
jamie@56 455 if(den < XTRACT_VERY_SMALL_NUMBER)
jamie@56 456 den = XTRACT_VERY_SMALL_NUMBER;
jamie@44 457
jamie@59 458 *result = 10 * log10(num / den);
jamie@25 459
jamie@56 460 return XTRACT_SUCCESS;
jamie@44 461
jamie@1 462 }
jamie@1 463
jamie@43 464 int xtract_tonality(const float *data, const int N, const void *argv, float *result){
jamie@25 465
jamie@1 466 float sfmdb, sfm;
jamie@25 467
jamie@1 468 sfm = *(float *)argv;
jamie@1 469
jamie@59 470 sfmdb = sfm / -60.f;
jamie@25 471
jamie@56 472 *result = XTRACT_MIN(sfmdb, 1);
jamie@25 473
jamie@56 474 return XTRACT_SUCCESS;
jamie@1 475 }
jamie@1 476
jamie@43 477 int xtract_crest(const float *data, const int N, const void *argv, float *result){
jamie@25 478
jamie@45 479 float max, mean;
jamie@45 480
jamie@45 481 max = mean = 0.f;
jamie@45 482
jamie@45 483 max = *(float *)argv;
jamie@45 484 mean = *((float *)argv+1);
jamie@45 485
jamie@45 486 *result = max / mean;
jamie@45 487
jamie@56 488 return XTRACT_SUCCESS;
jamie@25 489
jamie@1 490 }
jamie@1 491
jamie@43 492 int xtract_noisiness(const float *data, const int N, const void *argv, float *result){
jamie@25 493
jamie@45 494 float h, i, p; /*harmonics, inharmonics, partials */
jamie@45 495
jamie@45 496 i = p = h = 0.f;
jamie@45 497
jamie@45 498 h = *(float *)argv;
jamie@45 499 p = *((float *)argv+1);
jamie@45 500
jamie@45 501 i = p - h;
jamie@45 502
jamie@45 503 *result = i / p;
jamie@45 504
jamie@56 505 return XTRACT_SUCCESS;
jamie@25 506
jamie@1 507 }
jamie@2 508
jamie@43 509 int xtract_rms_amplitude(const float *data, const int N, const void *argv, float *result){
jamie@1 510
jamie@1 511 int n = N;
jamie@1 512
jamie@56 513 while(n--) *result += XTRACT_SQ(data[n]);
jamie@1 514
jamie@1 515 *result = sqrt(*result / N);
jamie@25 516
jamie@56 517 return XTRACT_SUCCESS;
jamie@1 518 }
jamie@1 519
jamie@52 520 int xtract_spectral_inharmonicity(const float *data, const int N, const void *argv, float *result){
jamie@1 521
jamie@41 522 int n = N >> 1;
jamie@43 523 float num = 0.f, den = 0.f, fund;
jamie@43 524 const float *freqs, *amps;
jamie@1 525
jamie@41 526 fund = *(float *)argv;
jamie@52 527 amps = data;
jamie@52 528 freqs = data + n;
jamie@25 529
jamie@1 530 while(n--){
jamie@59 531 if(amps[n]){
jamie@59 532 num += fabs(freqs[n] - n * fund) * XTRACT_SQ(amps[n]);
jamie@59 533 den += XTRACT_SQ(amps[n]);
jamie@59 534 }
jamie@1 535 }
jamie@1 536
jamie@41 537 *result = (2 * num) / (fund * den);
jamie@25 538
jamie@56 539 return XTRACT_SUCCESS;
jamie@1 540 }
jamie@1 541
jamie@1 542
jamie@43 543 int xtract_power(const float *data, const int N, const void *argv, float *result){
jamie@1 544
jamie@56 545 return XTRACT_FEATURE_NOT_IMPLEMENTED;
jamie@25 546
jamie@1 547 }
jamie@1 548
jamie@43 549 int xtract_odd_even_ratio(const float *data, const int N, const void *argv, float *result){
jamie@1 550
jamie@43 551 int M = (N >> 1), n;
jamie@1 552
jamie@59 553 float num = 0.f, den = 0.f, temp;
jamie@44 554
jamie@43 555 for(n = 0; n < M; n++){
jamie@43 556 if((temp = data[n])){
jamie@59 557 if(XTRACT_IS_ODD(n)){
jamie@59 558 num += temp;
jamie@43 559 }
jamie@43 560 else{
jamie@59 561 den += temp;
jamie@43 562 }
jamie@43 563 }
jamie@1 564 }
jamie@1 565
jamie@1 566 *result = num / den;
jamie@25 567
jamie@56 568 return XTRACT_SUCCESS;
jamie@1 569 }
jamie@1 570
jamie@43 571 int xtract_sharpness(const float *data, const int N, const void *argv, float *result){
jamie@1 572
jamie@48 573 int n = N, rv;
jamie@48 574 float sl, g, temp; /* sl = specific loudness */
jamie@48 575
jamie@48 576 sl = g = temp = 0.f;
jamie@48 577
jamie@56 578 if(n > XTRACT_BARK_BANDS)
jamie@56 579 rv = XTRACT_BAD_VECTOR_SIZE;
jamie@48 580 else
jamie@56 581 rv = XTRACT_SUCCESS;
jamie@48 582
jamie@48 583
jamie@48 584 while(n--){
jamie@59 585 sl = powf(data[n], 0.23);
jamie@59 586 g = (n < 15 ? 1.f : 0.066 * expf(0.171 * n));
jamie@49 587 temp += n * g * sl;
jamie@48 588 }
jamie@48 589
jamie@48 590 *result = 0.11 * temp / N;
jamie@48 591
jamie@48 592 return rv;
jamie@25 593
jamie@1 594 }
jamie@1 595
jamie@52 596 int xtract_spectral_slope(const float *data, const int N, const void *argv, float *result){
jamie@1 597
jamie@48 598 const float *freqs, *amps;
jamie@48 599 float f, a,
jamie@56 600 F, A, FA, FXTRACT_SQ; /* sums of freqs, amps, freq * amps, freq squared */
jamie@48 601 int n, M;
jamie@48 602
jamie@56 603 F = A = FA = FXTRACT_SQ = 0.f;
jamie@48 604 n = M = N >> 1;
jamie@48 605
jamie@52 606 amps = data;
jamie@52 607 freqs = data + n;
jamie@48 608
jamie@48 609 while(n--){
jamie@48 610 f = freqs[n];
jamie@48 611 a = amps[n];
jamie@48 612 F += f;
jamie@48 613 A += a;
jamie@48 614 FA += f * a;
jamie@56 615 FXTRACT_SQ += f * f;
jamie@48 616 }
jamie@48 617
jamie@56 618 *result = (1.f / A) * (M * FA - F * A) / (M * FXTRACT_SQ - F * F);
jamie@48 619
jamie@56 620 return XTRACT_SUCCESS;
jamie@25 621
jamie@1 622 }
jamie@1 623
jamie@45 624 int xtract_lowest_value(const float *data, const int N, const void *argv, float *result){
jamie@25 625
jamie@45 626 int n = N;
jamie@45 627 float temp;
jamie@45 628
jamie@46 629 *result = data[--n];
jamie@45 630
jamie@45 631 while(n--){
jamie@45 632 if((temp = data[n]) > *(float *)argv)
jamie@56 633 *result = XTRACT_MIN(*result, data[n]);
jamie@45 634 }
jamie@45 635
jamie@56 636 return XTRACT_SUCCESS;
jamie@45 637 }
jamie@45 638
jamie@45 639 int xtract_highest_value(const float *data, const int N, const void *argv, float *result){
jamie@45 640
jamie@1 641 int n = N;
jamie@1 642
jamie@46 643 *result = data[--n];
jamie@44 644
jamie@45 645 while(n--)
jamie@56 646 *result = XTRACT_MAX(*result, data[n]);
jamie@44 647
jamie@56 648 return XTRACT_SUCCESS;
jamie@1 649 }
jamie@1 650
jamie@45 651
jamie@45 652 int xtract_sum(const float *data, const int N, const void *argv, float *result){
jamie@45 653
jamie@45 654 int n = N;
jamie@45 655
jamie@45 656 while(n--)
jamie@45 657 *result += *data++;
jamie@45 658
jamie@56 659 return XTRACT_SUCCESS;
jamie@45 660
jamie@45 661 }
jamie@45 662
jamie@59 663 int xtract_nonzero_count(const float *data, const int N, const void *argv, float *result){
jamie@59 664
jamie@59 665 int n = N;
jamie@59 666
jamie@59 667 while(n--)
jamie@59 668 *result += (*data++ ? 1 : 0);
jamie@59 669
jamie@59 670 return XTRACT_SUCCESS;
jamie@59 671
jamie@59 672 }
jamie@59 673
jamie@43 674 int xtract_hps(const float *data, const int N, const void *argv, float *result){
jamie@1 675
jamie@1 676 int n = N, M, m, l, peak_index, position1_lwr;
jamie@1 677 float *coeffs2, *coeffs3, *product, L,
jamie@25 678 largest1_lwr, peak, ratio1, sr;
jamie@1 679
jamie@25 680 sr = *(float*)argv;
jamie@78 681 if(sr == 0)
jamie@78 682 sr = 44100.f;
jamie@25 683
jamie@1 684 coeffs2 = (float *)malloc(N * sizeof(float));
jamie@1 685 coeffs3 = (float *)malloc(N * sizeof(float));
jamie@1 686 product = (float *)malloc(N * sizeof(float));
jamie@25 687
jamie@1 688 while(n--) coeffs2[n] = coeffs3[n] = 1;
jamie@1 689
jamie@1 690 M = N >> 1;
jamie@1 691 L = N / 3;
jamie@1 692
jamie@1 693 while(M--){
jamie@25 694 m = M << 1;
jamie@25 695 coeffs2[M] = (data[m] + data[m+1]) * 0.5f;
jamie@1 696
jamie@25 697 if(M < L){
jamie@25 698 l = M * 3;
jamie@25 699 coeffs3[M] = (data[l] + data[l+1] + data[l+2]) / 3;
jamie@25 700 }
jamie@1 701 }
jamie@25 702
jamie@1 703 peak_index = peak = 0;
jamie@25 704
jamie@1 705 for(n = 1; n < N; n++){
jamie@25 706 product[n] = data[n] * coeffs2[n] * coeffs3[n];
jamie@25 707 if(product[n] > peak){
jamie@25 708 peak_index = n;
jamie@25 709 peak = product[n];
jamie@25 710 }
jamie@1 711 }
jamie@1 712
jamie@1 713 largest1_lwr = position1_lwr = 0;
jamie@1 714
jamie@1 715 for(n = 0; n < N; n++){
jamie@25 716 if(data[n] > largest1_lwr && n != peak_index){
jamie@25 717 largest1_lwr = data[n];
jamie@25 718 position1_lwr = n;
jamie@25 719 }
jamie@1 720 }
jamie@1 721
jamie@1 722 ratio1 = data[position1_lwr] / data[peak_index];
jamie@1 723
jamie@1 724 if(position1_lwr > peak_index * 0.4 && position1_lwr <
jamie@25 725 peak_index * 0.6 && ratio1 > 0.1)
jamie@25 726 peak_index = position1_lwr;
jamie@1 727
jamie@22 728 *result = sr / (float)peak_index;
jamie@25 729
jamie@1 730 free(coeffs2);
jamie@1 731 free(coeffs3);
jamie@1 732 free(product);
jamie@25 733
jamie@56 734 return XTRACT_SUCCESS;
jamie@1 735 }
jamie@5 736
jamie@5 737
jamie@43 738 int xtract_f0(const float *data, const int N, const void *argv, float *result){
jamie@5 739
jamie@78 740 int M, tau, n;
jamie@78 741 float sr;
jamie@43 742 size_t bytes;
jamie@43 743 float f0, err_tau_1, err_tau_x, array_max,
jamie@43 744 threshold_peak, threshold_centre,
jamie@43 745 *input;
jamie@22 746
jamie@25 747 sr = *(float *)argv;
jamie@78 748 if(sr == 0)
jamie@78 749 sr = 44100.f;
jamie@43 750
jamie@43 751 input = (float *)malloc(bytes = N * sizeof(float));
jamie@43 752 input = memcpy(input, data, bytes);
jamie@25 753 /* threshold_peak = *((float *)argv+1);
jamie@25 754 threshold_centre = *((float *)argv+2);
jamie@25 755 printf("peak: %.2f\tcentre: %.2f\n", threshold_peak, threshold_centre);*/
jamie@25 756 /* add temporary dynamic control over thresholds to test clipping effects */
jamie@22 757
jamie@25 758 /* FIX: tweak and make into macros */
jamie@25 759 threshold_peak = .8;
jamie@25 760 threshold_centre = .3;
jamie@25 761 M = N >> 1;
jamie@25 762 err_tau_1 = 0;
jamie@25 763 array_max = 0;
jamie@25 764
jamie@25 765 /* Find the array max */
jamie@25 766 for(n = 0; n < N; n++){
jamie@43 767 if (input[n] > array_max)
jamie@43 768 array_max = input[n];
jamie@12 769 }
jamie@25 770
jamie@25 771 threshold_peak *= array_max;
jamie@25 772
jamie@25 773 /* peak clip */
jamie@25 774 for(n = 0; n < N; n++){
jamie@43 775 if(input[n] > threshold_peak)
jamie@43 776 input[n] = threshold_peak;
jamie@43 777 else if(input[n] < -threshold_peak)
jamie@43 778 input[n] = -threshold_peak;
jamie@25 779 }
jamie@25 780
jamie@25 781 threshold_centre *= array_max;
jamie@25 782
jamie@25 783 /* Centre clip */
jamie@25 784 for(n = 0; n < N; n++){
jamie@43 785 if (input[n] < threshold_centre)
jamie@43 786 input[n] = 0;
jamie@25 787 else
jamie@43 788 input[n] -= threshold_centre;
jamie@25 789 }
jamie@25 790
jamie@25 791 /* Estimate fundamental freq */
jamie@25 792 for (n = 1; n < M; n++)
jamie@43 793 err_tau_1 = err_tau_1 + fabs(input[n] - input[n+1]);
jamie@25 794 /* FIX: this doesn't pose too much load if it returns 'early', but if it can't find f0, load can be significant for larger block sizes M^2 iterations! */
jamie@25 795 for (tau = 2; tau < M; tau++){
jamie@25 796 err_tau_x = 0;
jamie@25 797 for (n = 1; n < M; n++){
jamie@43 798 err_tau_x = err_tau_x + fabs(input[n] - input[n+tau]);
jamie@25 799 }
jamie@25 800 if (err_tau_x < err_tau_1) {
jamie@25 801 f0 = sr / (tau + (err_tau_x / err_tau_1));
jamie@25 802 *result = f0;
jamie@43 803 free(input);
jamie@56 804 return XTRACT_SUCCESS;
jamie@25 805 }
jamie@25 806 }
jamie@43 807 *result = -0;
jamie@43 808 free(input);
jamie@56 809 return XTRACT_NO_RESULT;
jamie@5 810 }
jamie@43 811
jamie@43 812 int xtract_failsafe_f0(const float *data, const int N, const void *argv, float *result){
jamie@44 813
jamie@59 814 float *spectrum = NULL, argf[2], *peaks = NULL, return_code, sr;
jamie@44 815
jamie@43 816 return_code = xtract_f0(data, N, argv, result);
jamie@44 817
jamie@56 818 if(return_code == XTRACT_NO_RESULT){
jamie@44 819
jamie@59 820 sr = *(float *)argv;
jamie@78 821 if(sr == 0)
jamie@78 822 sr = 44100.f;
jamie@59 823 spectrum = (float *)malloc(N * sizeof(float));
jamie@43 824 peaks = (float *)malloc(N * sizeof(float));
jamie@59 825 argf[0] = sr;
jamie@59 826 argf[1] = XTRACT_MAGNITUDE_SPECTRUM;
jamie@59 827 xtract_spectrum(data, N, argf, spectrum);
jamie@59 828 argf[1] = 10.f;
jamie@59 829 xtract_peak_spectrum(spectrum, N >> 1, argf, peaks);
jamie@43 830 argf[0] = 0.f;
jamie@59 831 xtract_lowest_value(peaks+(N >> 1), N >> 1, argf, result);
jamie@44 832
jamie@59 833 free(spectrum);
jamie@43 834 free(peaks);
jamie@43 835 }
jamie@43 836
jamie@56 837 return XTRACT_SUCCESS;
jamie@43 838
jamie@43 839 }
jamie@44 840