diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/descriptors.c | 2 | ||||
-rw-r--r-- | src/helper.c | 22 | ||||
-rw-r--r-- | src/init.c | 2 | ||||
-rw-r--r-- | src/libxtract.c | 1 | ||||
-rw-r--r-- | src/scalar.c | 237 | ||||
-rw-r--r-- | src/vector.c | 44 |
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 +} + @@ -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++) { |