Mercurial > hg > libxtract
changeset 42:84e69b155098
Numerous fixes, see ChangeLog
author | Jamie Bullock <jamie@postlude.co.uk> |
---|---|
date | Tue, 12 Dec 2006 21:47:42 +0000 |
parents | afb9e6fee244 |
children | 4a36f70a76e9 |
files | ChangeLog TODO examples/puredata/xtract~.c src/scalar.c src/vector.c xtract/xtract_scalar.h xtract/xtract_vector.h |
diffstat | 7 files changed, 107 insertions(+), 50 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Mon Dec 11 17:57:27 2006 +0000 +++ b/ChangeLog Tue Dec 12 21:47:42 2006 +0000 @@ -1,3 +1,10 @@ +2006-12-12 Jamie Bullock <jamie@postlude.co.uk> + * version 0.3.3 + * Fixed errors in skewnes, kurtosis, irregularity_k, irregularity_j, + tristimulus_1, tristimulus_2, and tristimulus_3. + * Tested the above + * Changed rolloff so output is in Hz. This means that a second + argument (samplerate) needs to be passed in as argv[1] 2006-12-11 Jamie Bullock <jamie@postlude.co.uk> * version 0.3.2 * changed xtract_inharmonicity so that it takes frequencies AND
--- a/TODO Mon Dec 11 17:57:27 2006 +0000 +++ b/TODO Tue Dec 12 21:47:42 2006 +0000 @@ -4,5 +4,7 @@ Add Pure Data help file Add delta functions Add Max/MSP external example +Add self documentation +Check sfm and tonality ...do other stuff and eventually... ...optimise!
--- a/examples/puredata/xtract~.c Mon Dec 11 17:57:27 2006 +0000 +++ b/examples/puredata/xtract~.c Tue Dec 12 21:47:42 2006 +0000 @@ -19,6 +19,7 @@ /* calculates the spectral xtract of one frame, given peak frequency and amplitude to first and second inputs respectively */ #include "m_pd.h" +#include <math.h> #define XTRACT #include "xtract/libxtract.h" @@ -53,6 +54,9 @@ if(return_code == FEATURE_NOT_IMPLEMENTED) pd_error(x, "Feature not implemented"); + + /* set nan, inf or -inf to 0 */ + result = (isinf(result) || isnan(result) ? 0 : result); outlet_float(x->x_obj.ob_outlet, result); return (w+4); @@ -166,6 +170,7 @@ case INHARMONICITY: case LOWEST_MATCH: case F0: + case TONALITY: floatargs = 1; break; case SKEWNESS: @@ -185,7 +190,6 @@ case ZCR: case LOUDNESS: case FLATNESS: - case TONALITY: case CREST: case NOISINESS: case RMS_AMPLITUDE: @@ -218,7 +222,7 @@ x->argv = (xtract_mel_filter *)getbytes(x->memory.argv); } else if(x->feature == BARK_COEFFICIENTS){ - x->memory.argv = (size_t)(sizeof(BARK_BANDS * sizeof(t_int))); + x->memory.argv = (size_t)(BARK_BANDS * sizeof(t_int)); x->argv = (t_int *)getbytes(x->memory.argv); } else if (floatargs){
--- a/src/scalar.c Mon Dec 11 17:57:27 2006 +0000 +++ b/src/scalar.c Tue Dec 12 21:47:42 2006 +0000 @@ -30,7 +30,7 @@ int n = N; while(n--) - *result += *data++; + *result += data[n]; *result /= N; @@ -42,7 +42,7 @@ int n = N; while(n--) - *result += *data++ - *(float *)argv; + *result += data[n] - *(float *)argv; *result = SQ(*result) / (N - 1); @@ -59,9 +59,9 @@ int xtract_average_deviation(float *data, int N, void *argv, float *result){ int n = N; - + while(n--) - *result += fabs(*data++ - *(float *)argv); + *result += fabs(data[n] - *(float *)argv); *result /= N; @@ -72,11 +72,15 @@ int n = N; - while(n--) - *result += (*data++ - ((float *)argv)[0]) / ((float *)argv)[1]; + float temp; - *result = pow(*result, 3) / N; + while(n--){ + temp = (data[n] - ((float *)argv)[0]) / ((float *)argv)[1]; + *result += pow(temp, 3); + } + *result /= N; + return SUCCESS; } @@ -84,11 +88,16 @@ int n = N; - while(n--) - *result += (*data++ - ((float *)argv)[0]) / ((float *)argv)[1]; + float temp; - *result = pow(*result, 4) / N - 3; + while(n--){ + temp = (data[n] - ((float *)argv)[0]) / ((float *)argv)[1]; + *result += pow(temp, 4); + } + *result /= N; + *result -= 3.0f; + return SUCCESS; } @@ -118,7 +127,7 @@ M = N - 1; for(n = 1; n < M; n++) - *result += abs(data[n] - (data[n-1] + data[n] + data[n+1]) / 3); + *result += fabs(data[n] - (data[n-1] + data[n] + data[n+1]) / 3); return SUCCESS; } @@ -130,8 +139,8 @@ float num = 0.f, den = 0.f; while(n--){ - num += data[n] - data[n+1]; - den += data[n] * data[n]; + num += pow(data[n] - data[n+1], 2); + den += pow(data[n], 2); } *result = num / den; @@ -143,12 +152,19 @@ int n = N; - float den = 0.f; + float den, p1, temp; - while(n--) - den += data[n]; + den = p1 = temp = 0.f; - *result = data[0] / den; + for(n = 0; n < N; n++){ + if((temp = data[n])){ + den += temp; + if(!p1) + p1 = temp; + } + } + + *result = p1 / den; return SUCCESS; } @@ -157,26 +173,43 @@ int n = N; - float den = 0.f; + float den, p2, p3, p4, temp; - while(n--) - den += data[n]; + den = p2 = p3 = p4 = temp = 0.f; - *result = (data[1] + data[2] + data[3]) / den; + 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; + } + } + + *result = (p2 + p3 + p4) / den; return SUCCESS; } int xtract_tristimulus_3(float *data, int N, void *argv, float *result){ - int n = N; + int n = N, count = 0; - float den = 0.f, num = 0.f; + float den, num, temp; - while(n--) - den += data[n]; + den = num = temp = 0.f; - num = den - data[0] + data[1] + data[2] + data[3]; + for(n = 0; n < N; n++){ + if((temp = data[n])){ + den += temp; + if(count >= 5) + num += temp; + count++; + } + } *result = num / den; @@ -231,15 +264,18 @@ int xtract_rolloff(float *data, int N, void *argv, float *result){ int n = N; - float pivot = 0.f, temp = 0.f; + float pivot, temp; + + pivot = temp = 0.f; while(n--) pivot += data[n]; - pivot *= *(float *)argv; + pivot *= ((float *)argv)[0]; - for(n = 0; temp < pivot; temp += data[n++]); + for(n = 0; temp < pivot; n++) + temp += data[n]; - *result = n; + *result = (n / (float)N) * (((float *)argv)[1] * .5); return SUCCESS; } @@ -259,21 +295,27 @@ int xtract_flatness(float *data, int N, void *argv, float *result){ - int n = N; + int n; - float num = 0.f, den = 0.f; + float num, den, temp; - while(n--){ - if(data[n] !=0){ - num *= data[n]; - den += data[n]; + den = temp = num = 0.f; + + for(n = 0; n < N; n++){ + if((temp = data[n])){ + if(!num) + num = den = temp; + else{ + num *= temp; + den += temp; + } } } - - num = pow(num, 1 / N); + + num = powf(num, 1.0f / N); den /= N; - *result = 10 * log10(num / den); + *result = num / den; return SUCCESS; }
--- a/src/vector.c Mon Dec 11 17:57:27 2006 +0000 +++ b/src/vector.c Tue Dec 12 21:47:42 2006 +0000 @@ -292,8 +292,10 @@ distance = fabs(nearest - ratio); if(distance > thresh) result[n] = result[M + n] = 0.f; - else - result[n] = result[M + n] = freqs[n]; + else { + result[n] = freqs[n]; + result[M + n] = amps[n]; + } } else result[n] = result[M + n] = 0.f;
--- a/xtract/xtract_scalar.h Mon Dec 11 17:57:27 2006 +0000 +++ b/xtract/xtract_scalar.h Tue Dec 12 21:47:42 2006 +0000 @@ -117,7 +117,7 @@ /** \brief Calculate the Tristimulus of an input vector using a method described by Pollard and Jansson (1982) * - * \param *data: a pointer to the first element in an array of floats representing the amplitudes of the harmonic spectrum of an audio vector e.g. a pointer to the second half of the array pointed to by *result from xtract_harmonics() + * \param *data: a pointer to the first element in an array of floats representing the amplitudes of the harmonic spectrum of an audio vector e.g. a pointer to the second half of the array pointed to by *result from xtract_harmonics(). The amplitudes of the peak spectrum (e.g. *result from xtract_peaks()) can be used if one wishes to consider all partials not just harmonics. * \param N: the number of elements to be considered * \param *argv: a pointer to NULL * \param *result: the tristimulus of N values from the array pointed to by *data @@ -162,8 +162,8 @@ * * \param *data: a pointer to the first element in an array of floats representing the magnitude spectrum of an audio vector * \param N: the number of elements to be considered - * \param *argv: a pointer to a floating point value representing the threshold for rolloff, i.e. the percentile at which the rolloff is determined - * \param *result: the spectral rolloff of N values from the array pointed to by *data + * \param *argv: a pointer to an array containing a floating point value representing the threshold for rolloff, i.e. the percentile at which the rolloff is determined, expressed in the range 0-1.0, and a float representing the sample rate in Hz + * \param *result: the spectral rolloff in Hz of N values from the array pointed to by *data. This is the point in the spectrum below which argv[0] of the energy is distributed. */ int xtract_rolloff(float *data, int N, void *argv, float *result); @@ -191,9 +191,9 @@ /** \brief Extract the tonality factor of an input vector using a method described by Tristan Jehan (2005) * - * \param *data: a pointer to the first element in an array of floats representing the spectral peaks of an audio vector - * \param N: the number of elements to be considered - * \param *argv: a pointer to NULL + * \param *data: not used. + * \param N: not used + * \param *argv: a pointer to the spectral flatness measure of an audio vector (e.g. the output from xtract_flatness) * \param *result: the tonality factor of N values from the array pointed to by *data */ int xtract_tonality(float *data, int N, void *argv, float *result);
--- a/xtract/xtract_vector.h Mon Dec 11 17:57:27 2006 +0000 +++ b/xtract/xtract_vector.h Tue Dec 12 21:47:42 2006 +0000 @@ -101,7 +101,7 @@ /** \brief Extract Bark band coefficients based on a method * \param *data: a pointer to the first element in an array of floats representing the magnitude spectrum of an audio vector * \param N: the number of array elements to be considered - * \param *argv: a pointer to an array of ints representing the limits of each bark band + * \param *argv: a pointer to an array of ints representing the limits of each bark band. This can be obtained by calling xtract_init_bark. * \param *result: a pointer to an array containing resultant bark coefficients * * The limits array pointed to by *argv must be obtained by first calling xtract_init_bark