diff options
author | Jamie Bullock <jamie@postlude.co.uk> | 2006-12-11 17:57:27 +0000 |
---|---|---|
committer | Jamie Bullock <jamie@postlude.co.uk> | 2006-12-11 17:57:27 +0000 |
commit | bff72881ced8120c84c3d70e1ffeaa6af5f741d0 (patch) | |
tree | 7d0bd26e46241a80a6280126386025800fcb14df | |
parent | 60b05d46c3450750d2df237bf3ee5825909ea895 (diff) | |
download | LibXtract-bff72881ced8120c84c3d70e1ffeaa6af5f741d0.tar.gz LibXtract-bff72881ced8120c84c3d70e1ffeaa6af5f741d0.tar.bz2 LibXtract-bff72881ced8120c84c3d70e1ffeaa6af5f741d0.zip |
Changes to xtract_inharmonicity - made parameters consistent with other
xtractors that use peak spectrum. Fixed memory alloc bug in pd example.
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | configure.in | 2 | ||||
-rw-r--r-- | examples/puredata/xtract~.c | 146 | ||||
-rw-r--r-- | src/scalar.c | 15 | ||||
-rw-r--r-- | src/vector.c | 2 | ||||
-rw-r--r-- | xtract/xtract_scalar.h | 14 |
6 files changed, 130 insertions, 58 deletions
@@ -1,4 +1,11 @@ -2006-11-10 Jamie Bullock <jamie@postlude.co.uk> +2006-12-11 Jamie Bullock <jamie@postlude.co.uk> + * version 0.3.2 + * changed xtract_inharmonicity so that it takes frequencies AND + amplitudes of peaks from *data rather than via *argv. This is + consistent with xtract_centroid and others, and it means the data can + come directly from xtract_peaks + * Improvements to pd example (fixed memory allocation bugs) +2006-12-10 Jamie Bullock <jamie@postlude.co.uk> * version 0.3.1 * Fixed xtract_init_mfcc (array entries zeroed out if not set) 2006-11-10 Jamie Bullock <jamie@postlude.co.uk> diff --git a/configure.in b/configure.in index 322f507..616faad 100644 --- a/configure.in +++ b/configure.in @@ -4,7 +4,7 @@ m4_define(libxtract_major_version, 0) # Increment for feature additions and enhancements m4_define(libxtract_minor_version, 3) # Increment for fixes -m4_define(libxtract_fix_version, 1) +m4_define(libxtract_fix_version, 2) m4_define(libxtract_version, libxtract_major_version.libxtract_minor_version.libxtract_fix_version) diff --git a/examples/puredata/xtract~.c b/examples/puredata/xtract~.c index 05dc5e0..575a170 100644 --- a/examples/puredata/xtract~.c +++ b/examples/puredata/xtract~.c @@ -18,20 +18,27 @@ 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" + #define XTRACT #include "xtract/libxtract.h" -#include "m_pd.h" #define BLOCKSIZE 1024 #define NYQUIST 22050.0f static t_class *xtract_class; +/* Struct for keeping track of memory allocations */ +typedef struct _tracked_memory { + char argv; +} tracked_memory; + typedef struct _xtract { t_object x_obj; t_float f; t_int feature; t_int feature_type; + tracked_memory memory; void *argv; } t_xtract_tilde; @@ -92,7 +99,7 @@ static void *xtract_new(t_symbol *me, t_int argc, t_atom *argv) { t_symbol *tmp; t_xtract_tilde *x = (t_xtract_tilde *)pd_new(xtract_class); xtract_mel_filter *f; - t_int n, N; + t_int n, N, floatargs = 0; N = BLOCKSIZE; @@ -100,12 +107,10 @@ static void *xtract_new(t_symbol *me, t_int argc, t_atom *argv) { tmp = atom_getsymbol(argv); + /* map creation args to features */ if(tmp == gensym("mean")) x->feature = MEAN; - else if(tmp == gensym("variance")) { - x->feature = VARIANCE; - x->argv = getbytes(sizeof(t_float)); - } - else if(tmp == gensym("standard_deviation")) x->feature = STANDARD_DEVIATION; + else if(tmp == gensym("variance")) x->feature = VARIANCE; + else if(tmp == gensym("standard_deviation"))x->feature = STANDARD_DEVIATION; else if(tmp == gensym("average_deviation")) x->feature = AVERAGE_DEVIATION; else if(tmp == gensym("skewness")) x->feature = SKEWNESS; else if(tmp == gensym("kurtosis")) x->feature = KURTOSIS; @@ -130,15 +135,10 @@ static void *xtract_new(t_symbol *me, t_int argc, t_atom *argv) { else if(tmp == gensym("odd_even_ratio")) x->feature = ODD_EVEN_RATIO; else if(tmp == gensym("sharpness")) x->feature = SHARPNESS; else if(tmp == gensym("slope")) x->feature = SLOPE; - else if(tmp == gensym("f0")){ - x->feature = F0; - x->argv = getbytes(3 * sizeof(t_float)); - } + else if(tmp == gensym("f0")) x->feature = F0; else if(tmp == gensym("hps"))x->feature = HPS; - else if(tmp == gensym("lowest_match")){ - x->feature = LOWEST_MATCH; - x->argv = getbytes(sizeof(t_float)); - } + else if(tmp == gensym("lowest_match"))x->feature = LOWEST_MATCH; + else if(tmp == gensym("dct")) x->feature = DCT; else if(tmp == gensym("magnitude_spectrum")) x->feature = MAGNITUDE_SPECTRUM; else if(tmp == gensym("autocorrelation")) x->feature = AUTOCORRELATION; @@ -146,17 +146,96 @@ static void *xtract_new(t_symbol *me, t_int argc, t_atom *argv) { x->feature = AUTOCORRELATION_FFT; else if(tmp == gensym("amdf")) x->feature = AMDF; else if(tmp == gensym("asdf")) x->feature = ASDF; - else if(tmp == gensym("mfcc")){ + else if(tmp == gensym("peaks")) x->feature = PEAKS; + else if(tmp == gensym("flux")) x->feature = FLUX; + else if(tmp == gensym("attack_time")) x->feature = ATTACK_TIME; + else if(tmp == gensym("decay_time")) x->feature = DECAY_TIME; + else if(tmp == gensym("delta")) x->feature = DELTA_FEATURE; + else if(tmp == gensym("mfcc")) x->feature = MFCC; + else if(tmp == gensym("harmonics")) x->feature = HARMONICS; + else if(tmp == gensym("bark_coefficients")) x->feature = BARK_COEFFICIENTS; + else post("xtract~: No feature selected"); + + /* allocate memory for feature arguments */ + switch(x->feature){ + case MEAN: + case VARIANCE: + case STANDARD_DEVIATION: + case AVERAGE_DEVIATION: + case ROLLOFF: + case INHARMONICITY: + case LOWEST_MATCH: + case F0: + floatargs = 1; + break; + case SKEWNESS: + case KURTOSIS: + case PEAKS: + case HARMONICS: + floatargs = 2; + break; + case CENTROID: + case IRREGULARITY_K: + case IRREGULARITY_J: + case TRISTIMULUS_1: + case TRISTIMULUS_2: + case TRISTIMULUS_3: + case SMOOTHNESS: + case SPREAD: + case ZCR: + case LOUDNESS: + case FLATNESS: + case TONALITY: + case CREST: + case NOISINESS: + case RMS_AMPLITUDE: + case POWER: + case ODD_EVEN_RATIO: + case SHARPNESS: + case SLOPE: + case HPS: + case FLUX: /*not implemented */ + case ATTACK_TIME: /*not implemented */ + case DECAY_TIME: /*not implemented */ + case DELTA_FEATURE: /*not implemented */ + case AUTOCORRELATION_FFT: + case MAGNITUDE_SPECTRUM: + case MFCC: + case DCT: + case AUTOCORRELATION: + case AMDF: + case ASDF: + case BARK_COEFFICIENTS: + floatargs = 0; + break; + default: + floatargs = 0; + break; + } + + if(x->feature == MFCC){ + x->memory.argv = (size_t)(sizeof(xtract_mel_filter)); + 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->argv = (t_int *)getbytes(x->memory.argv); + } + else if (floatargs){ + x->memory.argv = (size_t)(floatargs * sizeof(t_float)); + x->argv = (t_float *)getbytes(x->memory.argv); + } + else + x->memory.argv = 0; + + /* do init if needed */ + if(x->feature == MFCC){ - x->argv = (xtract_mel_filter *)getbytes(sizeof(xtract_mel_filter)); - /* Change! can use x->argv because it is a pointer to void */ - /* put the malloc here */ - x->feature = MFCC; f = x->argv; f->n_filters = 20; - post("filters = %d", ((xtract_mel_filter *)x->argv)->n_filters); + post("xtract~: mfcc: filters = %d", ((xtract_mel_filter *)x->argv)->n_filters); f->filters = (t_float **)getbytes(f->n_filters * sizeof(t_float *)); for(n = 0; n < f->n_filters; n++) @@ -165,23 +244,9 @@ static void *xtract_new(t_symbol *me, t_int argc, t_atom *argv) { xtract_init_mfcc(N, NYQUIST, EQUAL_GAIN, 18000.0f, 80.0f, f->n_filters, f->filters); } - else if(tmp == gensym("dct")) x->feature = DCT; - else if(tmp == gensym("harmonics")){ - x->feature = HARMONICS; - x->argv = getbytes(3 * sizeof(t_float)); - } - else if(tmp == gensym("bark_coefficients")){ - x->feature = BARK_COEFFICIENTS; - x->argv = (t_int *)getbytes(BARK_BANDS * sizeof(t_int)); + else if(x->feature == BARK_COEFFICIENTS) xtract_init_bark(N, NYQUIST, x->argv); - } - else if(tmp == gensym("peaks")) x->feature = PEAKS; - else if(tmp == gensym("flux")) x->feature = FLUX; - else if(tmp == gensym("attack_time")) x->feature = ATTACK_TIME; - else if(tmp == gensym("decay_time")) x->feature = DECAY_TIME; - else if(tmp == gensym("delta")) x->feature = DELTA_FEATURE; - else post("xtract~: No feature selected"); - + if(x->feature == AUTOCORRELATION || x->feature == AUTOCORRELATION_FFT || x->feature == MFCC || x->feature == AMDF || x->feature == ASDF|| x->feature == DCT || x->feature == BARK_COEFFICIENTS || @@ -198,7 +263,6 @@ static void *xtract_new(t_symbol *me, t_int argc, t_atom *argv) { /* argv through right inlet */ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("list"), gensym("list")); - /* if feature is vector, create signal out */ if(x->feature_type == VECTOR) outlet_new(&x->x_obj, &s_signal); @@ -237,9 +301,9 @@ static void xtract_tilde_show_help(t_xtract_tilde *x, t_symbol *s){ } static void xtract_tilde_free(t_xtract_tilde *x) { - /*FIX */ - if(x->argv != NULL) - freebytes(x->argv, 0); + + if(x->argv != NULL && x->memory.argv) + freebytes(x->argv, x->memory.argv); } void xtract_tilde_setup(void) { diff --git a/src/scalar.c b/src/scalar.c index cf453f9..8d0f821 100644 --- a/src/scalar.c +++ b/src/scalar.c @@ -316,19 +316,20 @@ int xtract_rms_amplitude(float *data, int N, void *argv, float *result){ int xtract_inharmonicity(float *data, int N, void *argv, float *result){ - int n = N; + int n = N >> 1; float num = 0.f, den = 0.f, - *fund, *freq; + fund, *freqs, *amps; - fund = *(float **)argv; - freq = fund+1; + fund = *(float *)argv; + freqs = data; + amps = data + n; while(n--){ - num += abs(freq[n] - n * *fund) * SQ(data[n]); - den += SQ(data[n]); + num += abs(freqs[n] - n * fund) * SQ(amps[n]); + den += SQ(amps[n]); } - *result = (2 * num) / (*fund * den); + *result = (2 * num) / (fund * den); return SUCCESS; } diff --git a/src/vector.c b/src/vector.c index 091e3f5..72e97f8 100644 --- a/src/vector.c +++ b/src/vector.c @@ -271,7 +271,7 @@ int xtract_peaks(float *data, int N, void *argv, float *result){ return (return_code ? return_code : SUCCESS); } - + int xtract_harmonics(float *data, int N, void *argv, float *result){ int n = (N >> 1), M = n; diff --git a/xtract/xtract_scalar.h b/xtract/xtract_scalar.h index eae8afc..9d95c09 100644 --- a/xtract/xtract_scalar.h +++ b/xtract/xtract_scalar.h @@ -47,7 +47,7 @@ int xtract_mean(float *data, int N, void *argv, float *result); * * \param *data: a pointer to the first element in an array of floats * \param N: the number of elements to be considered - * \param *argv: a pointer to a value representing the mean of the input vector + * \param *argv: a pointer to a float representing the mean of the input vector * \param *result: the variance of N values from the array pointed to by *data */ int xtract_variance(float *data, int N, void *argv, float *result); @@ -56,7 +56,7 @@ int xtract_variance(float *data, int N, void *argv, float *result); * * \param *data: a pointer to the first element in an array of floats * \param N: the number of elements to be considered - * \param *argv: a pointer to a value representing the variance of the input vector + * \param *argv: a pointer to a float representing the variance of the input vector * \param *result: the deviation of N values from the array pointed to by *data */ int xtract_standard_deviation(float *data, int N, void *argv, float *result); @@ -65,7 +65,7 @@ int xtract_standard_deviation(float *data, int N, void *argv, float *result); * * \param *data: a pointer to the first element in an array of floats * \param N: the number of elements to be considered - * \param *argv: a pointer to a value representing the mean of the input vector + * \param *argv: a pointer to a float representing the mean of the input vector * \param *result: the average deviation of N values from the array pointed to by *data */ int xtract_average_deviation(float *data, int N, void *argv, float *result); @@ -74,7 +74,7 @@ int xtract_average_deviation(float *data, int N, void *argv, float *result); * * \param *data: a pointer to the first element in an array of floats * \param N: the number of elements to be considered - * \param *argv: a pointer to an array of values representing the mean and standard deviation of the input vector + * \param *argv: a pointer to an array of floats representing the mean and standard deviation of the input vector * \param *result: the skewness of N values from the array pointed to by *data */ int xtract_skewness(float *data, int N, void *argv, float *result); @@ -88,7 +88,7 @@ int xtract_skewness(float *data, int N, void *argv, float *result); */ int xtract_kurtosis(float *data, int N, void *argv, float *result); -/** \brief Extract the kurtosis of an input vector +/** \brief Extract the centroid of an input vector * * \param *data: a pointer to the first element in an array of floats represeting a frequency spectrum of size N/2 and a magnitude peak spectrum of size N/2 (This is the output format of xtract_peaks) * \param N: the number of elements to be considered @@ -218,9 +218,9 @@ int xtract_rms_amplitude(float *data, int N, void *argv, float *result); /** \brief Extract the Inharmonicity of an input vector * - * \param *data: a pointer to the first element in an array of floats representing the amplitudes of the spectral peaks in an audio vector + * \param *data: a pointer to the first element in an array of floats represeting a frequency spectrum of size N/2 and a magnitude peak spectrum of size N/2 (This is the output format of xtract_peaks) * \param N: the number of elements to be considered - * \param *argv: a pointer to a multidimensional array containing the fundamental frequency of the input vector in the first element of the first dimension, and the frequencies of the spectral peaks in the second dimension + * \param *argv: a pointer to a float representing the fundamental frequency of the input vector. * \param *result: the inharmonicity of N values from the array pointed to by *data */ int xtract_inharmonicity(float *data, int N, void *argv, float *result); |