aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJamie Bullock <jamie@postlude.co.uk>2006-12-11 17:57:27 +0000
committerJamie Bullock <jamie@postlude.co.uk>2006-12-11 17:57:27 +0000
commitbff72881ced8120c84c3d70e1ffeaa6af5f741d0 (patch)
tree7d0bd26e46241a80a6280126386025800fcb14df
parent60b05d46c3450750d2df237bf3ee5825909ea895 (diff)
downloadLibXtract-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--ChangeLog9
-rw-r--r--configure.in2
-rw-r--r--examples/puredata/xtract~.c146
-rw-r--r--src/scalar.c15
-rw-r--r--src/vector.c2
-rw-r--r--xtract/xtract_scalar.h14
6 files changed, 130 insertions, 58 deletions
diff --git a/ChangeLog b/ChangeLog
index c1a9d18..62c2815 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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);