aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/puredata/xtract~.c5
-rw-r--r--src/descriptors.c494
-rw-r--r--src/scalar.c8
-rw-r--r--src/vector.c44
-rw-r--r--xtract/libxtract.h17
-rw-r--r--xtract/xtract_macros.h17
-rw-r--r--xtract/xtract_scalar.h18
-rw-r--r--xtract/xtract_vector.h3
8 files changed, 554 insertions, 52 deletions
diff --git a/examples/puredata/xtract~.c b/examples/puredata/xtract~.c
index a1fdb76..b89287f 100644
--- a/examples/puredata/xtract~.c
+++ b/examples/puredata/xtract~.c
@@ -105,6 +105,7 @@ static void *xtract_new(t_symbol *me, t_int argc, t_atom *argv) {
t_xtract_tilde *x = (t_xtract_tilde *)pd_new(xtract_class);
xtract_mel_filter *mf;
t_int n, N, f, F, n_args, type;
+ t_float *argv_max;
t_function_descriptor *fd;
char *p_name, *p_desc, *author;
int *year;
@@ -138,6 +139,10 @@ static void *xtract_new(t_symbol *me, t_int argc, t_atom *argv) {
type = fd[f].argv.type;
if(n_args){
+ for(n = 0; n < n_args; n++){
+ argv_max = &fd[f].argv.max[n];
+ post("Argument %d, max: %.2f", n, *argv_max);
+ }
if(type == MEL_FILTER){
x->memory.argv = (size_t)(n_args * sizeof(xtract_mel_filter));
x->argv = (xtract_mel_filter *)getbytes(x->memory.argv);
diff --git a/src/descriptors.c b/src/descriptors.c
index e47ccdf..fb23303 100644
--- a/src/descriptors.c
+++ b/src/descriptors.c
@@ -26,35 +26,36 @@
void *xtract_make_descriptors(){
t_function_descriptor *fd, *d;
- t_type *type;
+ t_type *argv_type;
int f , F;
- char *name, *p_name, *desc, *p_desc, *author;
+ char *name, *p_name, *desc, *p_desc, *author, *argv_donor;
+ float *argv_min, *argv_max, *argv_def, *result_min, *result_max;
int *argc, *year;
t_vector *data_format;
- /* *result_format; */
+ t_unit *data_unit, *argv_unit, *result_unit;
+ t_bool *is_scalar;
+ t_vector *result_format;
f = F = XTRACT_FEATURES;
fd = malloc(XTRACT_FEATURES * sizeof(t_function_descriptor));
+ /* FIX - this file probably needs a rewrite for readability */
while(f--){
d = &fd[f];
argc = &d->argc;
- type = &d->argv.type;
+ argv_type = &d->argv.type;
switch(f){
- case MEAN:
case VARIANCE:
case STANDARD_DEVIATION:
case AVERAGE_DEVIATION:
- case SPECTRAL_MEAN:
case SPECTRAL_VARIANCE:
case SPECTRAL_STANDARD_DEVIATION:
case SPECTRAL_AVERAGE_DEVIATION:
- case ROLLOFF:
case SPECTRAL_INHARMONICITY:
case ODD_EVEN_RATIO:
case LOWEST_VALUE:
@@ -62,7 +63,7 @@ void *xtract_make_descriptors(){
case FAILSAFE_F0:
case TONALITY:
*argc = 1;
- *type = FLOAT;
+ *argv_type = FLOAT;
break;
case SKEWNESS:
case KURTOSIS:
@@ -73,17 +74,20 @@ void *xtract_make_descriptors(){
case HARMONIC_SPECTRUM:
case NOISINESS:
case CREST:
+ case ROLLOFF:
*argc = 2;
- *type = FLOAT;
+ *argv_type = FLOAT;
break;
case MFCC:
*argc = 1;
- *type = MEL_FILTER;
+ *argv_type = MEL_FILTER;
break;
case BARK_COEFFICIENTS:
*argc = BARK_BANDS;
- *type = INT;
+ *argv_type = INT;
break;
+ case MEAN:
+ case SPECTRAL_MEAN:
case SPECTRAL_CENTROID:
case IRREGULARITY_K:
case IRREGULARITY_J:
@@ -111,10 +115,175 @@ void *xtract_make_descriptors(){
case AUTOCORRELATION:
case AMDF:
case ASDF:
+ default:
*argc = 0;
break;
+ }
+
+ argv_min = &d->argv.min[0];
+ argv_max = &d->argv.max[0];
+ argv_def = &d->argv.def[0];
+ argv_unit = &d->argv.unit[0];
+
+ switch (f) {
+ /* argc = 1 */
+ case VARIANCE:
+ case SPECTRAL_VARIANCE:
+ case STANDARD_DEVIATION:
+ case AVERAGE_DEVIATION:
+ case SPECTRAL_STANDARD_DEVIATION:
+ case SPECTRAL_AVERAGE_DEVIATION:
+ case LOWEST_VALUE:
+ case TONALITY:
+ case MFCC:
+ *argv_min = ANY;
+ *argv_max = ANY;
+ *argv_def = ANY;
+ *argv_unit = ANY;
+ case SPECTRAL_INHARMONICITY:
+ case ODD_EVEN_RATIO:
+ *argv_min = 0.f;
+ *argv_max = SR_UPPER_LIMIT / 2;
+ *argv_def = FUNDAMENTAL_DEFAULT;
+ *argv_unit = HERTZ;
+ case F0:
+ case FAILSAFE_F0:
+ *argv_min = SR_LOWER_LIMIT;
+ *argv_max = SR_UPPER_LIMIT;
+ *argv_def = SR_DEFAULT;
+ *argv_unit = HERTZ;
+ /* argc = 2 */;
+ case ROLLOFF:
+ *argv_min = FFT_BANDS_MIN;
+ *argv_max = FFT_BANDS_MAX;
+ *argv_def = SPEC_BW_DEF ;
+ *argv_unit = HERTZ;
+ *(argv_min + 1) = 0.f;
+ *(argv_max + 1) = 100.f;
+ *(argv_def + 1) = 95.f;
+ *(argv_unit + 1) = PERCENT;
+ case SPECTRUM:
+ *argv_min = SR_LOWER_LIMIT / 2;
+ *argv_max = SR_UPPER_LIMIT / 2;
+ *argv_def = SR_DEFAULT / 2;
+ *argv_unit = HERTZ;
+ *(argv_min + 1) = 0;
+ *(argv_max + 1) = 3 ;
+ *(argv_def + 1) = 0;
+ *(argv_unit + 1) = NONE;
+ case PEAK_SPECTRUM:
+ *argv_min = SR_LOWER_LIMIT / 2;
+ *argv_max = SR_UPPER_LIMIT / 2;
+ *argv_def = SR_DEFAULT / 2;
+ *argv_unit = HERTZ;
+ *(argv_min + 1) = 0.f;
+ *(argv_max + 1) = 100.f ;
+ *(argv_def + 1) = 10.f ;
+ *(argv_unit + 1) = PERCENT;
+ case HARMONIC_SPECTRUM:
+ *argv_min = 0.f;
+ *argv_max = SR_UPPER_LIMIT / 2;
+ *argv_def = FUNDAMENTAL_DEFAULT;
+ *argv_unit = HERTZ;
+ *(argv_min + 1) = 0.f;
+ *(argv_max + 1) = 1.f ;
+ *(argv_def + 1) = .1f ;
+ *(argv_unit + 1) = NONE;
+ case NOISINESS:
+ case SKEWNESS:
+ case KURTOSIS:
+ case SPECTRAL_SKEWNESS:
+ case SPECTRAL_KURTOSIS:
+ case CREST:
+ *argv_min = NONE;
+ *argv_max = NONE;
+ *argv_def = NONE;
+ *argv_unit = NONE;
+ *(argv_min + 1) = NONE;
+ *(argv_max + 1) = NONE;
+ *(argv_def + 1) = NONE;
+ *(argv_unit + 1) = NONE;
+ case BARK_COEFFICIENTS:
+ /* BARK_COEFFICIENTS is special because argc = BARK_BANDS */
default:
- *argc = 0;
+ *argv_min = NONE;
+ *argv_max = NONE;
+ *argv_def = NONE;
+ *argv_unit = NONE;
+ }
+
+ argv_donor = &d->argv.donor[0];
+
+ switch (f) {
+ /* argc = 1 */
+ case VARIANCE:
+ *argv_donor = MEAN;
+ break;
+ case SPECTRAL_VARIANCE:
+ *argv_donor = SPECTRAL_MEAN;
+ break;
+ case STANDARD_DEVIATION:
+ *argv_donor = VARIANCE;
+ break;
+ case AVERAGE_DEVIATION:
+ *argv_donor = MEAN;
+ break;
+ case SPECTRAL_STANDARD_DEVIATION:
+ *argv_donor = SPECTRAL_VARIANCE;
+ break;
+ case SPECTRAL_AVERAGE_DEVIATION:
+ *argv_donor = SPECTRAL_MEAN;
+ break;
+ case SPECTRAL_INHARMONICITY:
+ case ODD_EVEN_RATIO:
+ *argv_donor = FAILSAFE_F0;
+ break;
+ case TONALITY:
+ *argv_donor = FLATNESS;
+ break;
+ case LOWEST_VALUE:
+ case F0:
+ case FAILSAFE_F0:
+ *argv_donor = ANY;
+ break;
+ case MFCC:
+ *argv_donor = INIT_MFCC;
+ break;
+ /* argc = 2 */;
+ case SPECTRUM:
+ case ROLLOFF:
+ case PEAK_SPECTRUM:
+ *argv_donor = ANY;
+ *(argv_donor + 1) = ANY;
+ break;
+ case SKEWNESS:
+ case KURTOSIS:
+ *argv_donor = MEAN;
+ *(argv_donor + 1) = STANDARD_DEVIATION;
+ break;
+ case SPECTRAL_SKEWNESS:
+ case SPECTRAL_KURTOSIS:
+ *argv_donor = SPECTRAL_MEAN;
+ *(argv_donor + 1) = SPECTRAL_STANDARD_DEVIATION;
+ break;
+ case HARMONIC_SPECTRUM:
+ *argv_donor = FAILSAFE_F0;
+ *(argv_donor + 1) = ANY;
+ break;
+ case NOISINESS:
+ *argv_donor = SUM;
+ *(argv_donor + 1) = SUM;
+ break;
+ case CREST:
+ *argv_donor = HIGHEST_VALUE;
+ *(argv_donor + 1) = SPECTRAL_MEAN;
+ break;
+ /* argc = BARK_BANDS */
+ case BARK_COEFFICIENTS:
+ *argv_donor = INIT_BARK;
+ break;
+ default:
+ *argv_donor = ANY;
break;
}
@@ -198,6 +367,71 @@ void *xtract_make_descriptors(){
break;
}
+ data_unit = &d->data.unit;
+
+ switch(f){
+
+ case MEAN:
+ case VARIANCE:
+ case STANDARD_DEVIATION:
+ case AVERAGE_DEVIATION:
+ case SKEWNESS:
+ case KURTOSIS:
+ case LOWEST_VALUE:
+ case HIGHEST_VALUE:
+ case SUM:
+ case ZCR:
+ case PEAK_SPECTRUM:
+ case TRISTIMULUS_1:
+ case TRISTIMULUS_2:
+ case TRISTIMULUS_3:
+ case DCT:
+ case AMDF:
+ case ASDF:
+ case IRREGULARITY_K:
+ case IRREGULARITY_J:
+ case ATTACK_TIME:
+ case DECAY_TIME:
+ case DELTA_FEATURE:
+ case FLUX:
+ case F0:
+ case FAILSAFE_F0:
+ case MFCC:
+ case AUTOCORRELATION:
+ case AUTOCORRELATION_FFT:
+ case ROLLOFF:
+ case NOISINESS:
+ case CREST:
+ case FLATNESS:
+ case POWER:
+ case BARK_COEFFICIENTS:
+ case RMS_AMPLITUDE:
+ case SMOOTHNESS:
+ case SPREAD:
+ case SHARPNESS:
+ case HPS:
+ case SPECTRUM:
+ case TONALITY:
+ case LOUDNESS:
+ *data_unit = ANY;
+ break;
+ case SPECTRAL_MEAN:
+ case SPECTRAL_VARIANCE:
+ case SPECTRAL_STANDARD_DEVIATION:
+ case SPECTRAL_AVERAGE_DEVIATION:
+ case SPECTRAL_SKEWNESS:
+ case SPECTRAL_KURTOSIS:
+ case SPECTRAL_CENTROID:
+ case SPECTRAL_SLOPE:
+ case HARMONIC_SPECTRUM:
+ case SPECTRAL_INHARMONICITY:
+ *data_unit = ANY_AMPLITUDE_HERTZ;
+ break;
+ case ODD_EVEN_RATIO:
+ *data_unit = HERTZ;
+ break;
+ }
+
name = d->algo.name;
p_name = d->algo.p_name;
desc = d->algo.desc;
@@ -214,6 +448,7 @@ void *xtract_make_descriptors(){
strcpy(desc, "Extract the mean of an input vector");
strcpy(p_desc, "Extract the mean of a range of values");
strcpy(author, "");
+ d->argv.type = NONE;
break;
case VARIANCE:
strcpy(name, "variance");
@@ -629,6 +864,241 @@ void *xtract_make_descriptors(){
strcpy(author, "");
break;
}
+
+
+ switch(f){
+
+ case VARIANCE:
+ case STANDARD_DEVIATION:
+ case AVERAGE_DEVIATION:
+ case SPECTRAL_VARIANCE:
+ case SPECTRAL_STANDARD_DEVIATION:
+ case SPECTRAL_AVERAGE_DEVIATION:
+ case SPECTRAL_INHARMONICITY:
+ case ODD_EVEN_RATIO:
+ case LOWEST_VALUE:
+ case F0:
+ case FAILSAFE_F0:
+ case TONALITY:
+ *argc = 1;
+ *argv_type = FLOAT;
+ break;
+ case SKEWNESS:
+ case KURTOSIS:
+ case SPECTRAL_SKEWNESS:
+ case SPECTRAL_KURTOSIS:
+ case SPECTRUM:
+ case PEAK_SPECTRUM:
+ case HARMONIC_SPECTRUM:
+ case NOISINESS:
+ case CREST:
+ case ROLLOFF:
+ *argc = 2;
+ *argv_type = FLOAT;
+ break;
+ case MFCC:
+ *argc = 1;
+ *argv_type = MEL_FILTER;
+ break;
+ case BARK_COEFFICIENTS:
+ *argc = BARK_BANDS;
+ *argv_type = INT;
+ break;
+ case MEAN:
+ case SPECTRAL_MEAN:
+ case SPECTRAL_CENTROID:
+ case IRREGULARITY_K:
+ case IRREGULARITY_J:
+ case TRISTIMULUS_1:
+ case TRISTIMULUS_2:
+ case TRISTIMULUS_3:
+ case SMOOTHNESS:
+ case FLATNESS:
+ case SPREAD:
+ case ZCR:
+ case LOUDNESS:
+ case HIGHEST_VALUE:
+ case SUM:
+ case RMS_AMPLITUDE:
+ case POWER:
+ case SHARPNESS:
+ case SPECTRAL_SLOPE:
+ case HPS:
+ case FLUX:
+ case ATTACK_TIME:
+ case DECAY_TIME:
+ case DELTA_FEATURE:
+ case AUTOCORRELATION_FFT:
+ case DCT:
+ case AUTOCORRELATION:
+ case AMDF:
+ case ASDF:
+ default:
+ *argc = 0;
+ break;
+ }
+
+ is_scalar = &d->is_scalar;
+
+ switch(f){
+ case MEAN:
+ case VARIANCE:
+ case STANDARD_DEVIATION:
+ case AVERAGE_DEVIATION:
+ case SKEWNESS:
+ case KURTOSIS:
+ case SPECTRAL_MEAN:
+ case SPECTRAL_VARIANCE:
+ case SPECTRAL_STANDARD_DEVIATION:
+ case SPECTRAL_AVERAGE_DEVIATION:
+ case SPECTRAL_SKEWNESS:
+ case SPECTRAL_KURTOSIS:
+ case SPECTRAL_CENTROID:
+ case IRREGULARITY_K:
+ case IRREGULARITY_J:
+ case TRISTIMULUS_1:
+ case TRISTIMULUS_2:
+ case TRISTIMULUS_3:
+ case SMOOTHNESS:
+ case SPREAD:
+ case ZCR:
+ case ROLLOFF:
+ case LOUDNESS:
+ case FLATNESS:
+ case TONALITY:
+ case CREST:
+ case NOISINESS:
+ case RMS_AMPLITUDE:
+ case SPECTRAL_INHARMONICITY:
+ case POWER:
+ case ODD_EVEN_RATIO:
+ case SHARPNESS:
+ case SPECTRAL_SLOPE:
+ case LOWEST_VALUE:
+ case HIGHEST_VALUE:
+ case SUM:
+ case HPS:
+ case F0:
+ case FAILSAFE_F0:
+ *is_scalar = TRUE;
+ break;
+ case AUTOCORRELATION:
+ case AMDF:
+ case ASDF:
+ case BARK_COEFFICIENTS:
+ case PEAK_SPECTRUM:
+ case SPECTRUM:
+ case AUTOCORRELATION_FFT:
+ case MFCC:
+ case DCT:
+ case HARMONIC_SPECTRUM:
+ *is_scalar = FALSE;
+ break;
+ default:
+ *is_scalar = TRUE;
+ break;
+
+ }
+
+ if(*is_scalar){
+
+ result_unit = &d->result.scalar.unit;
+ result_min = &d->result.scalar.min;
+ result_max = &d->result.scalar.max;
+
+ switch(f){
+ case MEAN:
+ case VARIANCE:
+ case STANDARD_DEVIATION:
+ case AVERAGE_DEVIATION:
+ case SKEWNESS:
+ case KURTOSIS:
+ case RMS_AMPLITUDE:
+ case LOWEST_VALUE:
+ case HIGHEST_VALUE:
+ case SUM:
+ *result_unit = ANY;
+ *result_min = ANY;
+ *result_max = ANY;
+ break;
+ case SPECTRAL_SKEWNESS:
+ case SPECTRAL_KURTOSIS:
+ case IRREGULARITY_K:
+ case IRREGULARITY_J:
+ case TRISTIMULUS_1:
+ case TRISTIMULUS_2:
+ case TRISTIMULUS_3:
+ case NOISINESS:
+ case SMOOTHNESS:
+ *result_unit = NONE;
+ *result_min = ANY; /* FIX: need to check these */
+ *result_max = ANY;
+ break;
+ case SPECTRAL_MEAN:
+ case SPECTRAL_VARIANCE:
+ case SPECTRAL_STANDARD_DEVIATION:
+ case SPECTRAL_AVERAGE_DEVIATION:
+ case SPECTRAL_CENTROID:
+ case SPREAD:
+ case F0:
+ case FAILSAFE_F0:
+ case HPS:
+ case ROLLOFF:
+ *result_unit = HERTZ;
+ *result_min = 0.f;
+ *result_max = SR_UPPER_LIMIT / 2;
+ case ZCR:
+ *result_unit = HERTZ;
+ *result_min = 0.f;
+ *result_max = ANY;
+ case ODD_EVEN_RATIO:
+ *result_unit = NONE;
+ *result_min = 0.f;
+ *result_max = 1.f;
+ case LOUDNESS:
+ case FLATNESS:
+ case TONALITY:
+ case CREST:
+ case SPECTRAL_INHARMONICITY:
+ case POWER:
+ case SHARPNESS:
+ case SPECTRAL_SLOPE:
+ default:
+ *result_unit = UNKNOWN;
+ *result_min = UNKNOWN;
+ *result_max = UNKNOWN;
+ }
+ }
+ else {
+
+ result_min = NULL;
+ result_max = NULL;
+ result_unit = &d->result.vector.unit;
+ result_format = &d->result.vector.format;
+
+ switch(f) {
+ case AUTOCORRELATION:
+ case AMDF:
+ case ASDF:
+ case DCT:
+ *result_format = ARBITRARY_SERIES;
+ *result_unit = ANY;
+ case BARK_COEFFICIENTS:
+ *result_format = BARK_COEFFS;
+ *result_unit = UNKNOWN; /* FIX: check */
+ case PEAK_SPECTRUM:
+ case SPECTRUM:
+ case HARMONIC_SPECTRUM:
+ *result_format = SPECTRAL;
+ *result_unit = ANY_AMPLITUDE_HERTZ;
+ case AUTOCORRELATION_FFT:
+ case MFCC:
+ *result_format = MEL_COEFFS;
+ *result_unit = UNKNOWN; /* FIX: check */
+ default:
+ break;
+ }
+ }
}
return fd;
diff --git a/src/scalar.c b/src/scalar.c
index 6e7faeb..68b5b19 100644
--- a/src/scalar.c
+++ b/src/scalar.c
@@ -374,18 +374,20 @@ int xtract_zcr(const float *data, const int N, const void *argv, float *result){
int xtract_rolloff(const float *data, const int N, const void *argv, float *result){
int n = N;
- float pivot, temp;
+ float pivot, temp, percentile;
pivot = temp = 0.f;
+ percentile = ((float *)argv)[1];
while(n--) pivot += data[n];
- pivot *= ((float *)argv)[0];
+ pivot *= percentile / 100.f;
for(n = 0; temp < pivot; n++)
temp += data[n];
- *result = (n / (float)N) * (((float *)argv)[1] * .5);
+ *result = n * ((float *)argv)[0];
+ /* *result = (n / (float)N) * (((float *)argv)[1] * .5); */
return SUCCESS;
}
diff --git a/src/vector.c b/src/vector.c
index c4135cb..e7cd759 100644
--- a/src/vector.c
+++ b/src/vector.c
@@ -32,7 +32,7 @@
int xtract_spectrum(const float *data, const int N, const void *argv, float *result){
- float *input, *rfft, q, temp;
+ float *input, *rfft, nyquist, temp;
size_t bytes;
int n , NxN, M, vector;
fftwf_plan plan;
@@ -44,10 +44,10 @@ int xtract_spectrum(const float *data, const int N, const void *argv, float *res
input = (float *)malloc(bytes = N * sizeof(float));
input = memcpy(input, data, bytes);
- q = *(float *)argv;
+ nyquist = *(float *)argv;
vector = (int)*((float *)argv+1);
- CHECK_q;
+ CHECK_nyquist;
plan = fftwf_plan_r2r_1d(N, input, rfft, FFTW_R2HC, FFTW_ESTIMATE);
@@ -57,7 +57,7 @@ int xtract_spectrum(const float *data, const int N, const void *argv, float *res
case MAGNITUDE_SPECTRUM:
for(n = 0; n < M; n++){
result[n] = sqrt(SQ(rfft[n]) + SQ(rfft[N - n])) / N;
- result[M + n] = n * q;
+ result[M + n] = n * nyquist;
}
break;
case LOG_MAGNITUDE_SPECTRUM:
@@ -68,13 +68,13 @@ int xtract_spectrum(const float *data, const int N, const void *argv, float *res
temp = LOG_LIMIT_DB;
/*Normalise*/
result[n] = (temp + DB_SCALE_OFFSET) / DB_SCALE_OFFSET;
- result[M + n] = n * q;
+ result[M + n] = n * nyquist;
}
break;
case POWER_SPECTRUM:
for(n = 0; n < M; n++){
result[n] = (SQ(rfft[n]) + SQ(rfft[N - n])) / NxN;
- result[M + n] = n * q;
+ result[M + n] = n * nyquist;
}
break;
case LOG_POWER_SPECTRUM:
@@ -84,20 +84,20 @@ int xtract_spectrum(const float *data, const int N, const void *argv, float *res
else
temp = LOG_LIMIT_DB;
result[n] = (temp + DB_SCALE_OFFSET) / DB_SCALE_OFFSET;
- result[M + n] = n * q;
+ result[M + n] = n * nyquist;
}
break;
default:
/* MAGNITUDE_SPECTRUM */
for(n = 0; n < M; n++){
result[n] = sqrt(SQ(rfft[n]) + SQ(rfft[N - n])) / N;
- result[M + n] = n * q;
+ result[M + n] = n * nyquist;
}
break;
}
/* result[0] = fabs(temp[0]) / N */
- result[M] = q * .5;
+ result[M] = nyquist * .5;
fftwf_destroy_plan(plan);
fftwf_free(rfft);
@@ -279,25 +279,25 @@ int xtract_bark_coefficients(const float *data, const int N, const void *argv, f
int xtract_peak_spectrum(const float *data, const int N, const void *argv, float *result){
- float thresh, max, y, y2, y3, p, q, *input = NULL;
+ float threshold, max, y, y2, y3, p, nyquist, *input = NULL;
size_t bytes;
int n = N, M, rv = SUCCESS;
- thresh = max = y = y2 = y3 = p = q = 0.f;
+ threshold = max = y = y2 = y3 = p = nyquist = 0.f;
if(argv != NULL){
- thresh = ((float *)argv)[0];
- q = ((float *)argv)[1];
+ nyquist = ((float *)argv)[0];
+ threshold = ((float *)argv)[1];
}
else
rv = BAD_ARGV;
- if(thresh < 0 || thresh > 100){
- thresh = 0;
+ if(threshold < 0 || threshold > 100){
+ threshold = 0;
rv = BAD_ARGV;
}
- CHECK_q;
+ CHECK_nyquist;
input = (float *)malloc(bytes = N * sizeof(float));
@@ -311,15 +311,15 @@ int xtract_peak_spectrum(const float *data, const int N, const void *argv, float
while(n--)
max = MAX(max, input[n]);
- thresh *= .01 * max;
+ threshold *= .01 * max;
result[0] = 0;
result[M] = 0;
for(n = 1; n < M; n++){
- if(input[n] >= thresh){
+ if(input[n] >= threshold){
if(input[n] > input[n - 1] && input[n] > input[n + 1]){
- result[M + n] = q * (n + (p = .5 * (y = input[n-1] -
+ result[M + n] = nyquist * (n + (p = .5 * (y = input[n-1] -
(y3 = input[n+1])) / (input[n - 1] - 2 *
(y2 = input[n]) + input[n + 1])));
result[n] = y2 - .25 * (y - y3) * p;
@@ -344,12 +344,12 @@ int xtract_harmonic_spectrum(const float *data, const int N, const void *argv, f
int n = (N >> 1), M = n;
const float *freqs, *amps;
- float f0, thresh, ratio, nearest, distance;
+ float f0, threshold, ratio, nearest, distance;
amps = data;
freqs = data + n;
f0 = *((float *)argv);
- thresh = *((float *)argv+1);
+ threshold = *((float *)argv+1);
ratio = nearest = distance = 0.f;
@@ -358,7 +358,7 @@ int xtract_harmonic_spectrum(const float *data, const int N, const void *argv, f
ratio = freqs[n] / f0;
nearest = round(ratio);
distance = fabs(nearest - ratio);
- if(distance > thresh)
+ if(distance > threshold)
result[n] = result[M + n] = 0.f;
else {
result[n] = amps[n];
diff --git a/xtract/libxtract.h b/xtract/libxtract.h
index 51561cd..a78e239 100644
--- a/xtract/libxtract.h
+++ b/xtract/libxtract.h
@@ -112,6 +112,12 @@ enum features_ {
HARMONIC_SPECTRUM
};
+/** \brief Enumeration of feature initialisation functions */
+enum feature_init_ {
+ INIT_MFCC = 100,
+ INIT_BARK
+};
+
/** \brief Enumeration of feature types */
enum feature_types_ {
SCALAR,
@@ -146,14 +152,20 @@ enum spectrum_ {
/** \brief Enumeration of data types*/
typedef enum type_ {
FLOAT,
+ FLOATARRAY,
INT,
MEL_FILTER
} t_type;
/** \brief Enumeration of units*/
typedef enum unit_ {
- HERTZ,
- DBFS
+ /* NONE, ANY */
+ HERTZ = 2,
+ ANY_AMPLITUDE_HERTZ,
+ DBFS,
+ DBFS_HERTZ,
+ PERCENT,
+ SONE
} t_unit;
/** \brief Boolean */
@@ -217,6 +229,7 @@ typedef struct _function_descriptor {
t_bool is_scalar;
+ /* The result.<> entries in descritors.c need to be checked */
union {
struct {
diff --git a/xtract/xtract_macros.h b/xtract/xtract_macros.h
index f3b85f2..19983d3 100644
--- a/xtract/xtract_macros.h
+++ b/xtract/xtract_macros.h
@@ -35,16 +35,29 @@ extern "C" {
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define NEEDS_FFTW printf("LibXtract must be compiled with fftw support to use this function.\n")
-#define CHECK_q if(!q) q = 44100.f / N
#define VERY_SMALL_NUMBER 2e-42
#define LOG_LIMIT VERY_SMALL_NUMBER
#define LOG_LIMIT_DB -96
#define DB_SCALE_OFFSET 96
#define VERY_BIG_NUMBER 2e42
-#define SR_LIMIT 192000
+#define SR_UPPER_LIMIT 192000
+#define SR_LOWER_LIMIT 22050
+#define SR_DEFAULT 44100
+#define FUNDAMENTAL_DEFAULT 440
+#define CHECK_nyquist if(!nyquist) nyquist = SR_DEFAULT / N
+#define SR_LIMIT SR_UPPER_LIMIT
+#define FFT_BANDS_MIN 16
+#define FFT_BANDS_MAX 65536
+#define FFT_BANDS_DEF 1024
+#define SPEC_BW_MIN 0.168 /* Minimum spectral bandwidth (= SR_LOWER_LIMIT / \
+ FFT_BANDS_MAX*/
+#define SPEC_BW_MAX 12000 /* SR_UPPER_LIMIT / FFT_BANDS_MIN */
+#define SPEC_BW_DEF 43.066 /* SR_DEFAULT / FFT_BANDS_DEF */
#define BARK_BANDS 26
#define NONE 0
+#define ANY -1
+#define UNKNOWN -2
#define MAXARGS 4
#define MAX_NAME_LENGTH 64
#define MAX_AUTHOR_LENGTH 128
diff --git a/xtract/xtract_scalar.h b/xtract/xtract_scalar.h
index 63aa6cd..c3dbfc7 100644
--- a/xtract/xtract_scalar.h
+++ b/xtract/xtract_scalar.h
@@ -220,7 +220,7 @@ int xtract_zcr(const float *data, const int N, const void *argv, float *result);
*
* \param *data: a pointer to the first element in an array of floats representing the magnitude coefficients from the spectrum of an audio vector, (e.g. the first half of the array pointed to by *result from xtract_spectrum().
* \param N: the number of elements to be considered
- * \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 *argv: a pointer to an array containing a float representing (samplerate / N ) and a float representing the threshold for rolloff, i.e. the percentile at which the rolloff is determined, expressed as a percentage, and
* \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(const float *data, const int N, const void *argv, float *result);
@@ -258,10 +258,10 @@ int xtract_tonality(const float *data, const int N, const void *argv, float *res
/** \brief Extract the noisiness of an input vector using a method described by Tae Hong Park (2000)
*
- * \param *data: a pointer to the first element in an array of floats representing the magnitude coefficients from the spectrum of an audio vector, (e.g. the first half of the array pointed to by *result from xtract_spectrum().
- * \param N: the number of elements to be considered
- * \param *argv: a pointer to NULL
- * \param *result: the noisiness of N values from the array pointed to by *data
+ * \param *data: a pointer to NULL
+ * \param N:
+ * \param *argv: a pointer to an array containing a float represnting the number of harmonic partials in a spectrum, and a float representing the number of partials in a spectrum
+ * \param *result: the noisiness coefficient as calculated from argv
*/
int xtract_noisiness(const float *data, const int N, const void *argv, float *result);
@@ -285,9 +285,9 @@ int xtract_spectral_inharmonicity(const float *data, const int N, const void *ar
/** \brief Extract the spectral crest of an input vector using a method described by Peeters (2003)
*
- * \param *data: a pointer to the first element in an array of floats representing the magnitude coefficients from the spectrum of an audio vector, (e.g. the first half of the array pointed to by *result from xtract_spectrum().
- * \param N: the number of elements to be considered
- * \param *argv: a pointer to NULL
+ * \param *data: a pointer to NULL
+ * \param N: not used
+ * \param *argv: a pointer to an array containing a float representing the maximum value in a spectrum, and a float representing the mean value of a spectrum
* \param *result: the spectral crest of N values from the array pointed to by *data
*/
int xtract_crest(const float *data, const int N, const void *argv, float *result);
@@ -306,7 +306,7 @@ int xtract_power(const float *data, const int N, const void *argv, float *result
*
* \param *data: a pointer to the first element in an array of floats representing the frequencies of the harmonic spectrum of an audio vector. It is sufficient to pass in a pointer to the second half of the array pointed to by *result from xtract_harmonic_spectrum().
* \param N: the number of elements to be considered. If using the array pointed to by *result from xtract_harmonics, N should equal half the total array size i.e., just the frequencies of the peaks.
- * \param *argv: a pointer to NULL
+ * \param *argv: a pointer to a float representing the fundamental frequency of the input vector.
* \param *result: the odd/even harmonic ratio of N values from the array pointed to by *data
*/
int xtract_odd_even_ratio(const float *data, const int N, const void *argv, float *result);
diff --git a/xtract/xtract_vector.h b/xtract/xtract_vector.h
index 26a7ff4..4be7e45 100644
--- a/xtract/xtract_vector.h
+++ b/xtract/xtract_vector.h
@@ -112,11 +112,10 @@ int xtract_bark_coefficients(const float *data, const int N, const void *argv, f
/** \brief Extract the amplitude and frequency of spectral peaks from a magnitude spectrum
* \param *data: a pointer to an array of size N containing N/2 magnitude/power/log magnitude/log power coefficients and N/2 bin frequencies. (e.g. the first half of the array pointed to by *result from xtract_spectrum().
* \param N: the size of the output array (note: the input array can be of size N/2, i.e. just the magnitudes)
- * \param *argv: a pointer to an array containing the peak threshold as percentage of the magnitude of the maximum peak found, and a float representing (samplerate / N)
+ * \param *argv: a pointer to an array of floats, the first representing (samplerate / N), the second representing the peak threshold as percentage of the magnitude of the maximum peak found
* \param *result: a pointer to an array of size N containing N/2 magnitude/power/log magnitude/log power coefficients and N/2 bin frequencies.
*
*/
-
int xtract_peak_spectrum(const float *data, const int N, const void *argv, float *result);
/** \brief Extract the harmonic spectrum of from a of a peak spectrum