comparison src/scalar.c @ 140:67f6b6e63d45

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