From 46ee1ba4b2e3eda3e14abfc969356f6dcb0c6dc0 Mon Sep 17 00:00:00 2001 From: Jamie Bullock Date: Wed, 20 Dec 2006 15:34:56 +0000 Subject: Added new features: sum, highest_value, crest and noisiness --- src/libxtract.c | 8 ++++-- src/scalar.c | 76 ++++++++++++++++++++++++++++++++++++++++++--------------- src/vector.c | 19 +++++---------- 3 files changed, 69 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/libxtract.c b/src/libxtract.c index 11faeee..f729ccf 100644 --- a/src/libxtract.c +++ b/src/libxtract.c @@ -51,7 +51,9 @@ int(*xtract[])(const float *, const int, const void *, float *) = { xtract_odd_even_ratio, xtract_sharpness, xtract_slope, - xtract_lowest, + xtract_lowest_value, + xtract_highest_value, + xtract_sum, xtract_hps, xtract_f0, xtract_failsafe_f0, @@ -101,7 +103,9 @@ char *xtract_help_strings[] = { "xtract_odd_even_ratio", "xtract_sharpness", "xtract_slope", - "xtract_lowest", + "xtract_lowest_value", + "xtract_highest_value", + "xtract_sum", "xtract_hps", "xtract_f0", "xtract_failsafe_f0", diff --git a/src/scalar.c b/src/scalar.c index 02f0f18..c7d6edd 100644 --- a/src/scalar.c +++ b/src/scalar.c @@ -320,11 +320,11 @@ int xtract_flatness(const float *data, const int N, const void *argv, float *res num = pow(num, 1.f / N); den /= N; - if(num < 1e-20) - num = 1e-20; + if(num < VERY_SMALL_NUMBER) + num = VERY_SMALL_NUMBER; - if(den < 1e-20) - den = 1e-20; + if(den < VERY_SMALL_NUMBER) + den = VERY_SMALL_NUMBER; *result = num / den; @@ -338,7 +338,7 @@ int xtract_tonality(const float *data, const int N, const void *argv, float *res sfm = *(float *)argv; - sfmdb = (sfm > 0 ? (10 * log10(sfm)) / -60 : 0); + sfmdb = (sfm > 0 ? ((10 * log10(sfm)) / -60) : 0); *result = MIN(sfmdb, 1); @@ -347,13 +347,33 @@ int xtract_tonality(const float *data, const int N, const void *argv, float *res int xtract_crest(const float *data, const int N, const void *argv, float *result){ - return FEATURE_NOT_IMPLEMENTED; + float max, mean; + + max = mean = 0.f; + + max = *(float *)argv; + mean = *((float *)argv+1); + + *result = max / mean; + + return SUCCESS; } int xtract_noisiness(const float *data, const int N, const void *argv, float *result){ - return FEATURE_NOT_IMPLEMENTED; + float h, i, p; /*harmonics, inharmonics, partials */ + + i = p = h = 0.f; + + h = *(float *)argv; + p = *((float *)argv+1); + + i = p - h; + + *result = i / p; + + return SUCCESS; } @@ -431,24 +451,43 @@ int xtract_slope(const float *data, const int N, const void *argv, float *result } -int xtract_lowest(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){ - float lower, upper, lowest; int n = N; + float temp; - lower = *(float *)argv; - upper = *((float *)argv+1); - - lowest = upper; + *result = data[N]; - while(n--) { - if(data[n] > lower) - *result = MIN(lowest, data[n]); + while(n--){ + if((temp = data[n]) > *(float *)argv) + *result = MIN(*result, data[n]); } - *result = (*result == upper ? -0 : *result); + return SUCCESS; +} + +int xtract_highest_value(const float *data, const int N, const void *argv, float *result){ + + int n = N; + + *result = data[N]; + + while(n--) + *result = MAX(*result, data[n]); + + return SUCCESS; +} + + +int xtract_sum(const float *data, const int N, const void *argv, float *result){ + + int n = N; + + while(n--) + *result += *data++; return SUCCESS; + } int xtract_hps(const float *data, const int N, const void *argv, float *result){ @@ -599,8 +638,7 @@ int xtract_failsafe_f0(const float *data, const int N, const void *argv, float * argf[1] = *(float *)argv; xtract_peaks(magnitudes, N, argf, peaks); argf[0] = 0.f; - argf[1] = N >> 1; - xtract_lowest(peaks, argf[1], argf, result); + xtract_lowest_value(peaks, N >> 1, argf, result); free(magnitudes); free(peaks); diff --git a/src/vector.c b/src/vector.c index b0e42d5..3a6e587 100644 --- a/src/vector.c +++ b/src/vector.c @@ -245,8 +245,8 @@ int xtract_peaks(const float *data, const int N, const void *argv, float *result return_code = BAD_ARGV; } else{ - thresh = 0; - sr = 44100; + thresh = 0.f; + sr = 44100.f; } input = (float *)malloc(bytes = N * sizeof(float)); @@ -259,7 +259,7 @@ int xtract_peaks(const float *data, const int N, const void *argv, float *result M = N >> 1; width = sr / N; - y = y2 = y3 = p = max = 0; + y = y2 = y3 = p = max = 0.f; if(thresh < 0 || thresh > 100){ thresh = 0; @@ -267,19 +267,12 @@ int xtract_peaks(const float *data, const int N, const void *argv, float *result } if(!sr){ - sr = 44100; + sr = 44100.f; return_code = BAD_ARGV; } - while(n--){ + while(n--) max = MAX(max, input[n]); - /* ensure we never take log10(0) */ - /*input[n] = (input[n] < LOG_LIMIT ? LOG_LIMIT : input[n]);*/ - if ((input[n] * 100000) <= 1) - /* We get a more stable peak this way */ - input[n] = 1; - - } thresh *= .01 * max; @@ -289,7 +282,7 @@ int xtract_peaks(const float *data, const int N, const void *argv, float *result for(n = 1; n < M; n++){ if(input[n] >= thresh){ if(input[n] > input[n - 1] && input[n] > input[n + 1]){ - result[n] = width * (n + (p = .5 * (y = 20 * log10(input[n-1]) - (y3 = 20 * log10(input[n+1]))) / (20 * log10(input[n - 1]) - 2 * (y2 = 20 * log10(input[n])) + 20 * log10(input[n + 1])))); + result[n] = width * (n + (p = .5 * (y = input[n-1] - (y3 = input[n+1])) / (input[n - 1] - 2 * (y2 = input[n]) + input[n + 1]))); result[M + n] = y2 - .25 * (y - y3) * p; } else{ -- cgit v1.2.3