aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/descriptors.c2
-rw-r--r--src/helper.c22
-rw-r--r--src/init.c2
-rw-r--r--src/libxtract.c1
-rw-r--r--src/scalar.c237
-rw-r--r--src/vector.c44
6 files changed, 219 insertions, 89 deletions
diff --git a/src/descriptors.c b/src/descriptors.c
index ac1fd1b..4460de8 100644
--- a/src/descriptors.c
+++ b/src/descriptors.c
@@ -530,7 +530,7 @@ xtract_function_descriptor_t *xtract_make_descriptors(void){
break;
case XTRACT_ODD_EVEN_RATIO:
strcpy(name, "odd_even_ratio");
- strcpy(p_name, "Odd/Even Harmonic Ratio");
+ strcpy(p_name, "Odd/even Harmonic Ratio");
strcpy(desc,
"Extract the odd-to-even harmonic ratio of a spectrum");
strcpy(p_desc,
diff --git a/src/helper.c b/src/helper.c
index 60b3af7..e9e79e5 100644
--- a/src/helper.c
+++ b/src/helper.c
@@ -21,8 +21,18 @@
/* helper.c: helper functions. */
+#include <config.h>
+
+#include <stdio.h>
+
#include "xtract/libxtract.h"
+#ifdef WORDS_BIGENDIAN
+#define INDEX 0
+#else
+#define INDEX 1
+#endif
+
int xtract_windowed(const float *data, const int N, const void *argv, float *result){
int n;
@@ -45,8 +55,7 @@ int xtract_features_from_subframes(const float *data, const int N, const int fea
float *result1,
*result2;
- int n, i,
- rv;
+ int n, rv;
n = N >> 1;
@@ -63,3 +72,12 @@ int xtract_features_from_subframes(const float *data, const int N, const int fea
return rv;
}
+
+inline int xtract_is_denormal(double const d){
+ if(sizeof(d) != 2 * sizeof(int))
+ fprintf(stderr, "libxtract: Error: xtract_is_denormal() detects inconsistent wordlength for type 'double'\n");
+
+ int l = ((int *)&d)[INDEX];
+ return (l&0x7ff00000) == 0 && d!=0; //Check for 0 may not be necessary
+}
+
diff --git a/src/init.c b/src/init.c
index 6e544af..234b80e 100644
--- a/src/init.c
+++ b/src/init.c
@@ -149,7 +149,7 @@ int xtract_init_fft(int N, int feature_name){
input = output = NULL;
- fprintf(stderr, "Optimisation level: %d\n", XTRACT_FFT_OPTIMISATION_LEVEL);
+ //fprintf(stderr, "Optimisation level: %d\n", XTRACT_FFT_OPTIMISATION_LEVEL);
if(XTRACT_FFT_OPTIMISATION_LEVEL == 0)
optimisation = FFTW_ESTIMATE;
diff --git a/src/libxtract.c b/src/libxtract.c
index c46883e..5de699f 100644
--- a/src/libxtract.c
+++ b/src/libxtract.c
@@ -48,6 +48,7 @@ int(*xtract[])(const float *, const int, const void *, float *) = {
xtract_rolloff,
xtract_loudness,
xtract_flatness,
+ xtract_flatness_db,
xtract_tonality,
xtract_crest,
xtract_noisiness,
diff --git a/src/scalar.c b/src/scalar.c
index 6c29f91..b2fa868 100644
--- a/src/scalar.c
+++ b/src/scalar.c
@@ -21,12 +21,16 @@
/* scalar.c: defines functions that extract a feature as a single value from an input vector */
-#include "xtract/libxtract.h"
-#include "xtract_macros_private.h"
-#include "math.h"
+#include <config.h>
+
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
+#include <math.h>
+
+#include "xtract/libxtract.h"
+#include "xtract/xtract_helper.h"
+#include "xtract_macros_private.h"
#ifndef powf
#define powf pow
@@ -36,8 +40,20 @@
#define expf exp
#endif
+#ifndef sqrtf
+ #define sqrtf sqrt
+#endif
+
+#ifndef fabsf
+ #define fabsf fabs
+#endif
+
+
void test(void){
- printf("Hello world");
+ 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){
@@ -58,8 +74,10 @@ int xtract_variance(const float *data, const int N, const void *argv, float *res
int n = N;
+ *result += 0.f;
+
while(n--)
- *result += pow(data[n] - *(float *)argv, 2);
+ *result += powf(data[n] - *(float *)argv, 2);
*result = *result / (N - 1);
@@ -68,7 +86,7 @@ int xtract_variance(const float *data, const int N, const void *argv, float *res
int xtract_standard_deviation(const float *data, const int N, const void *argv, float *result){
- *result = sqrt(*(float *)argv);
+ *result = sqrtf(*(float *)argv);
return XTRACT_SUCCESS;
}
@@ -77,8 +95,10 @@ int xtract_average_deviation(const float *data, const int N, const void *argv, f
int n = N;
+ *result += 0.f;
+
while(n--)
- *result += fabs(data[n] - *(float *)argv);
+ *result += fabsf(data[n] - *(float *)argv);
*result /= N;
@@ -91,9 +111,11 @@ int xtract_skewness(const float *data, const int N, const void *argv, float *re
float temp = 0.f;
+ *result += 0.f;
+
while(n--){
temp = (data[n] - ((float *)argv)[0]) / ((float *)argv)[1];
- *result += pow(temp, 3);
+ *result += powf(temp, 3);
}
*result /= N;
@@ -106,11 +128,13 @@ int xtract_kurtosis(const float *data, const int N, const void *argv, float *re
int n = N;
- float temp;
+ float temp = 0.f;
+
+ *result += 0.f;
while(n--){
temp = (data[n] - ((float *)argv)[0]) / ((float *)argv)[1];
- *result += pow(temp, 4);
+ *result += powf(temp, 4);
}
*result /= N;
@@ -134,7 +158,10 @@ int xtract_spectral_centroid(const float *data, const int N, const void *argv,
A += amps[n];
}
- *result = FA / A;
+ if(A == 0.f)
+ *result = 0.f;
+ else
+ *result = FA / A;
return XTRACT_SUCCESS;
}
@@ -156,6 +183,8 @@ int xtract_spectral_variance(const float *data, const int N, const void *argv, f
amps = data;
freqs = data + m;
+ *result += 0.f;
+
while(m--){
A += amps[m];
*result += powf((freqs[m] - *(float *)argv) * amps[m], 2);
@@ -168,7 +197,7 @@ int xtract_spectral_variance(const float *data, const int N, const void *argv, f
int xtract_spectral_standard_deviation(const float *data, const int N, const void *argv, float *result){
- *result = sqrt(*(float *)argv);
+ *result = sqrtf(*(float *)argv);
return XTRACT_SUCCESS;
}
@@ -184,9 +213,11 @@ int xtract_spectral_average_deviation(const float *data, const int N, const void
amps = data;
freqs = data + m;
+ *result += 0.f;
+
while(m--){
A += amps[m];
- *result += fabs((amps[m] * freqs[m]) - *(float *)argv);
+ *result += fabsf((amps[m] * freqs[m]) - *(float *)argv);
}
*result /= A;
@@ -205,11 +236,13 @@ int xtract_spectral_skewness(const float *data, const int N, const void *argv,
amps = data;
freqs = data + m;
+ *result += 0.f;
+
while(m--){
A += amps[m];
temp = ((amps[m] * freqs[m]) -
((float *)argv)[0]) / ((float *)argv)[1];
- *result += pow(temp, 3);
+ *result += powf(temp, 3);
}
*result /= A;
@@ -228,11 +261,13 @@ int xtract_spectral_kurtosis(const float *data, const int N, const void *argv,
amps = data;
freqs = data + m;
+ *result += 0.f;
+
while(m--){
A += amps[m];
temp = ((amps[m] * freqs[m]) -
((float *)argv)[0]) / ((float *)argv)[1];
- *result += pow(temp, 4);
+ *result += powf(temp, 4);
}
*result /= A;
@@ -246,10 +281,10 @@ int xtract_irregularity_k(const float *data, const int N, const void *argv, floa
int n,
M = N - 1;
- *result = 0.f;
+ *result = 0.f;
for(n = 1; n < M; n++)
- *result += fabs(data[n] - (data[n-1] + data[n] + data[n+1]) / 3);
+ *result += fabsf(data[n] - (data[n-1] + data[n] + data[n+1]) / 3.f);
return XTRACT_SUCCESS;
}
@@ -261,8 +296,8 @@ int xtract_irregularity_j(const float *data, const int N, const void *argv, floa
double num = 0.f, den = 0.f;
while(n--){
- num += pow(data[n] - data[n+1], 2);
- den += pow(data[n], 2);
+ num += powf(data[n] - data[n+1], 2);
+ den += powf(data[n], 2);
}
*result = (float)(num / den);
@@ -286,18 +321,23 @@ int xtract_tristimulus_1(const float *data, const int N, const void *argv, float
}
}
- *result = p1 / den;
-
- return XTRACT_SUCCESS;
+ if(den == 0.f || p1 == 0.f){
+ *result = 0.f;
+ return XTRACT_NO_RESULT;
+ }
+ else{
+ *result = p1 / den;
+ return XTRACT_SUCCESS;
+ }
}
int xtract_tristimulus_2(const float *data, const int N, const void *argv, float *result){
int n = N;
- float den, p2, p3, p4, temp;
+ float den, p2, p3, p4, ps, temp;
- den = p2 = p3 = p4 = temp = 0.f;
+ den = p2 = p3 = p4 = ps = temp = 0.f;
for(n = 0; n < N; n++){
if((temp = data[n])){
@@ -311,9 +351,17 @@ int xtract_tristimulus_2(const float *data, const int N, const void *argv, float
}
}
- *result = (p2 + p3 + p4) / den;
+ ps = p2 + p3 + p4;
+
+ if(den == 0.f || ps == 0.f){
+ *result = 0.f;
+ return XTRACT_NO_RESULT;
+ }
+ else{
+ *result = ps / den;
+ return XTRACT_SUCCESS;
+ }
- return XTRACT_SUCCESS;
}
int xtract_tristimulus_3(const float *data, const int N, const void *argv, float *result){
@@ -333,9 +381,14 @@ int xtract_tristimulus_3(const float *data, const int N, const void *argv, float
}
}
- *result = num / den;
-
- return XTRACT_SUCCESS;
+ if(den == 0.f || num == 0.f){
+ *result = 0.f;
+ return XTRACT_NO_RESULT;
+ }
+ else{
+ *result = num / den;
+ return XTRACT_SUCCESS;
+ }
}
int xtract_smoothness(const float *data, const int N, const void *argv, float *result){
@@ -347,14 +400,18 @@ 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) input[0] = 1;
+ if (input[0] <= 0)
+ input[0] = XTRACT_LOG_LIMIT;
+ if (input[1] <= 0)
+ input[1] = XTRACT_LOG_LIMIT;
M = N - 1;
for(n = 1; n < M; n++){
- if(input[n] <= 0) input[n] = 1;
- *result += fabs(20 * log(input[n]) - (20 * log(input[n-1]) +
- 20 * log(input[n]) + 20 * log(input[n+1])) / 3);
+ 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);
}
free(input);
@@ -377,7 +434,7 @@ int xtract_spread(const float *data, const int N, const void *argv, float *resul
den += data[n];
}
- *result = sqrt(num / den);
+ *result = sqrtf(num / den);
return XTRACT_SUCCESS;
}
@@ -389,7 +446,7 @@ int xtract_zcr(const float *data, const int N, const void *argv, float *result){
for(n = 1; n < N; n++)
if(data[n] * data[n-1] < 0) (*result)++;
- *result /= N;
+ *result /= (float)N;
return XTRACT_SUCCESS;
}
@@ -419,6 +476,8 @@ int xtract_loudness(const float *data, const int N, const void *argv, float *res
int n = N, rv;
+ *result = 0.f;
+
if(n > XTRACT_BARK_BANDS){
n = XTRACT_BARK_BANDS;
rv = XTRACT_BAD_VECTOR_SIZE;
@@ -434,30 +493,56 @@ int xtract_loudness(const float *data, const int N, const void *argv, float *res
int xtract_flatness(const float *data, const int N, const void *argv, float *result){
- int n;
+ int n, count, denormal_found;
double num, den, temp;
- den = data[0];
- num = (data[0] == 0.f ? 1.f : data[0]);
+ num = 1.f;
+ den = temp = 0.f;
- for(n = 1; n < N; n++){
- if((temp = data[n]) != 0.f) {
- num *= temp;
- den += temp;
- }
+ denormal_found = 0;
+ count = 0;
+
+ for(n = 0; n < N; n++){
+ if((temp = data[n]) != 0.f) {
+ if (xtract_is_denormal(num)){
+ denormal_found = 1;
+ break;
+ }
+ num *= temp;
+ den += temp;
+ count++;
+ }
+ }
+
+ if(!count){
+ *result = 0.f;
+ return XTRACT_NO_RESULT;
}
- num = powf(num, 1.f / N);
- den /= N;
+ num = powf(num, 1.f / (float)N);
+ den /= (float)N;
+
+
+ *result = (float) (num / den);
+
+ if(denormal_found)
+ return XTRACT_DENORMAL_FOUND;
+ else
+ return XTRACT_SUCCESS;
+
+}
+
+int xtract_flatness_db(const float *data, const int N, const void *argv, float *result){
- if(num < XTRACT_VERY_SMALL_NUMBER)
- num = XTRACT_VERY_SMALL_NUMBER;
+ float flatness_db;
- if(den < XTRACT_VERY_SMALL_NUMBER)
- den = XTRACT_VERY_SMALL_NUMBER;
+ flatness_db = *(float *)argv;
- *result = 10 * log10(num / den);
+ if (flatness_db <= 0)
+ flatness_db = XTRACT_LOG_LIMIT;
+
+ *result = 10 * log10f(flatness_db);
return XTRACT_SUCCESS;
@@ -465,13 +550,11 @@ int xtract_flatness(const float *data, const int N, const void *argv, float *res
int xtract_tonality(const float *data, const int N, const void *argv, float *result){
- float sfmdb, sfm;
-
- sfm = *(float *)argv;
+ float sfmdb;
- sfmdb = sfm / -60.f;
+ sfmdb = *(float *)argv;
- *result = XTRACT_MIN(sfmdb, 1);
+ *result = XTRACT_MIN(sfmdb / -60.f, 1);
return XTRACT_SUCCESS;
}
@@ -512,9 +595,11 @@ int xtract_rms_amplitude(const float *data, const int N, const void *argv, float
int n = N;
+ *result = 0.f;
+
while(n--) *result += XTRACT_SQ(data[n]);
- *result = sqrt(*result / N);
+ *result = sqrtf(*result / (float)N);
return XTRACT_SUCCESS;
}
@@ -531,7 +616,7 @@ int xtract_spectral_inharmonicity(const float *data, const int N, const void *ar
while(n--){
if(amps[n]){
- num += fabs(freqs[n] - n * fund) * XTRACT_SQ(amps[n]);
+ num += fabsf(freqs[n] - n * fund) * XTRACT_SQ(amps[n]);
den += XTRACT_SQ(amps[n]);
}
}
@@ -552,30 +637,37 @@ int xtract_odd_even_ratio(const float *data, const int N, const void *argv, floa
int M = (N >> 1), n;
- float num = 0.f, den = 0.f, temp;
+ float odd = 0.f, even = 0.f, temp;
for(n = 0; n < M; n++){
if((temp = data[n])){
if(XTRACT_IS_ODD(n)){
- num += temp;
+ odd += temp;
}
else{
- den += temp;
+ even += temp;
}
}
}
- *result = num / den;
-
- return XTRACT_SUCCESS;
+ if(odd == 0.f || even == 0.f){
+ *result = 0.f;
+ return XTRACT_NO_RESULT;
+ }
+ else {
+ *result = odd / even;
+ return XTRACT_SUCCESS;
+ }
}
int xtract_sharpness(const float *data, const int N, const void *argv, float *result){
int n = N, rv;
- float sl, g, temp; /* sl = specific loudness */
+ float sl, g; /* sl = specific loudness */
+ double temp;
- sl = g = temp = 0.f;
+ sl = g = 0.f;
+ temp = 0.f;
if(n > XTRACT_BARK_BANDS)
rv = XTRACT_BAD_VECTOR_SIZE;
@@ -589,7 +681,8 @@ int xtract_sharpness(const float *data, const int N, const void *argv, float *re
temp += n * g * sl;
}
- *result = 0.11 * temp / N;
+ temp = 0.11 * temp / (float)N;
+ *result = (float)temp;
return rv;
@@ -655,6 +748,8 @@ int xtract_sum(const float *data, const int N, const void *argv, float *result){
int n = N;
+ *result = 0.f;
+
while(n--)
*result += *data++;
@@ -665,6 +760,8 @@ int xtract_sum(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);
@@ -690,7 +787,7 @@ int xtract_hps(const float *data, const int N, const void *argv, float *result){
while(n--) coeffs2[n] = coeffs3[n] = 1;
M = N >> 1;
- L = N / 3;
+ L = N / 3.f;
while(M--){
m = M << 1;
@@ -698,7 +795,7 @@ int xtract_hps(const float *data, const int N, const void *argv, float *result){
if(M < L){
l = M * 3;
- coeffs3[M] = (data[l] + data[l+1] + data[l+2]) / 3;
+ coeffs3[M] = (data[l] + data[l+1] + data[l+2]) / 3.f;
}
}
@@ -792,12 +889,12 @@ int xtract_f0(const float *data, const int N, const void *argv, float *result){
/* Estimate fundamental freq */
for (n = 1; n < M; n++)
- err_tau_1 = err_tau_1 + fabs(input[n] - input[n+1]);
+ 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 + fabs(input[n] - input[n+tau]);
+ 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));
diff --git a/src/vector.c b/src/vector.c
index e44a8af..ce74630 100644
--- a/src/vector.c
+++ b/src/vector.c
@@ -37,6 +37,22 @@
}
#endif
+#ifndef powf
+ #define powf pow
+#endif
+
+#ifndef expf
+ #define expf exp
+#endif
+
+#ifndef sqrtf
+ #define sqrtf sqrt
+#endif
+
+#ifndef fabsf
+ #define fabsf fabs
+#endif
+
#ifdef XTRACT_FFT
#include <fftw3.h>
@@ -45,11 +61,10 @@
int xtract_spectrum(const float *data, const int N, const void *argv, float *result){
- float *input, *rfft, q, temp, max;
+ float *input, *rfft, q, temp, max, NxN;
size_t bytes;
int n,
m,
- NxN,
M,
vector,
withDC,
@@ -89,7 +104,7 @@ int xtract_spectrum(const float *data, const int N, const void *argv, float *res
for(n = 1; n < M; n++){
if ((temp = XTRACT_SQ(rfft[n]) +
XTRACT_SQ(rfft[N - n])) > XTRACT_LOG_LIMIT)
- temp = log(sqrt(temp) / N);
+ temp = logf(sqrtf(temp) / (float)N);
else
temp = XTRACT_LOG_LIMIT_DB;
@@ -130,7 +145,7 @@ int xtract_spectrum(const float *data, const int N, const void *argv, float *res
for(n = 1; n < M; n++){
if ((temp = XTRACT_SQ(rfft[n]) + XTRACT_SQ(rfft[N - n])) >
XTRACT_LOG_LIMIT)
- temp = log(temp / NxN);
+ temp = logf(temp / NxN);
else
temp = XTRACT_LOG_LIMIT_DB;
@@ -161,8 +176,8 @@ int xtract_spectrum(const float *data, const int N, const void *argv, float *res
result[M + m] = n * q;
}
- result[m] = sqrt(XTRACT_SQ(rfft[n]) +
- XTRACT_SQ(rfft[N - n])) / N;
+ result[m] = sqrtf(XTRACT_SQ(rfft[n]) +
+ XTRACT_SQ(rfft[N - n])) / (float)N;
max = result[m] > max ? result[m] : max;
}
break;
@@ -254,7 +269,7 @@ int xtract_mfcc(const float *data, const int N, const void *argv, float *result)
for(n = 0; n < N; n++){
result[filter] += data[n] * f->filters[filter][n];
}
- result[filter] = log(result[filter] < XTRACT_LOG_LIMIT ? XTRACT_LOG_LIMIT : result[filter]);
+ result[filter] = logf(result[filter] < XTRACT_LOG_LIMIT ? XTRACT_LOG_LIMIT : result[filter]);
}
xtract_dct(result, f->n_filters, NULL, result);
@@ -334,13 +349,13 @@ int xtract_amdf(const float *data, const int N, const void *argv, float *result)
float md, temp;
while(n--){
- md = 0;
+ md = 0.f;
for(i = 0; i < N - n; i++){
temp = data[i] - data[i + n];
temp = (temp < 0 ? -temp : temp);
md += temp;
}
- result[n] = md / N;
+ result[n] = md / (float)N;
}
return XTRACT_SUCCESS;
@@ -353,12 +368,12 @@ int xtract_asdf(const float *data, const int N, const void *argv, float *result)
float sd;
while(n--){
- sd = 0;
+ sd = 0.f;
for(i = 0; i < N - n; i++){
/*sd = 1;*/
sd += XTRACT_SQ(data[i] - data[i + n]);
}
- result[n] = sd / N;
+ result[n] = sd / (float)N;
}
return XTRACT_SUCCESS;
@@ -488,13 +503,12 @@ int xtract_lpc(const float *data, const int N, const void *argv, float *result){
M = L * 2; /* The length of *result */
ref = result;
lpc = result+L;
-/*
+
if(error == 0.0){
- for(i = 0; i < M; i++)
- result[i] = 0.f;
+ memset(result, 0, M * sizeof(float));
return XTRACT_NO_RESULT;
}
-*/
+
memset(result, 0, M * sizeof(float));
for (i = 0; i < L; i++) {