annotate src/scalar.c @ 187:48a90b436be5

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