comparison src/scalar.c @ 43:4a36f70a76e9

Numerous fixes and enhancements, see ChangeLog.
author Jamie Bullock <jamie@postlude.co.uk>
date Fri, 15 Dec 2006 21:17:12 +0000
parents 84e69b155098
children b2e7e24c9a9c
comparison
equal deleted inserted replaced
42:84e69b155098 43:4a36f70a76e9
22 /* xtract_scalar.c: defines functions that extract a feature as a single value from an input vector */ 22 /* xtract_scalar.c: defines functions that extract a feature as a single value from an input vector */
23 23
24 #include "xtract/libxtract.h" 24 #include "xtract/libxtract.h"
25 #include "math.h" 25 #include "math.h"
26 #include <stdlib.h> 26 #include <stdlib.h>
27 27 #include <string.h>
28 int xtract_mean(float *data, int N, void *argv, float *result){ 28
29 int xtract_mean(const float *data, const int N, const void *argv, float *result){
29 30
30 int n = N; 31 int n = N;
31 32
32 while(n--) 33 while(n--)
33 *result += data[n]; 34 *result += data[n];
35 *result /= N; 36 *result /= N;
36 37
37 return SUCCESS; 38 return SUCCESS;
38 } 39 }
39 40
40 int xtract_variance(float *data, int N, void *argv, float *result){ 41 int xtract_variance(const float *data, const int N, const void *argv, float *result){
41 42
42 int n = N; 43 int n = N;
43 44
44 while(n--) 45 while(n--)
45 *result += data[n] - *(float *)argv; 46 *result += pow(data[n] - *(float *)argv, 2);
46 47
47 *result = SQ(*result) / (N - 1); 48 *result = *result / (N - 1);
48 49
49 return SUCCESS; 50 return SUCCESS;
50 } 51 }
51 52
52 int xtract_standard_deviation(float *data, int N, void *argv, float *result){ 53 int xtract_standard_deviation(const float *data, const int N, const void *argv, float *result){
53 54
54 *result = sqrt(*(float *)argv); 55 *result = sqrt(*(float *)argv);
55 56
56 return SUCCESS; 57 return SUCCESS;
57 } 58 }
58 59
59 int xtract_average_deviation(float *data, int N, void *argv, float *result){ 60 int xtract_average_deviation(const float *data, const int N, const void *argv, float *result){
60 61
61 int n = N; 62 int n = N;
62 63
63 while(n--) 64 while(n--)
64 *result += fabs(data[n] - *(float *)argv); 65 *result += fabs(data[n] - *(float *)argv);
66 *result /= N; 67 *result /= N;
67 68
68 return SUCCESS; 69 return SUCCESS;
69 } 70 }
70 71
71 int xtract_skewness(float *data, int N, void *argv, float *result){ 72 int xtract_skewness(const float *data, const int N, const void *argv, float *result){
72 73
73 int n = N; 74 int n = N;
74 75
75 float temp; 76 float temp;
76 77
82 *result /= N; 83 *result /= N;
83 84
84 return SUCCESS; 85 return SUCCESS;
85 } 86 }
86 87
87 int xtract_kurtosis(float *data, int N, void *argv, float *result){ 88 int xtract_kurtosis(const float *data, const int N, const void *argv, float *result){
88 89
89 int n = N; 90 int n = N;
90 91
91 float temp; 92 float temp;
92 93
100 101
101 return SUCCESS; 102 return SUCCESS;
102 } 103 }
103 104
104 105
105 int xtract_centroid(float *data, int N, void *argv, float *result){ 106 int xtract_centroid(const float *data, const int N, const void *argv, float *result){
106 107
107 int n = (N >> 1); 108 int n = (N >> 1);
108 109
109 float *freqs, *amps, FA = 0.f, A = 0.f; 110 const float *freqs, *amps;
111 float FA = 0.f, A = 0.f;
110 112
111 freqs = data; 113 freqs = data;
112 amps = data + n; 114 amps = data + n;
113 115
114 while(n--){ 116 while(n--){
119 *result = FA / A; 121 *result = FA / A;
120 122
121 return SUCCESS; 123 return SUCCESS;
122 } 124 }
123 125
124 int xtract_irregularity_k(float *data, int N, void *argv, float *result){ 126 int xtract_irregularity_k(const float *data, const int N, const void *argv, float *result){
125 127
126 int n, 128 int n,
127 M = N - 1; 129 M = N - 1;
128 130
129 for(n = 1; n < M; n++) 131 for(n = 1; n < M; n++)
130 *result += fabs(data[n] - (data[n-1] + data[n] + data[n+1]) / 3); 132 *result += fabs(data[n] - (data[n-1] + data[n] + data[n+1]) / 3);
131 133
132 return SUCCESS; 134 return SUCCESS;
133 } 135 }
134 136
135 int xtract_irregularity_j(float *data, int N, void *argv, float *result){ 137 int xtract_irregularity_j(const float *data, const int N, const void *argv, float *result){
136 138
137 int n = N; 139 int n = N;
138 140
139 float num = 0.f, den = 0.f; 141 float num = 0.f, den = 0.f;
140 142
146 *result = num / den; 148 *result = num / den;
147 149
148 return SUCCESS; 150 return SUCCESS;
149 } 151 }
150 152
151 int xtract_tristimulus_1(float *data, int N, void *argv, float *result){ 153 int xtract_tristimulus_1(const float *data, const int N, const void *argv, float *result){
152 154
153 int n = N; 155 int n = N;
154 156
155 float den, p1, temp; 157 float den, p1, temp;
156 158
167 *result = p1 / den; 169 *result = p1 / den;
168 170
169 return SUCCESS; 171 return SUCCESS;
170 } 172 }
171 173
172 int xtract_tristimulus_2(float *data, int N, void *argv, float *result){ 174 int xtract_tristimulus_2(const float *data, const int N, const void *argv, float *result){
173 175
174 int n = N; 176 int n = N;
175 177
176 float den, p2, p3, p4, temp; 178 float den, p2, p3, p4, temp;
177 179
192 *result = (p2 + p3 + p4) / den; 194 *result = (p2 + p3 + p4) / den;
193 195
194 return SUCCESS; 196 return SUCCESS;
195 } 197 }
196 198
197 int xtract_tristimulus_3(float *data, int N, void *argv, float *result){ 199 int xtract_tristimulus_3(const float *data, const int N, const void *argv, float *result){
198 200
199 int n = N, count = 0; 201 int n = N, count = 0;
200 202
201 float den, num, temp; 203 float den, num, temp;
202 204
214 *result = num / den; 216 *result = num / den;
215 217
216 return SUCCESS; 218 return SUCCESS;
217 } 219 }
218 220
219 int xtract_smoothness(float *data, int N, void *argv, float *result){ 221 int xtract_smoothness(const float *data, const int N, const void *argv, float *result){
220 222
221 int n = N; 223 int n = N;
222 224
223 if (data[0] <= 0) data[0] = 1; 225 float *input;
224 if (data[1] <= 0) data[1] = 1; 226
227 input = (float *)malloc(N * sizeof(float));
228 input = memcpy(input, data, N * sizeof(float));
229
230 if (input[0] <= 0) input[0] = 1;
231 if (input[1] <= 0) input[1] = 1;
225 232
226 for(n = 2; n < N; n++){ 233 for(n = 2; n < N; n++){
227 if(data[n] <= 0) data[n] = 1; 234 if(input[n] <= 0) input[n] = 1;
228 *result += abs(20 * log(data[n-1]) - (20 * log(data[n-2]) + 235 *result += abs(20 * log(input[n-1]) - (20 * log(input[n-2]) +
229 20 * log(data[n-1]) + 20 * log(data[n])) / 3); 236 20 * log(input[n-1]) + 20 * log(input[n])) / 3);
230 } 237 }
231 238
232 return SUCCESS; 239 free(input);
233 } 240
234 241 return SUCCESS;
235 int xtract_spread(float *data, int N, void *argv, float *result){ 242 }
243
244 int xtract_spread(const float *data, const int N, const void *argv, float *result){
236 245
237 int n = N; 246 int n = N;
238 247
239 float num = 0.f, den = 0.f, tmp; 248 float num = 0.f, den = 0.f, tmp;
240 249
247 *result = sqrt(num / den); 256 *result = sqrt(num / den);
248 257
249 return SUCCESS; 258 return SUCCESS;
250 } 259 }
251 260
252 int xtract_zcr(float *data, int N, void *argv, float *result){ 261 int xtract_zcr(const float *data, const int N, const void *argv, float *result){
253 262
254 int n = N; 263 int n = N;
255 264
256 for(n = 1; n < N; n++) 265 for(n = 1; n < N; n++)
257 if(data[n] * data[n-1] < 0) (*result)++; 266 if(data[n] * data[n-1] < 0) (*result)++;
259 *result /= N; 268 *result /= N;
260 269
261 return SUCCESS; 270 return SUCCESS;
262 } 271 }
263 272
264 int xtract_rolloff(float *data, int N, void *argv, float *result){ 273 int xtract_rolloff(const float *data, const int N, const void *argv, float *result){
265 274
266 int n = N; 275 int n = N;
267 float pivot, temp; 276 float pivot, temp;
268 277
269 pivot = temp = 0.f; 278 pivot = temp = 0.f;
278 *result = (n / (float)N) * (((float *)argv)[1] * .5); 287 *result = (n / (float)N) * (((float *)argv)[1] * .5);
279 288
280 return SUCCESS; 289 return SUCCESS;
281 } 290 }
282 291
283 int xtract_loudness(float *data, int N, void *argv, float *result){ 292 int xtract_loudness(const float *data, const int N, const void *argv, float *result){
284 293
285 int n = BARK_BANDS; 294 int n = BARK_BANDS;
286 295
287 /*if(n != N) return BAD_VECTOR_SIZE; */ 296 /*if(n != N) return BAD_VECTOR_SIZE; */
288 297
291 300
292 return SUCCESS; 301 return SUCCESS;
293 } 302 }
294 303
295 304
296 int xtract_flatness(float *data, int N, void *argv, float *result){ 305 int xtract_flatness(const float *data, const int N, const void *argv, float *result){
297 306
298 int n; 307 int n;
299 308
300 float num, den, temp; 309 float num, den, temp, *tmp, prescale;
301 310 int lower, upper;
311
312 tmp = (float *)argv;
313 lower = (int)tmp[0];
314 upper = (int)tmp[1];
315 prescale = (float)tmp[2];
316
317 upper = (upper > N ? N : upper);
318 lower = (lower < 0.f ? 0.f : lower);
319
302 den = temp = num = 0.f; 320 den = temp = num = 0.f;
303 321
304 for(n = 0; n < N; n++){ 322 for(n = lower; n < upper; n++){
305 if((temp = data[n])){ 323 if((temp = data[n] * prescale)){
306 if(!num) 324 if(!num)
307 num = den = temp; 325 num = den = temp;
308 else{ 326 else{
309 num *= temp; 327 num *= temp;
310 den += temp; 328 den += temp;
318 *result = num / den; 336 *result = num / den;
319 337
320 return SUCCESS; 338 return SUCCESS;
321 } 339 }
322 340
323 int xtract_tonality(float *data, int N, void *argv, float *result){ 341 int xtract_tonality(const float *data, const int N, const void *argv, float *result){
324 342
325 float sfmdb, sfm; 343 float sfmdb, sfm;
326 344
327 sfm = *(float *)argv; 345 sfm = *(float *)argv;
328 346
331 *result = MIN(sfmdb, 1); 349 *result = MIN(sfmdb, 1);
332 350
333 return SUCCESS; 351 return SUCCESS;
334 } 352 }
335 353
336 int xtract_crest(float *data, int N, void *argv, float *result){ 354 int xtract_crest(const float *data, const int N, const void *argv, float *result){
337 355
338 return FEATURE_NOT_IMPLEMENTED; 356 return FEATURE_NOT_IMPLEMENTED;
339 357
340 } 358 }
341 359
342 int xtract_noisiness(float *data, int N, void *argv, float *result){ 360 int xtract_noisiness(const float *data, const int N, const void *argv, float *result){
343 361
344 return FEATURE_NOT_IMPLEMENTED; 362 return FEATURE_NOT_IMPLEMENTED;
345 363
346 } 364 }
347 365
348 int xtract_rms_amplitude(float *data, int N, void *argv, float *result){ 366 int xtract_rms_amplitude(const float *data, const int N, const void *argv, float *result){
349 367
350 int n = N; 368 int n = N;
351 369
352 while(n--) *result += SQ(data[n]); 370 while(n--) *result += SQ(data[n]);
353 371
354 *result = sqrt(*result / N); 372 *result = sqrt(*result / N);
355 373
356 return SUCCESS; 374 return SUCCESS;
357 } 375 }
358 376
359 int xtract_inharmonicity(float *data, int N, void *argv, float *result){ 377 int xtract_inharmonicity(const float *data, const int N, const void *argv, float *result){
360 378
361 int n = N >> 1; 379 int n = N >> 1;
362 float num = 0.f, den = 0.f, 380 float num = 0.f, den = 0.f, fund;
363 fund, *freqs, *amps; 381 const float *freqs, *amps;
364 382
365 fund = *(float *)argv; 383 fund = *(float *)argv;
366 freqs = data; 384 freqs = data;
367 amps = data + n; 385 amps = data + n;
368 386
375 393
376 return SUCCESS; 394 return SUCCESS;
377 } 395 }
378 396
379 397
380 int xtract_power(float *data, int N, void *argv, float *result){ 398 int xtract_power(const float *data, const int N, const void *argv, float *result){
381 399
382 return FEATURE_NOT_IMPLEMENTED; 400 return FEATURE_NOT_IMPLEMENTED;
383 401
384 } 402 }
385 403
386 int xtract_odd_even_ratio(float *data, int N, void *argv, float *result){ 404 int xtract_odd_even_ratio(const float *data, const int N, const void *argv, float *result){
387 405
388 int n = N, j, k; 406 int M = (N >> 1), n;
389 407
390 float num = 0.f, den = 0.f; 408 float num = 0.f, den = 0.f, temp, f0;
391 409
392 while(n--){ 410 f0 = *(float *)argv;
393 j = n * 2; 411
394 k = j - 1; 412 for(n = 0; n < M; n++){
395 num += data[k]; 413 if((temp = data[n])){
396 den += data[j]; 414 if(((int)(rintf(temp / f0)) % 2) != 0){
415 num += data[M + n];
416 }
417 else{
418 den += data[M + n];
419 }
420 }
397 } 421 }
398 422
399 *result = num / den; 423 *result = num / den;
400 424
401 return SUCCESS; 425 return SUCCESS;
402 } 426 }
403 427
404 int xtract_sharpness(float *data, int N, void *argv, float *result){ 428 int xtract_sharpness(const float *data, const int N, const void *argv, float *result){
405 429
406 return FEATURE_NOT_IMPLEMENTED; 430 return FEATURE_NOT_IMPLEMENTED;
407 431
408 } 432 }
409 433
410 int xtract_slope(float *data, int N, void *argv, float *result){ 434 int xtract_slope(const float *data, const int N, const void *argv, float *result){
411 435
412 return FEATURE_NOT_IMPLEMENTED; 436 return FEATURE_NOT_IMPLEMENTED;
413 437
414 } 438 }
415 439
416 int xtract_lowest_match(float *data, int N, void *argv, float *result){ 440 int xtract_lowest(const float *data, const int N, const void *argv, float *result){
417 441
418 float lowest_match = SR_LIMIT; 442 float lower, upper, lowest;
419 int n = N; 443 int n = N;
444
445 lower = *(float *)argv;
446 upper = *((float *)argv+1);
447
448 lowest = upper;
420 449
421 while(n--) { 450 while(n--) {
422 if(data[n] > 0) 451 if(data[n] > lower)
423 lowest_match = MIN(lowest_match, data[n]); 452 *result = MIN(lowest, data[n]);
424 } 453 }
425 454
426 *result = (lowest_match == SR_LIMIT ? 0 : lowest_match); 455 *result = (*result == upper ? -0 : *result);
427 456
428 return SUCCESS; 457 return SUCCESS;
429 } 458 }
430 459
431 int xtract_hps(float *data, int N, void *argv, float *result){ 460 int xtract_hps(const float *data, const int N, const void *argv, float *result){
432 461
433 int n = N, M, m, l, peak_index, position1_lwr; 462 int n = N, M, m, l, peak_index, position1_lwr;
434 float *coeffs2, *coeffs3, *product, L, 463 float *coeffs2, *coeffs3, *product, L,
435 largest1_lwr, peak, ratio1, sr; 464 largest1_lwr, peak, ratio1, sr;
436 465
488 517
489 return SUCCESS; 518 return SUCCESS;
490 } 519 }
491 520
492 521
493 int xtract_f0(float *data, int N, void *argv, float *result){ 522 int xtract_f0(const float *data, const int N, const void *argv, float *result){
494 523
495 int M, sr, tau, n; 524 int M, sr, tau, n;
496 float f0, err_tau_1, err_tau_x, array_max, threshold_peak, threshold_centre; 525 size_t bytes;
526 float f0, err_tau_1, err_tau_x, array_max,
527 threshold_peak, threshold_centre,
528 *input;
497 529
498 sr = *(float *)argv; 530 sr = *(float *)argv;
531
532 input = (float *)malloc(bytes = N * sizeof(float));
533 input = memcpy(input, data, bytes);
499 /* threshold_peak = *((float *)argv+1); 534 /* threshold_peak = *((float *)argv+1);
500 threshold_centre = *((float *)argv+2); 535 threshold_centre = *((float *)argv+2);
501 printf("peak: %.2f\tcentre: %.2f\n", threshold_peak, threshold_centre);*/ 536 printf("peak: %.2f\tcentre: %.2f\n", threshold_peak, threshold_centre);*/
502 /* add temporary dynamic control over thresholds to test clipping effects */ 537 /* add temporary dynamic control over thresholds to test clipping effects */
503 538
508 err_tau_1 = 0; 543 err_tau_1 = 0;
509 array_max = 0; 544 array_max = 0;
510 545
511 /* Find the array max */ 546 /* Find the array max */
512 for(n = 0; n < N; n++){ 547 for(n = 0; n < N; n++){
513 if (data[n] > array_max) 548 if (input[n] > array_max)
514 array_max = data[n]; 549 array_max = input[n];
515 } 550 }
516 551
517 threshold_peak *= array_max; 552 threshold_peak *= array_max;
518 553
519 /* peak clip */ 554 /* peak clip */
520 for(n = 0; n < N; n++){ 555 for(n = 0; n < N; n++){
521 if(data[n] > threshold_peak) 556 if(input[n] > threshold_peak)
522 data[n] = threshold_peak; 557 input[n] = threshold_peak;
523 else if(data[n] < -threshold_peak) 558 else if(input[n] < -threshold_peak)
524 data[n] = -threshold_peak; 559 input[n] = -threshold_peak;
525 } 560 }
526 561
527 threshold_centre *= array_max; 562 threshold_centre *= array_max;
528 563
529 /* Centre clip */ 564 /* Centre clip */
530 for(n = 0; n < N; n++){ 565 for(n = 0; n < N; n++){
531 if (data[n] < threshold_centre) 566 if (input[n] < threshold_centre)
532 data[n] = 0; 567 input[n] = 0;
533 else 568 else
534 data[n] -= threshold_centre; 569 input[n] -= threshold_centre;
535 } 570 }
536 571
537 /* Estimate fundamental freq */ 572 /* Estimate fundamental freq */
538 for (n = 1; n < M; n++) 573 for (n = 1; n < M; n++)
539 err_tau_1 = err_tau_1 + fabs(data[n] - data[n+1]); 574 err_tau_1 = err_tau_1 + fabs(input[n] - input[n+1]);
540 /* 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! */ 575 /* 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! */
541 for (tau = 2; tau < M; tau++){ 576 for (tau = 2; tau < M; tau++){
542 err_tau_x = 0; 577 err_tau_x = 0;
543 for (n = 1; n < M; n++){ 578 for (n = 1; n < M; n++){
544 err_tau_x = err_tau_x + fabs(data[n] - data[n+tau]); 579 err_tau_x = err_tau_x + fabs(input[n] - input[n+tau]);
545 } 580 }
546 if (err_tau_x < err_tau_1) { 581 if (err_tau_x < err_tau_1) {
547 f0 = sr / (tau + (err_tau_x / err_tau_1)); 582 f0 = sr / (tau + (err_tau_x / err_tau_1));
548 *result = f0; 583 *result = f0;
584 free(input);
549 return SUCCESS; 585 return SUCCESS;
550 } 586 }
551 } 587 }
588 *result = -0;
589 free(input);
552 return NO_RESULT; 590 return NO_RESULT;
553 } 591 }
592
593 int xtract_failsafe_f0(const float *data, const int N, const void *argv, float *result){
594
595 float *magnitudes = NULL, argf[2], *peaks = NULL, return_code;
596
597 return_code = xtract_f0(data, N, argv, result);
598
599 if(return_code == NO_RESULT){
600
601 magnitudes = (float *)malloc(N * sizeof(float));
602 peaks = (float *)malloc(N * sizeof(float));
603 xtract_magnitude_spectrum(data, N, NULL, magnitudes);
604 argf[0] = 10.f;
605 argf[1] = *(float *)argv;
606 xtract_peaks(magnitudes, N, argf, peaks);
607 argf[0] = 0.f;
608 argf[1] = N >> 1;
609 xtract_lowest(peaks, argf[1], argf, result);
610
611 free(magnitudes);
612 free(peaks);
613 }
614
615 return SUCCESS;
616
617 }
618