annotate src/scalar.c @ 144:7fbca00c2c05

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