diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | examples/puredata/xtract~.c | 8 | ||||
-rw-r--r-- | src/scalar.c | 120 | ||||
-rw-r--r-- | src/vector.c | 6 | ||||
-rw-r--r-- | xtract/xtract_scalar.h | 12 | ||||
-rw-r--r-- | xtract/xtract_vector.h | 2 |
7 files changed, 107 insertions, 50 deletions
@@ -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 @@ -4,5 +4,7 @@ Fix xtract_hps - it doesn't work! 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! diff --git a/examples/puredata/xtract~.c b/examples/puredata/xtract~.c index 575a170..77945f8 100644 --- a/examples/puredata/xtract~.c +++ b/examples/puredata/xtract~.c @@ -19,6 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /* 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 @@ static t_int *xtract_perform(t_int *w) { 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 @@ static void *xtract_new(t_symbol *me, t_int argc, t_atom *argv) { case INHARMONICITY: case LOWEST_MATCH: case F0: + case TONALITY: floatargs = 1; break; case SKEWNESS: @@ -185,7 +190,6 @@ static void *xtract_new(t_symbol *me, t_int argc, t_atom *argv) { case ZCR: case LOUDNESS: case FLATNESS: - case TONALITY: case CREST: case NOISINESS: case RMS_AMPLITUDE: @@ -218,7 +222,7 @@ static void *xtract_new(t_symbol *me, t_int argc, t_atom *argv) { 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){ diff --git a/src/scalar.c b/src/scalar.c index 8d0f821..476b843 100644 --- a/src/scalar.c +++ b/src/scalar.c @@ -30,7 +30,7 @@ int xtract_mean(float *data, int N, void *argv, float *result){ int n = N; while(n--) - *result += *data++; + *result += data[n]; *result /= N; @@ -42,7 +42,7 @@ int xtract_variance(float *data, int N, void *argv, float *result){ 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_standard_deviation(float *data, int N, void *argv, float *result){ 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 xtract_skewness(float *data, int N, void *argv, float *result){ 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 xtract_kurtosis(float *data, int N, void *argv, float *result){ 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 @@ int xtract_irregularity_k(float *data, int N, void *argv, float *result){ 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 @@ int xtract_irregularity_j(float *data, int N, void *argv, float *result){ 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 xtract_tristimulus_1(float *data, int N, void *argv, float *result){ 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 xtract_tristimulus_2(float *data, int N, void *argv, float *result){ 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_zcr(float *data, int N, void *argv, float *result){ 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_loudness(float *data, int N, void *argv, float *result){ 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; } diff --git a/src/vector.c b/src/vector.c index 72e97f8..275b2b7 100644 --- a/src/vector.c +++ b/src/vector.c @@ -292,8 +292,10 @@ int xtract_harmonics(float *data, int N, void *argv, float *result){ 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; diff --git a/xtract/xtract_scalar.h b/xtract/xtract_scalar.h index 9d95c09..8beceec 100644 --- a/xtract/xtract_scalar.h +++ b/xtract/xtract_scalar.h @@ -117,7 +117,7 @@ int xtract_irregularity_j(float *data, int N, void *argv, float *result); /** \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 @@ int xtract_zcr(float *data, int N, void *argv, float *result); * * \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 @@ int xtract_flatness(float *data, int N, void *argv, float *result); /** \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); diff --git a/xtract/xtract_vector.h b/xtract/xtract_vector.h index 21cc8a3..a8b0550 100644 --- a/xtract/xtract_vector.h +++ b/xtract/xtract_vector.h @@ -101,7 +101,7 @@ int xtract_asdf(float *data, int N, void *argv, float *result); /** \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 |