aboutsummaryrefslogtreecommitdiff
path: root/src/scalar.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/scalar.c')
-rw-r--r--src/scalar.c572
1 files changed, 330 insertions, 242 deletions
diff --git a/src/scalar.c b/src/scalar.c
index a82dda0..4aab5a4 100644
--- a/src/scalar.c
+++ b/src/scalar.c
@@ -1,5 +1,5 @@
/* libxtract feature extraction library
- *
+ *
* Copyright (C) 2006 Jamie Bullock
*
* This program is free software; you can redistribute it and/or modify
@@ -14,7 +14,7 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*/
@@ -33,79 +33,85 @@
#include "xtract_macros_private.h"
#ifndef powf
- #define powf pow
+#define powf pow
#endif
#ifndef expf
- #define expf exp
+#define expf exp
#endif
#ifndef sqrtf
- #define sqrtf sqrt
+#define sqrtf sqrt
#endif
#ifndef fabsf
- #define fabsf fabs
+#define fabsf fabs
#endif
-void test(void){
+void test(void)
+{
printf("Hello world\n");
#ifdef WORDS_BIGENDIAN
printf("Big endian!\n");
#endif
}
-int xtract_mean(const float *data, const int N, const void *argv, float *result){
+int xtract_mean(const float *data, const int N, const void *argv, float *result)
+{
int n = N;
-
+
*result = 0.f;
while(n--)
- *result += data[n];
-
+ *result += data[n];
+
*result /= N;
return XTRACT_SUCCESS;
}
-int xtract_variance(const float *data, const int N, const void *argv, float *result){
+int xtract_variance(const float *data, const int N, const void *argv, float *result)
+{
int n = N;
*result = 0.f;
while(n--)
- *result += powf(data[n] - *(float *)argv, 2);
+ *result += powf(data[n] - *(float *)argv, 2);
*result = *result / (N - 1);
return XTRACT_SUCCESS;
}
-int xtract_standard_deviation(const float *data, const int N, const void *argv, float *result){
+int xtract_standard_deviation(const float *data, const int N, const void *argv, float *result)
+{
*result = sqrtf(*(float *)argv);
return XTRACT_SUCCESS;
}
-int xtract_average_deviation(const float *data, const int N, const void *argv, float *result){
+int xtract_average_deviation(const float *data, const int N, const void *argv, float *result)
+{
int n = N;
*result = 0.f;
while(n--)
- *result += fabsf(data[n] - *(float *)argv);
+ *result += fabsf(data[n] - *(float *)argv);
*result /= N;
return XTRACT_SUCCESS;
}
-int xtract_skewness(const float *data, const int N, const void *argv, float *result){
+int xtract_skewness(const float *data, const int N, const void *argv, float *result)
+{
int n = N;
@@ -113,9 +119,10 @@ int xtract_skewness(const float *data, const int N, const void *argv, float *re
*result = 0.f;
- while(n--){
- temp = (data[n] - ((float *)argv)[0]) / ((float *)argv)[1];
- *result += powf(temp, 3);
+ while(n--)
+ {
+ temp = (data[n] - ((float *)argv)[0]) / ((float *)argv)[1];
+ *result += powf(temp, 3);
}
*result /= N;
@@ -124,7 +131,8 @@ int xtract_skewness(const float *data, const int N, const void *argv, float *re
return XTRACT_SUCCESS;
}
-int xtract_kurtosis(const float *data, const int N, const void *argv, float *result){
+int xtract_kurtosis(const float *data, const int N, const void *argv, float *result)
+{
int n = N;
@@ -132,9 +140,10 @@ int xtract_kurtosis(const float *data, const int N, const void *argv, float *re
*result = 0.f;
- while(n--){
- temp = (data[n] - ((float *)argv)[0]) / ((float *)argv)[1];
- *result += powf(temp, 4);
+ while(n--)
+ {
+ temp = (data[n] - ((float *)argv)[0]) / ((float *)argv)[1];
+ *result += powf(temp, 4);
}
*result /= N;
@@ -143,7 +152,8 @@ int xtract_kurtosis(const float *data, const int N, const void *argv, float *re
return XTRACT_SUCCESS;
}
-int xtract_spectral_centroid(const float *data, const int N, const void *argv, float *result){
+int xtract_spectral_centroid(const float *data, const int N, const void *argv, float *result)
+{
int n = (N >> 1);
@@ -153,9 +163,10 @@ int xtract_spectral_centroid(const float *data, const int N, const void *argv,
amps = data;
freqs = data + n;
- while(n--){
- FA += freqs[n] * amps[n];
- A += amps[n];
+ while(n--)
+ {
+ FA += freqs[n] * amps[n];
+ A += amps[n];
}
if(A == 0.f)
@@ -166,13 +177,15 @@ int xtract_spectral_centroid(const float *data, const int N, const void *argv,
return XTRACT_SUCCESS;
}
-int xtract_spectral_mean(const float *data, const int N, const void *argv, float *result){
+int xtract_spectral_mean(const float *data, const int N, const void *argv, float *result)
+{
return xtract_spectral_centroid(data, N, argv, result);
}
-int xtract_spectral_variance(const float *data, const int N, const void *argv, float *result){
+int xtract_spectral_variance(const float *data, const int N, const void *argv, float *result)
+{
int m;
float A = 0.f;
@@ -185,7 +198,8 @@ int xtract_spectral_variance(const float *data, const int N, const void *argv, f
*result = 0.f;
- while(m--){
+ while(m--)
+ {
A += amps[m];
*result += powf(freqs[m] - ((float *)argv)[0], 2) * amps[m];
}
@@ -195,9 +209,10 @@ int xtract_spectral_variance(const float *data, const int N, const void *argv, f
return XTRACT_SUCCESS;
}
-int xtract_spectral_standard_deviation(const float *data, const int N, const void *argv, float *result){
+int xtract_spectral_standard_deviation(const float *data, const int N, const void *argv, float *result)
+{
- *result = sqrtf(*(float *)argv);
+ *result = sqrtf(*(float *)argv);
return XTRACT_SUCCESS;
}
@@ -225,7 +240,8 @@ int xtract_spectral_standard_deviation(const float *data, const int N, const voi
return XTRACT_SUCCESS;
}*/
-int xtract_spectral_skewness(const float *data, const int N, const void *argv, float *result){
+int xtract_spectral_skewness(const float *data, const int N, const void *argv, float *result)
+{
int m;
const float *freqs, *amps;
@@ -245,7 +261,8 @@ int xtract_spectral_skewness(const float *data, const int N, const void *argv,
return XTRACT_SUCCESS;
}
-int xtract_spectral_kurtosis(const float *data, const int N, const void *argv, float *result){
+int xtract_spectral_kurtosis(const float *data, const int N, const void *argv, float *result)
+{
int m;
const float *freqs, *amps;
@@ -266,28 +283,31 @@ int xtract_spectral_kurtosis(const float *data, const int N, const void *argv,
return XTRACT_SUCCESS;
}
-int xtract_irregularity_k(const float *data, const int N, const void *argv, float *result){
+int xtract_irregularity_k(const float *data, const int N, const void *argv, float *result)
+{
int n,
- M = N - 1;
-
+ M = N - 1;
+
*result = 0.f;
-
+
for(n = 1; n < M; n++)
- *result += fabsf(data[n] - (data[n-1] + data[n] + data[n+1]) / 3.f);
+ *result += fabsf(data[n] - (data[n-1] + data[n] + data[n+1]) / 3.f);
return XTRACT_SUCCESS;
}
-int xtract_irregularity_j(const float *data, const int N, const void *argv, float *result){
+int xtract_irregularity_j(const float *data, const int N, const void *argv, float *result)
+{
int n = N;
double num = 0.f, den = 0.f;
- while(n--){
- num += powf(data[n] - data[n+1], 2);
- den += powf(data[n], 2);
+ while(n--)
+ {
+ num += powf(data[n] - data[n+1], 2);
+ den += powf(data[n], 2);
}
*result = (float)(num / den);
@@ -295,7 +315,8 @@ int xtract_irregularity_j(const float *data, const int N, const void *argv, floa
return XTRACT_SUCCESS;
}
-int xtract_tristimulus_1(const float *data, const int N, const void *argv, float *result){
+int xtract_tristimulus_1(const float *data, const int N, const void *argv, float *result)
+{
int n = N;
@@ -303,25 +324,30 @@ int xtract_tristimulus_1(const float *data, const int N, const void *argv, float
den = p1 = temp = 0.f;
- for(n = 0; n < N; n++){
- if((temp = data[n])){
- den += temp;
- if(!p1)
- p1 = temp;
- }
+ for(n = 0; n < N; n++)
+ {
+ if((temp = data[n]))
+ {
+ den += temp;
+ if(!p1)
+ p1 = temp;
+ }
}
- if(den == 0.f || p1 == 0.f){
+ if(den == 0.f || p1 == 0.f)
+ {
*result = 0.f;
return XTRACT_NO_RESULT;
}
- else{
+ else
+ {
*result = p1 / den;
return XTRACT_SUCCESS;
}
}
-int xtract_tristimulus_2(const float *data, const int N, const void *argv, float *result){
+int xtract_tristimulus_2(const float *data, const int N, const void *argv, float *result)
+{
int n = N;
@@ -329,32 +355,37 @@ int xtract_tristimulus_2(const float *data, const int N, const void *argv, float
den = p2 = p3 = p4 = ps = temp = 0.f;
- for(n = 0; n < N; n++){
- if((temp = data[n])){
- den += temp;
- if(!p2)
- p2 = temp;
- else if(!p3)
- p3 = temp;
- else if(!p4)
- p4 = temp;
- }
+ for(n = 0; n < N; n++)
+ {
+ if((temp = data[n]))
+ {
+ den += temp;
+ if(!p2)
+ p2 = temp;
+ else if(!p3)
+ p3 = temp;
+ else if(!p4)
+ p4 = temp;
+ }
}
ps = p2 + p3 + p4;
- if(den == 0.f || ps == 0.f){
+ if(den == 0.f || ps == 0.f)
+ {
*result = 0.f;
return XTRACT_NO_RESULT;
}
- else{
+ else
+ {
*result = ps / den;
return XTRACT_SUCCESS;
}
}
-int xtract_tristimulus_3(const float *data, const int N, const void *argv, float *result){
+int xtract_tristimulus_3(const float *data, const int N, const void *argv, float *result)
+{
int n = N, count = 0;
@@ -362,26 +393,31 @@ int xtract_tristimulus_3(const float *data, const int N, const void *argv, float
den = num = temp = 0.f;
- for(n = 0; n < N; n++){
- if((temp = data[n])){
- den += temp;
- if(count >= 5)
- num += temp;
- count++;
- }
+ for(n = 0; n < N; n++)
+ {
+ if((temp = data[n]))
+ {
+ den += temp;
+ if(count >= 5)
+ num += temp;
+ count++;
+ }
}
- if(den == 0.f || num == 0.f){
+ if(den == 0.f || num == 0.f)
+ {
*result = 0.f;
return XTRACT_NO_RESULT;
}
- else{
+ else
+ {
*result = num / den;
return XTRACT_SUCCESS;
}
}
-int xtract_smoothness(const float *data, const int N, const void *argv, float *result){
+int xtract_smoothness(const float *data, const int N, const void *argv, float *result)
+{
int n, M;
@@ -390,18 +426,19 @@ int xtract_smoothness(const float *data, const int N, const void *argv, float *r
input = (float *)malloc(N * sizeof(float));
memcpy(input, data, N * sizeof(float));
- if (input[0] <= 0)
+ if (input[0] <= 0)
input[0] = XTRACT_LOG_LIMIT;
- if (input[1] <= 0)
+ if (input[1] <= 0)
input[1] = XTRACT_LOG_LIMIT;
M = N - 1;
- for(n = 1; n < M; n++){
- if(input[n+1] <= 0)
+ for(n = 1; n < M; n++)
+ {
+ if(input[n+1] <= 0)
input[n+1] = XTRACT_LOG_LIMIT;
- *result += fabsf(20.f * logf(input[n]) - (20.f * logf(input[n-1]) +
- 20.f * logf(input[n]) + 20.f * logf(input[n+1])) / 3.f);
+ *result += fabsf(20.f * logf(input[n]) - (20.f * logf(input[n-1]) +
+ 20.f * logf(input[n]) + 20.f * logf(input[n+1])) / 3.f);
}
free(input);
@@ -409,24 +446,27 @@ int xtract_smoothness(const float *data, const int N, const void *argv, float *r
return XTRACT_SUCCESS;
}
-int xtract_spread(const float *data, const int N, const void *argv, float *result){
+int xtract_spread(const float *data, const int N, const void *argv, float *result)
+{
- return xtract_spectral_variance(data, N, argv, result);
+ return xtract_spectral_variance(data, N, argv, result);
}
-int xtract_zcr(const float *data, const int N, const void *argv, float *result){
+int xtract_zcr(const float *data, const int N, const void *argv, float *result)
+{
int n = N;
for(n = 1; n < N; n++)
- if(data[n] * data[n-1] < 0) (*result)++;
+ if(data[n] * data[n-1] < 0) (*result)++;
*result /= (float)N;
return XTRACT_SUCCESS;
}
-int xtract_rolloff(const float *data, const int N, const void *argv, float *result){
+int xtract_rolloff(const float *data, const int N, const void *argv, float *result)
+{
int n = N;
float pivot, temp, percentile;
@@ -434,12 +474,12 @@ int xtract_rolloff(const float *data, const int N, const void *argv, float *resu
pivot = temp = 0.f;
percentile = ((float *)argv)[1];
- while(n--) pivot += data[n];
+ while(n--) pivot += data[n];
pivot *= percentile / 100.f;
for(n = 0; temp < pivot; n++)
- temp += data[n];
+ temp += data[n];
*result = n * ((float *)argv)[0];
/* *result = (n / (float)N) * (((float *)argv)[1] * .5); */
@@ -447,30 +487,33 @@ int xtract_rolloff(const float *data, const int N, const void *argv, float *resu
return XTRACT_SUCCESS;
}
-int xtract_loudness(const float *data, const int N, const void *argv, float *result){
+int xtract_loudness(const float *data, const int N, const void *argv, float *result)
+{
int n = N, rv;
*result = 0.f;
- if(n > XTRACT_BARK_BANDS){
- n = XTRACT_BARK_BANDS;
- rv = XTRACT_BAD_VECTOR_SIZE;
+ if(n > XTRACT_BARK_BANDS)
+ {
+ n = XTRACT_BARK_BANDS;
+ rv = XTRACT_BAD_VECTOR_SIZE;
}
else
- rv = XTRACT_SUCCESS;
+ rv = XTRACT_SUCCESS;
while(n--)
- *result += powf(data[n], 0.23);
+ *result += powf(data[n], 0.23);
return rv;
}
-int xtract_flatness(const float *data, const int N, const void *argv, float *result){
+int xtract_flatness(const float *data, const int N, const void *argv, float *result)
+{
int n, count, denormal_found;
- double num, den, temp;
+ double num, den, temp;
num = 1.f;
den = temp = 0.f;
@@ -478,9 +521,12 @@ int xtract_flatness(const float *data, const int N, const void *argv, float *res
denormal_found = 0;
count = 0;
- for(n = 0; n < N; n++){
- if((temp = data[n]) != 0.f) {
- if (xtract_is_denormal(num)){
+ for(n = 0; n < N; n++)
+ {
+ if((temp = data[n]) != 0.f)
+ {
+ if (xtract_is_denormal(num))
+ {
denormal_found = 1;
break;
}
@@ -490,7 +536,8 @@ int xtract_flatness(const float *data, const int N, const void *argv, float *res
}
}
- if(!count){
+ if(!count)
+ {
*result = 0.f;
return XTRACT_NO_RESULT;
}
@@ -505,16 +552,17 @@ int xtract_flatness(const float *data, const int N, const void *argv, float *res
return XTRACT_DENORMAL_FOUND;
else
return XTRACT_SUCCESS;
-
+
}
-int xtract_flatness_db(const float *data, const int N, const void *argv, float *result){
+int xtract_flatness_db(const float *data, const int N, const void *argv, float *result)
+{
float flatness;
flatness = *(float *)argv;
- if (flatness <= 0)
+ if (flatness <= 0)
flatness = XTRACT_LOG_LIMIT;
*result = 10 * log10f(flatness);
@@ -523,7 +571,8 @@ int xtract_flatness_db(const float *data, const int N, const void *argv, float *
}
-int xtract_tonality(const float *data, const int N, const void *argv, float *result){
+int xtract_tonality(const float *data, const int N, const void *argv, float *result)
+{
float sfmdb;
@@ -534,9 +583,10 @@ int xtract_tonality(const float *data, const int N, const void *argv, float *res
return XTRACT_SUCCESS;
}
-int xtract_crest(const float *data, const int N, const void *argv, float *result){
+int xtract_crest(const float *data, const int N, const void *argv, float *result)
+{
- float max, mean;
+ float max, mean;
max = mean = 0.f;
@@ -549,7 +599,8 @@ int xtract_crest(const float *data, const int N, const void *argv, float *result
}
-int xtract_noisiness(const float *data, const int N, const void *argv, float *result){
+int xtract_noisiness(const float *data, const int N, const void *argv, float *result)
+{
float h, i, p; /*harmonics, inharmonics, partials */
@@ -566,7 +617,8 @@ int xtract_noisiness(const float *data, const int N, const void *argv, float *re
}
-int xtract_rms_amplitude(const float *data, const int N, const void *argv, float *result){
+int xtract_rms_amplitude(const float *data, const int N, const void *argv, float *result)
+{
int n = N;
@@ -579,81 +631,94 @@ int xtract_rms_amplitude(const float *data, const int N, const void *argv, float
return XTRACT_SUCCESS;
}
-int xtract_spectral_inharmonicity(const float *data, const int N, const void *argv, float *result){
+int xtract_spectral_inharmonicity(const float *data, const int N, const void *argv, float *result)
+{
int n = N >> 1;
- float num = 0.f, den = 0.f, fund;
+ float num = 0.f, den = 0.f, fund;
const float *freqs, *amps;
fund = *(float *)argv;
amps = data;
freqs = data + n;
- while(n--){
- if(amps[n]){
- num += fabsf(freqs[n] - n * fund) * XTRACT_SQ(amps[n]);
- den += XTRACT_SQ(amps[n]);
- }
+ while(n--)
+ {
+ if(amps[n])
+ {
+ num += fabsf(freqs[n] - n * fund) * XTRACT_SQ(amps[n]);
+ den += XTRACT_SQ(amps[n]);
+ }
}
- *result = (2 * num) / (fund * den);
+ *result = (2 * num) / (fund * den);
return XTRACT_SUCCESS;
}
-int xtract_power(const float *data, const int N, const void *argv, float *result){
+int xtract_power(const float *data, const int N, const void *argv, float *result)
+{
return XTRACT_FEATURE_NOT_IMPLEMENTED;
}
-int xtract_odd_even_ratio(const float *data, const int N, const void *argv, float *result){
+int xtract_odd_even_ratio(const float *data, const int N, const void *argv, float *result)
+{
int M = (N >> 1), n;
float odd = 0.f, even = 0.f, temp;
- for(n = 0; n < M; n++){
- if((temp = data[n])){
- if(XTRACT_IS_ODD(n)){
- odd += temp;
- }
- else{
- even += temp;
- }
- }
+ for(n = 0; n < M; n++)
+ {
+ if((temp = data[n]))
+ {
+ if(XTRACT_IS_ODD(n))
+ {
+ odd += temp;
+ }
+ else
+ {
+ even += temp;
+ }
+ }
}
- if(odd == 0.f || even == 0.f){
+ if(odd == 0.f || even == 0.f)
+ {
*result = 0.f;
return XTRACT_NO_RESULT;
}
- else {
+ else
+ {
*result = odd / even;
return XTRACT_SUCCESS;
}
}
-int xtract_sharpness(const float *data, const int N, const void *argv, float *result){
+int xtract_sharpness(const float *data, const int N, const void *argv, float *result)
+{
int n = N, rv;
float sl, g; /* sl = specific loudness */
- double temp;
+ double temp;
sl = g = 0.f;
temp = 0.f;
- if(n > XTRACT_BARK_BANDS)
- rv = XTRACT_BAD_VECTOR_SIZE;
+ if(n > XTRACT_BARK_BANDS)
+ rv = XTRACT_BAD_VECTOR_SIZE;
else
- rv = XTRACT_SUCCESS;
+ rv = XTRACT_SUCCESS;
- while(n--){
- sl = powf(data[n], 0.23);
- g = (n < 15 ? 1.f : 0.066 * expf(0.171 * n));
- temp += n * g * sl;
+ while(n--)
+ {
+ sl = powf(data[n], 0.23);
+ g = (n < 15 ? 1.f : 0.066 * expf(0.171 * n));
+ temp += n * g * sl;
}
temp = 0.11 * temp / (float)N;
@@ -663,97 +728,105 @@ int xtract_sharpness(const float *data, const int N, const void *argv, float *re
}
-int xtract_spectral_slope(const float *data, const int N, const void *argv, float *result){
+int xtract_spectral_slope(const float *data, const int N, const void *argv, float *result)
+{
- const float *freqs, *amps;
+ const float *freqs, *amps;
float f, a,
- F, A, FA, FXTRACT_SQ; /* sums of freqs, amps, freq * amps, freq squared */
- int n, M;
-
+ F, A, FA, FXTRACT_SQ; /* sums of freqs, amps, freq * amps, freq squared */
+ int n, M;
+
F = A = FA = FXTRACT_SQ = 0.f;
n = M = N >> 1;
amps = data;
freqs = data + n;
- while(n--){
- f = freqs[n];
- a = amps[n];
- F += f;
- A += a;
- FA += f * a;
- FXTRACT_SQ += f * f;
+ while(n--)
+ {
+ f = freqs[n];
+ a = amps[n];
+ F += f;
+ A += a;
+ FA += f * a;
+ FXTRACT_SQ += f * f;
}
- *result = (1.f / A) * (M * FA - F * A) / (M * FXTRACT_SQ - F * F);
+ *result = (1.f / A) * (M * FA - F * A) / (M * FXTRACT_SQ - F * F);
return XTRACT_SUCCESS;
}
-int xtract_lowest_value(const float *data, const int N, const void *argv, float *result){
+int xtract_lowest_value(const float *data, const int N, const void *argv, float *result)
+{
int n = N;
float temp;
*result = data[--n];
- while(n--){
- if((temp = data[n]) > *(float *)argv)
- *result = XTRACT_MIN(*result, data[n]);
+ while(n--)
+ {
+ if((temp = data[n]) > *(float *)argv)
+ *result = XTRACT_MIN(*result, data[n]);
}
return XTRACT_SUCCESS;
}
-int xtract_highest_value(const float *data, const int N, const void *argv, float *result){
+int xtract_highest_value(const float *data, const int N, const void *argv, float *result)
+{
int n = N;
*result = data[--n];
- while(n--)
- *result = XTRACT_MAX(*result, data[n]);
+ while(n--)
+ *result = XTRACT_MAX(*result, data[n]);
return XTRACT_SUCCESS;
}
-int xtract_sum(const float *data, const int N, const void *argv, float *result){
+int xtract_sum(const float *data, const int N, const void *argv, float *result)
+{
int n = N;
*result = 0.f;
while(n--)
- *result += *data++;
+ *result += *data++;
return XTRACT_SUCCESS;
}
-int xtract_nonzero_count(const float *data, const int N, const void *argv, float *result){
+int xtract_nonzero_count(const float *data, const int N, const void *argv, float *result)
+{
int n = N;
-
+
*result = 0.f;
while(n--)
- *result += (*data++ ? 1 : 0);
+ *result += (*data++ ? 1 : 0);
return XTRACT_SUCCESS;
}
-int xtract_hps(const float *data, const int N, const void *argv, float *result){
+int xtract_hps(const float *data, const int N, const void *argv, float *result)
+{
int n = N, M, m, l, peak_index, position1_lwr;
- float *coeffs2, *coeffs3, *product, L,
- largest1_lwr, peak, ratio1, sr;
+ float *coeffs2, *coeffs3, *product, L,
+ largest1_lwr, peak, ratio1, sr;
sr = *(float*)argv;
if(sr == 0)
- sr = 44100.f;
+ sr = 44100.f;
coeffs2 = (float *)malloc(N * sizeof(float));
coeffs3 = (float *)malloc(N * sizeof(float));
@@ -764,42 +837,48 @@ int xtract_hps(const float *data, const int N, const void *argv, float *result){
M = N >> 1;
L = N / 3.f;
- while(M--){
- m = M << 1;
- coeffs2[M] = (data[m] + data[m+1]) * 0.5f;
+ while(M--)
+ {
+ m = M << 1;
+ coeffs2[M] = (data[m] + data[m+1]) * 0.5f;
- if(M < L){
- l = M * 3;
- coeffs3[M] = (data[l] + data[l+1] + data[l+2]) / 3.f;
- }
+ if(M < L)
+ {
+ l = M * 3;
+ coeffs3[M] = (data[l] + data[l+1] + data[l+2]) / 3.f;
+ }
}
peak_index = peak = 0;
- for(n = 1; n < N; n++){
- product[n] = data[n] * coeffs2[n] * coeffs3[n];
- if(product[n] > peak){
- peak_index = n;
- peak = product[n];
- }
+ for(n = 1; n < N; n++)
+ {
+ product[n] = data[n] * coeffs2[n] * coeffs3[n];
+ if(product[n] > peak)
+ {
+ peak_index = n;
+ peak = product[n];
+ }
}
largest1_lwr = position1_lwr = 0;
- for(n = 0; n < N; n++){
- if(data[n] > largest1_lwr && n != peak_index){
- largest1_lwr = data[n];
- position1_lwr = n;
- }
+ for(n = 0; n < N; n++)
+ {
+ if(data[n] > largest1_lwr && n != peak_index)
+ {
+ largest1_lwr = data[n];
+ position1_lwr = n;
+ }
}
ratio1 = data[position1_lwr] / data[peak_index];
- if(position1_lwr > peak_index * 0.4 && position1_lwr <
- peak_index * 0.6 && ratio1 > 0.1)
- peak_index = position1_lwr;
+ if(position1_lwr > peak_index * 0.4 && position1_lwr <
+ peak_index * 0.6 && ratio1 > 0.1)
+ peak_index = position1_lwr;
- *result = sr / (float)peak_index;
+ *result = sr / (float)peak_index;
free(coeffs2);
free(coeffs3);
@@ -809,24 +888,25 @@ int xtract_hps(const float *data, const int N, const void *argv, float *result){
}
-int xtract_f0(const float *data, const int N, const void *argv, float *result){
+int xtract_f0(const float *data, const int N, const void *argv, float *result)
+{
int M, tau, n;
float sr;
size_t bytes;
- float f0, err_tau_1, err_tau_x, array_max,
- threshold_peak, threshold_centre,
- *input;
+ float f0, err_tau_1, err_tau_x, array_max,
+ threshold_peak, threshold_centre,
+ *input;
sr = *(float *)argv;
if(sr == 0)
- sr = 44100.f;
+ sr = 44100.f;
input = (float *)malloc(bytes = N * sizeof(float));
input = memcpy(input, data, bytes);
/* threshold_peak = *((float *)argv+1);
- threshold_centre = *((float *)argv+2);
- printf("peak: %.2f\tcentre: %.2f\n", threshold_peak, threshold_centre);*/
+ threshold_centre = *((float *)argv+2);
+ printf("peak: %.2f\tcentre: %.2f\n", threshold_peak, threshold_centre);*/
/* add temporary dynamic control over thresholds to test clipping effects */
/* FIX: tweak and make into macros */
@@ -837,75 +917,83 @@ int xtract_f0(const float *data, const int N, const void *argv, float *result){
array_max = 0;
/* Find the array max */
- for(n = 0; n < N; n++){
- if (input[n] > array_max)
- array_max = input[n];
+ for(n = 0; n < N; n++)
+ {
+ if (input[n] > array_max)
+ array_max = input[n];
}
threshold_peak *= array_max;
/* peak clip */
- for(n = 0; n < N; n++){
- if(input[n] > threshold_peak)
- input[n] = threshold_peak;
- else if(input[n] < -threshold_peak)
- input[n] = -threshold_peak;
+ for(n = 0; n < N; n++)
+ {
+ if(input[n] > threshold_peak)
+ input[n] = threshold_peak;
+ else if(input[n] < -threshold_peak)
+ input[n] = -threshold_peak;
}
threshold_centre *= array_max;
/* Centre clip */
- for(n = 0; n < N; n++){
- if (input[n] < threshold_centre)
- input[n] = 0;
- else
- input[n] -= threshold_centre;
+ for(n = 0; n < N; n++)
+ {
+ if (input[n] < threshold_centre)
+ input[n] = 0;
+ else
+ input[n] -= threshold_centre;
}
/* Estimate fundamental freq */
for (n = 1; n < M; n++)
- err_tau_1 = err_tau_1 + fabsf(input[n] - input[n+1]);
- /* 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! */
- for (tau = 2; tau < M; tau++){
- err_tau_x = 0;
- for (n = 1; n < M; n++){
- err_tau_x = err_tau_x + fabsf(input[n] - input[n+tau]);
- }
- if (err_tau_x < err_tau_1) {
- f0 = sr / (tau + (err_tau_x / err_tau_1));
- *result = f0;
- free(input);
- return XTRACT_SUCCESS;
- }
+ err_tau_1 = err_tau_1 + fabsf(input[n] - input[n+1]);
+ /* 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! */
+ for (tau = 2; tau < M; tau++)
+ {
+ err_tau_x = 0;
+ for (n = 1; n < M; n++)
+ {
+ err_tau_x = err_tau_x + fabsf(input[n] - input[n+tau]);
+ }
+ if (err_tau_x < err_tau_1)
+ {
+ f0 = sr / (tau + (err_tau_x / err_tau_1));
+ *result = f0;
+ free(input);
+ return XTRACT_SUCCESS;
+ }
}
*result = -0;
free(input);
return XTRACT_NO_RESULT;
}
-int xtract_failsafe_f0(const float *data, const int N, const void *argv, float *result){
+int xtract_failsafe_f0(const float *data, const int N, const void *argv, float *result)
+{
float *spectrum = NULL, argf[2], *peaks = NULL, return_code, sr;
return_code = xtract_f0(data, N, argv, result);
- if(return_code == XTRACT_NO_RESULT){
-
- sr = *(float *)argv;
- if(sr == 0)
- sr = 44100.f;
- spectrum = (float *)malloc(N * sizeof(float));
- peaks = (float *)malloc(N * sizeof(float));
- argf[0] = sr;
- argf[1] = XTRACT_MAGNITUDE_SPECTRUM;
- xtract_spectrum(data, N, argf, spectrum);
- argf[1] = 10.f;
- xtract_peak_spectrum(spectrum, N >> 1, argf, peaks);
- argf[0] = 0.f;
- xtract_lowest_value(peaks+(N >> 1), N >> 1, argf, result);
-
- free(spectrum);
- free(peaks);
+ if(return_code == XTRACT_NO_RESULT)
+ {
+
+ sr = *(float *)argv;
+ if(sr == 0)
+ sr = 44100.f;
+ spectrum = (float *)malloc(N * sizeof(float));
+ peaks = (float *)malloc(N * sizeof(float));
+ argf[0] = sr;
+ argf[1] = XTRACT_MAGNITUDE_SPECTRUM;
+ xtract_spectrum(data, N, argf, spectrum);
+ argf[1] = 10.f;
+ xtract_peak_spectrum(spectrum, N >> 1, argf, peaks);
+ argf[0] = 0.f;
+ xtract_lowest_value(peaks+(N >> 1), N >> 1, argf, result);
+
+ free(spectrum);
+ free(peaks);
}
return XTRACT_SUCCESS;