Mercurial > hg > libxtract
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 |