aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO4
-rw-r--r--examples/puredata/xtract~.c28
-rw-r--r--src/descriptors.c307
-rw-r--r--src/libxtract.c16
-rw-r--r--src/scalar.c99
-rw-r--r--src/vector.c47
-rw-r--r--xtract/libxtract.h18
-rw-r--r--xtract/xtract_macros.h2
-rw-r--r--xtract/xtract_scalar.h67
-rw-r--r--xtract/xtract_vector.h23
10 files changed, 415 insertions, 196 deletions
diff --git a/TODO b/TODO
index 03a3094..31a0d97 100644
--- a/TODO
+++ b/TODO
@@ -1,3 +1,7 @@
+Add spectral_flux
+Add geometric_mean
+Add spectral_mean, spectral_deviation, spectral_geometric_mean etc.
+Add weighted temporal features as per Peeters (xtract_weighted_mean etc) weight given as argv?
Improve noise robustness of xtract_f0
Add feature advertisement
Fix xtract_hps - it doesn't work!
diff --git a/examples/puredata/xtract~.c b/examples/puredata/xtract~.c
index 25b176a..54b0bf8 100644
--- a/examples/puredata/xtract~.c
+++ b/examples/puredata/xtract~.c
@@ -20,6 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "m_pd.h"
#include <math.h>
+#include <string.h>
#define XTRACT
#include "xtract/libxtract.h"
@@ -105,6 +106,10 @@ static void *xtract_new(t_symbol *me, t_int argc, t_atom *argv) {
xtract_mel_filter *mf;
t_int n, N, f, F, n_args, type;
t_function_descriptor *fd;
+ char *p_name, *p_desc, *author;
+ int *year;
+
+ p_name = p_desc = author = NULL;
n_args = type = x->feature = 0;
@@ -124,7 +129,6 @@ static void *xtract_new(t_symbol *me, t_int argc, t_atom *argv) {
/* map creation arg to feature */
if(tmp == gensym(fd[f].algo.name)){
x->feature = f;
- /* FIX: possible bug if no argument given */
break;
}
}
@@ -149,8 +153,24 @@ static void *xtract_new(t_symbol *me, t_int argc, t_atom *argv) {
else
x->memory.argv = 0;
}
+
+
+ p_name = fd[f].algo.p_name;
+ p_desc = fd[f].algo.p_desc;
+ author = fd[f].algo.author;
+ year = &fd[f].algo.year;
+
+ if(argc){
+ if(strcmp(p_name, ""))
+ post("xtract~: %s", p_name );
+ if(strcmp(p_desc, ""))
+ post("xtract~: %s", p_desc );
+ if(strcmp(author, "") && year)
+ post("xtract~: %s(%d)", author, *year);
+ }
+ else
+ post("xtract~: No arguments given");
- post("xtract~: %s", fd[f].algo.p_name);
/* do init if needed */
if(x->feature == MFCC){
@@ -174,8 +194,8 @@ static void *xtract_new(t_symbol *me, t_int argc, t_atom *argv) {
if(x->feature == AUTOCORRELATION || x->feature == AUTOCORRELATION_FFT ||
x->feature == MFCC || x->feature == AMDF || x->feature == ASDF||
x->feature == DCT || x->feature == BARK_COEFFICIENTS ||
- x->feature == MAGNITUDE_SPECTRUM || x->feature == PEAKS ||
- x->feature == HARMONICS)
+ x->feature == MAGNITUDE_SPECTRUM || x->feature == PEAK_SPECTRUM ||
+ x->feature == HARMONIC_SPECTRUM)
x->feature_type = VECTOR;
else if (x->feature == FLUX || x->feature == ATTACK_TIME ||
diff --git a/src/descriptors.c b/src/descriptors.c
index 8b00084..abd5d15 100644
--- a/src/descriptors.c
+++ b/src/descriptors.c
@@ -24,13 +24,13 @@
#define XTRACT
void *xtract_make_descriptors(){
-
+
t_function_descriptor *fd, *d;
t_type *type;
int f , F;
char *name, *p_name, *desc, *p_desc, *author;
int *argc, *year;
-
+
f = F = XTRACT_FEATURES;
fd = malloc(XTRACT_FEATURES * sizeof(t_function_descriptor));
@@ -43,12 +43,17 @@ void *xtract_make_descriptors(){
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 INHARMONICITY:
+ case SPECTRAL_INHARMONICITY:
case MAGNITUDE_SPECTRUM:
case ODD_EVEN_RATIO:
case LOWEST_VALUE:
@@ -56,26 +61,28 @@ void *xtract_make_descriptors(){
case FAILSAFE_F0:
case TONALITY:
*argc = 1;
- d->argv.type = FLOAT;
+ *type = FLOAT;
break;
case SKEWNESS:
case KURTOSIS:
- case PEAKS:
- case HARMONICS:
+ case SPECTRAL_SKEWNESS:
+ case SPECTRAL_KURTOSIS:
+ case PEAK_SPECTRUM:
+ case HARMONIC_SPECTRUM:
case NOISINESS:
case CREST:
*argc = 2;
- d->argv.type = FLOAT;
+ *type = FLOAT;
break;
case MFCC:
*argc = 1;
- d->argv.type = MEL_FILTER;
+ *type = MEL_FILTER;
break;
case BARK_COEFFICIENTS:
*argc = BARK_BANDS;
- d->argv.type = INT;
+ *type = INT;
break;
- case CENTROID:
+ case SPECTRAL_CENTROID:
case IRREGULARITY_K:
case IRREGULARITY_J:
case TRISTIMULUS_1:
@@ -91,7 +98,7 @@ void *xtract_make_descriptors(){
case RMS_AMPLITUDE:
case POWER:
case SHARPNESS:
- case SLOPE:
+ case SPECTRAL_SLOPE:
case HPS:
case FLUX:
case ATTACK_TIME:
@@ -121,67 +128,101 @@ void *xtract_make_descriptors(){
switch(f){
case MEAN:
strcpy(name, "mean");
- strcpy(p_name, "Spectral Mean");
+ strcpy(p_name, "Mean");
strcpy(desc, "Extract the mean of an input vector");
- strcpy(p_desc, "Extract the mean of a audio spectrum");
+ strcpy(p_desc, "Extract the mean of a range of values");
strcpy(author, "");
break;
case VARIANCE:
strcpy(name, "variance");
strcpy(p_name, "Variance");
strcpy(desc, "Extract the variance of an input vector");
- strcpy(p_desc, "Extract the variance of an audio spectrum");
+ strcpy(p_desc, "Extract the variance of a range of values");
strcpy(author, "");
break;
case STANDARD_DEVIATION:
strcpy(name, "standard_deviation");
strcpy(p_name, "Standard Deviation");
- strcpy(desc, "Extract the standard deviation of an input \
- vector");
- strcpy(p_desc, "Extract the standard deviation of an audio \
- spectrum");
+ strcpy(desc,
+ "Extract the standard deviation of an input vector");
+ strcpy(p_desc,
+ "Extract the standard deviation of a range of values");
strcpy(author, "");
break;
case AVERAGE_DEVIATION:
strcpy(name, "average_deviation");
strcpy(p_name, "Average Deviation");
- strcpy(desc, "Extract the average deviation of an input vector");
- strcpy(p_desc, "Extract the average deviation of an audio \
- spectrum");
+ strcpy(desc,
+ "Extract the average deviation of an input vector");
+ strcpy(p_desc,
+ "Extract the average deviation of a range of values");
strcpy(author, "");
break;
- case ROLLOFF:
- strcpy(name, "rolloff");
- strcpy(p_name, "Spectral Rolloff");
- strcpy(desc, "Extract the rolloff point of a spectrum");
- strcpy(p_desc, "Extract the rolloff point of an audio \
- spectrum");
+ case SPECTRAL_MEAN:
+ strcpy(name, "spectral_mean");
+ strcpy(p_name, "Spectral Mean");
+ strcpy(desc, "Extract the mean of an input spectrum");
+ strcpy(p_desc, "Extract the mean of an audio spectrum");
+ strcpy(author, "");
+ break;
+ case SPECTRAL_VARIANCE:
+ strcpy(name, "spectral_variance");
+ strcpy(p_name, "Spectral Variance");
+ strcpy(desc, "Extract the variance of an input spectrum");
+ strcpy(p_desc, "Extract the variance of an audio spectrum");
strcpy(author, "");
break;
- case INHARMONICITY:
- strcpy(name, "inharmonicity");
+ case SPECTRAL_STANDARD_DEVIATION:
+ strcpy(name, "spectral_standard_deviation");
+ strcpy(p_name, "Spectral Standard Deviation");
+ strcpy(desc,
+ "Extract the standard deviation of an input spectrum");
+ strcpy(p_desc,
+ "Extract the standard deviation of an audio spectrum");
+ strcpy(author, "");
+ break;
+ case SPECTRAL_AVERAGE_DEVIATION:
+ strcpy(name, "spectral_average_deviation");
+ strcpy(p_name, "Spectral Average Deviation");
+ strcpy(desc,
+ "Extract the average deviation of an input spectrum");
+ strcpy(p_desc,
+ "Extract the average deviation of an audio spectrum");
+ strcpy(author, "");
+ break;
+ case ROLLOFF:
+ strcpy(name, "spectral_rolloff");
+ strcpy(p_name, "Spectral Rolloff");
+ strcpy(desc,
+ "Extract the rolloff point of a spectrum");
+ strcpy(p_desc,
+ "Extract the rolloff point of an audio spectrum");
+ strcpy(author, "Bee Suan Ong");
+ *year = 2005;
+ break;
+ case SPECTRAL_INHARMONICITY:
+ strcpy(name, "spectral_inharmonicity");
strcpy(p_name, "Inharmonicity");
strcpy(desc, "Extract the inharmonicity of a spectrum");
- strcpy(p_desc, "Extract the inharmonicity of an audio \
- spectrum");
- strcpy(author, "");
+ strcpy(p_desc,
+ "Extract the inharmonicity of an audio spectrum");
break;
case MAGNITUDE_SPECTRUM:
strcpy(name, "magnitude_spectrum");
strcpy(p_name, "Magnitude Spectrum");
- strcpy(desc, "Extract the magnitude spectrum of an input \
- vector");
- strcpy(p_desc, "Extract the magnitude spectrum of an \
- audio signal");
+ strcpy(desc,
+ "Extract the magnitude spectrum of an input vector");
+ strcpy(p_desc,
+ "Extract the magnitude spectrum of an audio signal");
strcpy(author, "");
break;
case ODD_EVEN_RATIO:
strcpy(name, "odd_even_ratio");
strcpy(p_name, "Odd/Even Harmonic Ratio");
- strcpy(desc, "Extract the odd-to-even harmonic ratio of a \
- spectrum");
- strcpy(p_desc, "Extract the odd-to-even harmonic ratio of an \
- audio spectrum");
+ strcpy(desc,
+ "Extract the odd-to-even harmonic ratio of a spectrum");
+ strcpy(p_desc,
+ "Extract the odd-to-even harmonic ratio of an audio spectrum");
strcpy(author, "");
break;
case LOWEST_VALUE:
@@ -195,16 +236,16 @@ void *xtract_make_descriptors(){
strcpy(name, "f0");
strcpy(p_name, "Fundamental Frequency");
strcpy(desc, "Extract the fundamental frequency of a signal");
- strcpy(p_desc, "Extract the fundamental frequency of an audio \
- signal");
+ strcpy(p_desc,
+ "Extract the fundamental frequency of an audio signal");
strcpy(author, "");
break;
case FAILSAFE_F0:
strcpy(name, "failsafe_f0");
strcpy(p_name, "Fundamental Frequency (failsafe)");
strcpy(desc, "Extract the fundamental frequency of a signal");
- strcpy(p_desc, "Extract the fundamental frequency of an audio \
- signal");
+ strcpy(p_desc,
+ "Extract the fundamental frequency of an audio signal");
strcpy(author, "");
break;
case TONALITY:
@@ -212,33 +253,34 @@ void *xtract_make_descriptors(){
strcpy(p_name, "Tonality");
strcpy(desc, "Extract the tonality of a spectrum");
strcpy(p_desc, "Extract the tonality an audio spectrum");
- strcpy(author, "");
+ strcpy(author, "Tristan Jehan");
+ *year = 2005;
break;
- case SKEWNESS:
- strcpy(name, "skewness");
+ case SPECTRAL_SKEWNESS:
+ strcpy(name, "spectral_skewness");
strcpy(p_name, "Spectral Skewness");
- strcpy(desc, "Extract the skewness of an input vector");
+ strcpy(desc, "Extract the skewness of an input spectrum");
strcpy(p_desc, "Extract the skewness of an audio spectrum");
strcpy(author, "");
break;
- case KURTOSIS:
- strcpy(name, "kurtosis");
+ case SPECTRAL_KURTOSIS:
+ strcpy(name, "spectral_kurtosis");
strcpy(p_name, "Spectral Kurtosis");
- strcpy(desc, "Extract the kurtosis of an input vector");
+ strcpy(desc, "Extract the kurtosis of an input spectrum");
strcpy(p_desc, "Extract the kurtosis of an audio spectrum");
strcpy(author, "");
break;
- case PEAKS:
- strcpy(name, "peaks");
- strcpy(p_name, "Spectral Peaks");
+ case PEAK_SPECTRUM:
+ strcpy(name, "peak_spectrum");
+ strcpy(p_name, "Peak Spectrum");
strcpy(desc, "Extract the spectral peaks from of a spectrum");
- strcpy(p_desc, "Extract the spectral peaks from an audio \
- spectrum");
+ strcpy(p_desc,
+ "Extract the spectral peaks from an audio spectrum");
strcpy(author, "");
break;
- case HARMONICS:
- strcpy(name, "harmonics");
- strcpy(p_name, "Spectral Harmonics");
+ case HARMONIC_SPECTRUM:
+ strcpy(p_name, "harmonic_spectrum");
+ strcpy(p_name, "Harmonic Spectrum");
strcpy(desc, "Extract the harmonics from a spectrum");
strcpy(p_desc, "Extract the harmonics from an audio spectrum");
strcpy(author, "");
@@ -248,120 +290,132 @@ void *xtract_make_descriptors(){
strcpy(p_name, "Noisiness");
strcpy(desc, "Extract the noisiness of a spectrum");
strcpy(p_desc, "Extract the noisiness of an audio spectrum");
- strcpy(author, "");
+ strcpy(author, "Tae Hong Park");
+ *year = 2000;
break;
case CREST:
strcpy(name, "crest");
strcpy(p_name, "Spectral Crest Measure");
- strcpy(desc, "Extract the spectral crest measure of a \
- spectrum");
- strcpy(p_desc, "Extract the spectral crest measure of a \
- audio spectrum");
- strcpy(author, "");
+ strcpy(desc,
+ "Extract the spectral crest measure of a spectrum");
+ strcpy(p_desc,
+ "Extract the spectral crest measure of a audio spectrum");
+ strcpy(author, "Peeters");
+ *year = 2003;
break;
case MFCC:
strcpy(name, "mfcc");
- strcpy(p_name, "Mel Frequency Cepstral Coefficients");
+ strcpy(p_name, "Mel-Frequency Cepstral Coefficients");
strcpy(desc, "Extract MFCC from a spectrum");
strcpy(p_desc, "Extract MFCC from an audio spectrum");
- strcpy(author, "");
+ strcpy(author, "Rabiner");
break;
case BARK_COEFFICIENTS:
strcpy(name, "bark_coefficients");
strcpy(p_name, "Bark Coefficients");
strcpy(desc, "Extract bark coefficients from a spectrum");
- strcpy(p_desc, "Extract bark coefficients from an audio \
- spectrum");
+ strcpy(p_desc,
+ "Extract bark coefficients from an audio spectrum");
strcpy(author, "");
break;
- case CENTROID:
- strcpy(name, "centroid");
+ case SPECTRAL_CENTROID:
+ strcpy(name, "spectral_centroid");
strcpy(p_name, "Spectral Centroid");
strcpy(desc, "Extract the spectral centroid of a spectrum");
- strcpy(p_desc, "Extract the spectral centroid of an audio \
- spectrum");
+ strcpy(p_desc,
+ "Extract the spectral centroid of an audio spectrum");
strcpy(author, "");
break;
case IRREGULARITY_K:
strcpy(name, "irregularity_k");
strcpy(p_name, "Irregularity I");
strcpy(desc, "Extract the irregularity of a spectrum");
- strcpy(p_desc, "Extract the irregularity of an audio \
- spectrum");
- strcpy(author, "");
+ strcpy(p_desc,
+ "Extract the irregularity of an audio spectrum");
+ strcpy(author, "Krimphoff");
+ *year = 1994;
break;
case IRREGULARITY_J:
strcpy(name, "irregularity_j");
strcpy(p_name, "Irregularity II");
strcpy(desc, "Extract the irregularity of a spectrum");
- strcpy(p_desc, "Extract the irregularity of an audio \
- spectrum");
- strcpy(author, "");
+ strcpy(p_desc,
+ "Extract the irregularity of an audio spectrum");
+ strcpy(author, "Jensen");
+ *year = 1999;
break;
case TRISTIMULUS_1:
strcpy(name, "tristimulus_1");
strcpy(p_name, "Tristimulus I");
strcpy(desc, "Extract the tristimulus (type I) of a spectrum");
- strcpy(p_desc, "Extract the tristimulus (type I) of an audio \
- spectrum");
- strcpy(author, "");
+ strcpy(p_desc,
+ "Extract the tristimulus (type I) of an audio spectrum");
+ strcpy(author, "Pollard and Jansson");
+ *year = 1982;
break;
case TRISTIMULUS_2:
strcpy(name, "tristimulus_2");
strcpy(p_name, "Tristimulus II");
strcpy(desc, "Extract the tristimulus (type II) of a spectrum");
- strcpy(p_desc, "Extract the tristimulus (type II) of an audio \
- spectrum");
- strcpy(author, "");
+ strcpy(p_desc,
+ "Extract the tristimulus (type II) of an audio spectrum");
+ strcpy(author, "Pollard and Jansson");
+ *year = 1982;
break;
case TRISTIMULUS_3:
strcpy(name, "tristimulus_3");
strcpy(p_name, "Tristimulus III");
- strcpy(desc, "Extract the tristimulus (type III) of a spectrum");
- strcpy(p_desc, "Extract the tristimulus (type III) of an audio \
- spectrum");
- strcpy(author, "");
+ strcpy(desc,
+ "Extract the tristimulus (type III) of a spectrum");
+ strcpy(p_desc,
+ "Extract the tristimulus (type III) of an audio spectrum");
+ strcpy(author, "Pollard and Jansson");
+ *year = 1982;
break;
case SMOOTHNESS:
strcpy(name, "smoothness");
strcpy(p_name, "Spectral Smoothness");
strcpy(desc, "Extract the spectral smoothness of a spectrum");
- strcpy(p_desc, "Extract the spectral smoothness of an audio \
- spectrum");
- strcpy(author, "");
+ strcpy(p_desc,
+ "Extract the spectral smoothness of an audio spectrum");
+ strcpy(author, "McAdams");
+ *year = 1999;
break;
case FLATNESS:
strcpy(name, "flatness");
strcpy(p_name, "Spectral Flatness");
strcpy(desc, "Extract the spectral flatness of a spectrum");
- strcpy(p_desc, "Extract the spectral flatness of an audio \
- spectrum");
- strcpy(author, "");
+ strcpy(p_desc,
+ "Extract the spectral flatness of an audio spectrum");
+ strcpy(author, "Tristan Jehan");
+ *year = 2005;
break;
case SPREAD:
strcpy(name, "spread");
strcpy(p_name, "Spectral Spread");
strcpy(desc, "Extract the spectral spread of a spectrum");
- strcpy(p_desc, "Extract the spectral spread of an audio \
- spectrum");
- strcpy(author, "");
+ strcpy(p_desc,
+ "Extract the spectral spread of an audio spectrum");
+ strcpy(author, "Norman Casagrande");
+ *year = 2005;
break;
case ZCR:
strcpy(name, "zcr");
strcpy(p_name, "Zero Crossing Rate");
strcpy(desc, "Extract the zero crossing rate of a vector");
- strcpy(p_desc, "Extract the zero crossing rate of an audio \
- signal");
+ strcpy(p_desc,
+ "Extract the zero crossing rate of an audio signal");
strcpy(author, "");
break;
case LOUDNESS:
strcpy(name, "loudness");
strcpy(p_name, "Loudness");
- strcpy(desc, "Extract the loudness of a signal from its \
- spectrum");
- strcpy(p_desc, "Extract the loudness of an audio signal from \
- its spectrum");
- strcpy(author, "");
+ strcpy(desc,
+ "Extract the loudness of a signal from its spectrum");
+ strcpy(p_desc,
+ "Extract the loudness of an audio signal from its spectrum");
+ strcpy(author, "Moore, Glasberg et al");
+ *year = 2005;
break;
case HIGHEST_VALUE:
strcpy(name, "highest_value");
@@ -373,10 +427,10 @@ void *xtract_make_descriptors(){
case SUM:
strcpy(name, "sum");
strcpy(p_name, "Sum of Values");
- strcpy(desc, "Extract the sum of the values in an input \
- vector");
- strcpy(p_desc, "Extract the sum of the values in a given \
- range");
+ strcpy(desc,
+ "Extract the sum of the values in an input vector");
+ strcpy(p_desc,
+ "Extract the sum of the values in a given range");
strcpy(author, "");
break;
case RMS_AMPLITUDE:
@@ -390,41 +444,42 @@ void *xtract_make_descriptors(){
strcpy(name, "power");
strcpy(p_name, "Spectral Power");
strcpy(desc, "Extract the spectral power of a spectrum");
- strcpy(p_desc, "Extract the spectral power of an audio \
- spectrum");
- strcpy(author, "");
+ strcpy(p_desc,
+ "Extract the spectral power of an audio spectrum");
+ strcpy(author, "Bee Suan Ong");
+ *year = 2005;
break;
case SHARPNESS:
strcpy(name, "sharpness");
strcpy(p_name, "Spectral Sharpness");
strcpy(desc, "Extract the spectral sharpness of a spectrum");
- strcpy(p_desc, "Extract the spectral sharpness of an audio \
- spectrum");
+ strcpy(p_desc,
+ "Extract the spectral sharpness of an audio spectrum");
strcpy(author, "");
break;
- case SLOPE:
- strcpy(name, "slope");
+ case SPECTRAL_SLOPE:
+ strcpy(name, "spectral_slope");
strcpy(p_name, "Spectral Slope");
strcpy(desc, "Extract the spectral slope of a spectrum");
- strcpy(p_desc, "Extract the spectral slope of an audio \
- spectrum");
+ strcpy(p_desc,
+ "Extract the spectral slope of an audio spectrum");
strcpy(author, "");
break;
case HPS:
strcpy(name, "hps");
strcpy(p_name, "Harmonic Product Spectrum");
- strcpy(desc, "Extract the harmonic product spectrum of a \
- spectrum");
- strcpy(p_desc, "Extract the harmonic product spectrum of an \
- audio spectrum");
+ strcpy(desc,
+ "Extract the harmonic product spectrum of a spectrum");
+ strcpy(p_desc,
+ "Extract the harmonic product spectrum of an audio spectrum");
strcpy(author, "");
break;
case FLUX:
strcpy(name, "flux");
strcpy(p_name, "Spectral Flux");
strcpy(desc, "Extract the spectral flux of a spectrum");
- strcpy(p_desc, "Extract the spectral flux of an audio \
- spectrum");
+ strcpy(p_desc,
+ "Extract the spectral flux of an audio spectrum");
strcpy(author, "");
break;
case ATTACK_TIME:
@@ -466,7 +521,8 @@ void *xtract_make_descriptors(){
strcpy(name, "autocorrelation");
strcpy(p_name, "Autocorrelation");
strcpy(desc, "Extract the autocorrelation of a signal");
- strcpy(p_desc, "Extract the autocorrelation of an audio signal");
+ strcpy(p_desc,
+ "Extract the autocorrelation of an audio signal");
strcpy(author, "");
break;
case AMDF:
@@ -485,6 +541,7 @@ void *xtract_make_descriptors(){
break;
default:
strcpy(name, "");
+ strcpy(p_name, "");
strcpy(desc, "");
strcpy(p_desc, "");
strcpy(author, "");
diff --git a/src/libxtract.c b/src/libxtract.c
index c8865d5..b39f018 100644
--- a/src/libxtract.c
+++ b/src/libxtract.c
@@ -30,7 +30,13 @@ int(*xtract[])(const float *, const int, const void *, float *) = {
xtract_average_deviation,
xtract_skewness,
xtract_kurtosis,
- xtract_centroid,
+ xtract_spectral_mean,
+ xtract_spectral_variance,
+ xtract_spectral_standard_deviation,
+ xtract_spectral_average_deviation,
+ xtract_spectral_skewness,
+ xtract_spectral_kurtosis,
+ xtract_spectral_centroid,
xtract_irregularity_k,
xtract_irregularity_j,
xtract_tristimulus_1,
@@ -46,11 +52,11 @@ int(*xtract[])(const float *, const int, const void *, float *) = {
xtract_crest,
xtract_noisiness,
xtract_rms_amplitude,
- xtract_inharmonicity,
+ xtract_spectral_inharmonicity,
xtract_power,
xtract_odd_even_ratio,
xtract_sharpness,
- xtract_slope,
+ xtract_spectral_slope,
xtract_lowest_value,
xtract_highest_value,
xtract_sum,
@@ -67,12 +73,12 @@ int(*xtract[])(const float *, const int, const void *, float *) = {
xtract_amdf,
xtract_asdf,
xtract_bark_coefficients,
- xtract_peaks,
+ xtract_peak_spectrum,
xtract_magnitude_spectrum,
xtract_autocorrelation_fft,
xtract_mfcc,
xtract_dct,
- xtract_harmonics
+ xtract_harmonic_spectrum
};
diff --git a/src/scalar.c b/src/scalar.c
index 139cd05..cfb3e7c 100644
--- a/src/scalar.c
+++ b/src/scalar.c
@@ -102,16 +102,15 @@ int xtract_kurtosis(const float *data, const int N, const void *argv, float *re
return SUCCESS;
}
-
-int xtract_centroid(const float *data, const int N, const void *argv, float *result){
+int xtract_spectral_centroid(const float *data, const int N, const void *argv, float *result){
int n = (N >> 1);
const float *freqs, *amps;
float FA = 0.f, A = 0.f;
- freqs = data;
- amps = data + n;
+ amps = data;
+ freqs = data + n;
while(n--){
FA += freqs[n] * amps[n];
@@ -123,6 +122,84 @@ int xtract_centroid(const float *data, const int N, const void *argv, float *re
return SUCCESS;
}
+int xtract_spectral_mean(const float *data, const int N, const void *argv, float *result){
+
+ return xtract_spectral_centroid(data, N, argv, result);
+
+}
+
+int xtract_spectral_variance(const float *data, const int N, const void *argv, float *result){
+
+ int M, m;
+
+ m = M = N >> 1;
+
+ while(m--)
+ *result += pow((data[m] * data[M +m]) - *(float *)argv, 2);
+
+ *result = *result / (M - 1);
+
+ return SUCCESS;
+}
+
+int xtract_spectral_standard_deviation(const float *data, const int N, const void *argv, float *result){
+
+ *result = sqrt(*(float *)argv);
+
+ return SUCCESS;
+}
+
+int xtract_spectral_average_deviation(const float *data, const int N, const void *argv, float *result){
+
+ int M, m;
+
+ m = M = N >> 1;
+
+ while(m--)
+ *result += fabs((data[m] * data[M + m]) - *(float *)argv);
+
+ *result /= M;
+
+ return SUCCESS;
+}
+
+int xtract_spectral_skewness(const float *data, const int N, const void *argv, float *result){
+
+ int M, m;
+ float temp;
+
+ m = M = N >> 1;
+
+ while(m--){
+ temp = ((data[m] * data[M + m]) -
+ ((float *)argv)[0]) / ((float *)argv)[1];
+ *result += pow(temp, 3);
+ }
+
+ *result /= M;
+
+ return SUCCESS;
+}
+
+int xtract_spectral_kurtosis(const float *data, const int N, const void *argv, float *result){
+
+ int M, m;
+ float temp;
+
+ m = M = N >> 1;
+
+ while(m--){
+ temp = ((data[m] * data[M + m]) -
+ ((float *)argv)[0]) / ((float *)argv)[1];
+ *result += pow(temp, 4);
+ }
+
+ *result /= M;
+ *result -= 3.0f;
+
+ return SUCCESS;
+}
+
int xtract_irregularity_k(const float *data, const int N, const void *argv, float *result){
int n,
@@ -391,15 +468,15 @@ int xtract_rms_amplitude(const float *data, const int N, const void *argv, float
return SUCCESS;
}
-int xtract_inharmonicity(const float *data, const int N, const void *argv, float *result){
+int xtract_spectral_inharmonicity(const float *data, const int N, const void *argv, float *result){
int n = N >> 1;
float num = 0.f, den = 0.f, fund;
const float *freqs, *amps;
fund = *(float *)argv;
- freqs = data;
- amps = data + n;
+ amps = data;
+ freqs = data + n;
while(n--){
num += abs(freqs[n] - n * fund) * SQ(amps[n]);
@@ -467,7 +544,7 @@ int xtract_sharpness(const float *data, const int N, const void *argv, float *re
}
-int xtract_slope(const float *data, const int N, const void *argv, float *result){
+int xtract_spectral_slope(const float *data, const int N, const void *argv, float *result){
const float *freqs, *amps;
float f, a,
@@ -477,8 +554,8 @@ int xtract_slope(const float *data, const int N, const void *argv, float *result
F = A = FA = FSQ = 0.f;
n = M = N >> 1;
- freqs = data;
- amps = data + n;
+ amps = data;
+ freqs = data + n;
while(n--){
f = freqs[n];
@@ -680,7 +757,7 @@ int xtract_failsafe_f0(const float *data, const int N, const void *argv, float *
xtract_magnitude_spectrum(data, N, argv, magnitudes);
argf[0] = 10.f;
argf[1] = *(float *)argv;
- xtract_peaks(magnitudes, N, argf, peaks);
+ xtract_peak_spectrum(magnitudes, N, argf, peaks);
argf[0] = 0.f;
xtract_lowest_value(peaks, N >> 1, argf, result);
diff --git a/src/vector.c b/src/vector.c
index 7968e74..c19046e 100644
--- a/src/vector.c
+++ b/src/vector.c
@@ -32,7 +32,7 @@
int xtract_magnitude_spectrum(const float *data, const int N, const void *argv, float *result){
- float *temp, *input, q, sr;
+ float *temp, *input, q;
size_t bytes;
int n , M = N >> 1;
fftwf_plan plan;
@@ -41,25 +41,21 @@ int xtract_magnitude_spectrum(const float *data, const int N, const void *argv,
input = (float *)malloc(bytes = N * sizeof(float));
input = memcpy(input, data, bytes);
- q = sr = 0.f;
+ q = *(float *)argv;
- sr = *(float *)argv;
-
- CHECK_SR;
-
- q = (sr * .5) / M;
+ CHECK_q;
plan = fftwf_plan_r2r_1d(N, input, temp, FFTW_R2HC, FFTW_ESTIMATE);
fftwf_execute(plan);
for(n = 1; n < M; n++){
- result[M + n] = sqrt(SQ(temp[n]) + SQ(temp[N - n])) / N;
- result[n] = n * q;
+ result[n] = sqrt(SQ(temp[n]) + SQ(temp[N - n])) / N;
+ result[M + n] = n * q;
}
- result[M] = fabs(temp[0]) / N;
- result[0] = q * .5;
+ result[0] = fabs(temp[0]) / N;
+ result[M] = q * .5;
fftwf_destroy_plan(plan);
fftwf_free(temp);
@@ -239,19 +235,17 @@ int xtract_bark_coefficients(const float *data, const int N, const void *argv, f
return SUCCESS;
}
-int xtract_peaks(const float *data, const int N, const void *argv, float *result){
+int xtract_peak_spectrum(const float *data, const int N, const void *argv, float *result){
- float thresh, max, y, y2,
- y3, p, width, sr,
- *input = NULL;
+ float thresh, max, y, y2, y3, p, q, *input = NULL;
size_t bytes;
int n = N, M, rv = SUCCESS;
- thresh = max = y = y2 = y3 = p = width = sr = 0.f;
+ thresh = max = y = y2 = y3 = p = q = 0.f;
if(argv != NULL){
thresh = ((float *)argv)[0];
- sr = ((float *)argv)[1];
+ q = ((float *)argv)[1];
}
else
rv = BAD_ARGV;
@@ -261,7 +255,7 @@ int xtract_peaks(const float *data, const int N, const void *argv, float *result
rv = BAD_ARGV;
}
- CHECK_SR;
+ CHECK_q;
input = (float *)malloc(bytes = N * sizeof(float));
@@ -271,7 +265,6 @@ int xtract_peaks(const float *data, const int N, const void *argv, float *result
return MALLOC_FAILED;
M = N >> 1;
- width = sr / N;
while(n--)
max = MAX(max, input[n]);
@@ -284,8 +277,10 @@ int xtract_peaks(const float *data, const int N, const void *argv, float *result
for(n = 1; n < M; n++){
if(input[n] >= thresh){
if(input[n] > input[n - 1] && input[n] > input[n + 1]){
- result[n] = width * (n + (p = .5 * (y = input[n-1] - (y3 = input[n+1])) / (input[n - 1] - 2 * (y2 = input[n]) + input[n + 1])));
- result[M + n] = y2 - .25 * (y - y3) * p;
+ result[M + n] = q * (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;
}
else{
result[n] = 0;
@@ -302,15 +297,15 @@ int xtract_peaks(const float *data, const int N, const void *argv, float *result
return (rv ? rv : SUCCESS);
}
-int xtract_harmonics(const float *data, const int N, const void *argv, float *result){
+int xtract_harmonic_spectrum(const float *data, const int N, const void *argv, float *result){
int n = (N >> 1), M = n;
const float *freqs, *amps;
float f0, thresh, ratio, nearest, distance;
- freqs = data;
- amps = data + n;
+ amps = data;
+ freqs = data + n;
f0 = *((float *)argv);
thresh = *((float *)argv+1);
@@ -324,8 +319,8 @@ int xtract_harmonics(const float *data, const int N, const void *argv, float *re
if(distance > thresh)
result[n] = result[M + n] = 0.f;
else {
- result[n] = freqs[n];
- result[M + n] = amps[n];
+ result[n] = amps[n];
+ result[M + n] = freqs[n];
}
}
else
diff --git a/xtract/libxtract.h b/xtract/libxtract.h
index c1bead7..43ccdac 100644
--- a/xtract/libxtract.h
+++ b/xtract/libxtract.h
@@ -53,7 +53,7 @@ extern "C" {
* @{
*/
-#define XTRACT_FEATURES 47
+#define XTRACT_FEATURES 53
/** \brief Enumeration of features, elements are used as indixes to an array of pointers to feature extracton functions */
enum features_ {
@@ -63,7 +63,13 @@ enum features_ {
AVERAGE_DEVIATION,
SKEWNESS,
KURTOSIS,
- CENTROID,
+ SPECTRAL_MEAN,
+ SPECTRAL_VARIANCE,
+ SPECTRAL_STANDARD_DEVIATION,
+ SPECTRAL_AVERAGE_DEVIATION,
+ SPECTRAL_SKEWNESS,
+ SPECTRAL_KURTOSIS,
+ SPECTRAL_CENTROID,
IRREGULARITY_K,
IRREGULARITY_J,
TRISTIMULUS_1,
@@ -79,11 +85,11 @@ enum features_ {
CREST,
NOISINESS,
RMS_AMPLITUDE,
- INHARMONICITY,
+ SPECTRAL_INHARMONICITY,
POWER,
ODD_EVEN_RATIO,
SHARPNESS,
- SLOPE,
+ SPECTRAL_SLOPE,
LOWEST_VALUE,
HIGHEST_VALUE,
SUM,
@@ -98,12 +104,12 @@ enum features_ {
AMDF,
ASDF,
BARK_COEFFICIENTS,
- PEAKS,
+ PEAK_SPECTRUM,
MAGNITUDE_SPECTRUM,
AUTOCORRELATION_FFT,
MFCC,
DCT,
- HARMONICS
+ HARMONIC_SPECTRUM
};
/** \brief Enumeration of feature types */
diff --git a/xtract/xtract_macros.h b/xtract/xtract_macros.h
index ca8d924..9e72a41 100644
--- a/xtract/xtract_macros.h
+++ b/xtract/xtract_macros.h
@@ -35,7 +35,7 @@ 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_SR if(!sr) sr = 44100.f
+#define CHECK_q if(!q) q = 44100.f / N
#define VERY_SMALL_NUMBER 1e-20
#define LOG_LIMIT VERY_SMALL_NUMBER
diff --git a/xtract/xtract_scalar.h b/xtract/xtract_scalar.h
index 959d06a..fd01ada 100644
--- a/xtract/xtract_scalar.h
+++ b/xtract/xtract_scalar.h
@@ -36,7 +36,7 @@ extern "C" {
/** \brief Extract the mean of an input vector
*
- * \param *data: a pointer to the first element in an array of floats
+ * \param *data: a pointer to the first element
* \param N: the number of array elements to be considered
* \param *argv: a pointer to NULL
* \param *result: the mean of N values from the array pointed to by *data
@@ -88,17 +88,72 @@ int xtract_skewness(const float *data, const int N, const void *argv, float *re
*/
int xtract_kurtosis(const float *data, const int N, const void *argv, float *result);
+/** \brief Extract the mean of an input spectrum
+ *
+ * \param *data: a pointer to the first element in an array of floats representing the spectrum of an audio vector, (e.g. the array pointed to by *result from xtract_magnitude_spectrum(), xtract_spectral_peaks() or xtract_spectral_harmonics()).
+ * \param N: the size of the array pointed to by *data
+ * \param *argv: a pointer to NULL
+ * \param *result: the mean of the spectrum pointed to by *data
+ */
+int xtract_spectral_mean(const float *data, const int N, const void *argv, float *result);
+
+/** \brief Extract the variance of an input spectrum
+ *
+ * \param *data: a pointer to the first element in an array of floats representing the spectrum of an audio vector, (e.g. the array pointed to by *result from xtract_magnitude_spectrum(), xtract_spectral_peaks() or xtract_spectral_harmonics()).
+ * \param N: the number of elements to be considered
+ * \param N: the size of the array pointed to by *data
+ * \param *argv: a pointer to a float representing the mean of the input spectrum
+ * \param *result: the variance of the spectrum pointed to by *data
+ */
+int xtract_spectral_variance(const float *data, const int N, const void *argv, float *result);
+
+/** \brief Extract the deviation of an input spectrum
+ *
+ * \param *data: a pointer to the first element in an array of floats representing the spectrum of an audio vector, (e.g. the array pointed to by *result from xtract_magnitude_spectrum(), xtract_spectral_peaks() or xtract_spectral_harmonics()).
+ * \param N: the size of the array pointed to by *data
+ * \param *argv: a pointer to a float representing the variance of the input spectrum
+ * \param *result: the deviation of the spectrum pointed to by *data
+ */
+int xtract_spectral_standard_deviation(const float *data, const int N, const void *argv, float *result);
+
+/** \brief Extract the average deviation of an input spectrum
+ *
+ * \param *data: a pointer to the first element in an array of floats representing the spectrum of an audio vector, (e.g. the array pointed to by *result from xtract_magnitude_spectrum(), xtract_spectral_peaks() or xtract_spectral_harmonics()).
+ * \param N: the size of the array pointed to by *data
+ * \param *argv: a pointer to a float representing the mean of the input spectrum
+ * \param *result: the average deviation of the spectrum pointed to by *data
+ */
+int xtract_spectral_average_deviation(const float *data, const int N, const void *argv, float *result);
+
+/** \brief Extract the skewness of an input spectrum
+ *
+ * \param *data: a pointer to the first element in an array of floats representing the spectrum of an audio vector, (e.g. the array pointed to by *result from xtract_magnitude_spectrum(), xtract_spectral_peaks() or xtract_spectral_harmonics()).
+ * \param N: the size of the array pointed to by *data
+ * \param *argv: a pointer to an array of floats representing the mean and standard deviation of the input spectrum
+ * \param *result: the skewness of the spectrum pointed to by *data
+ */
+int xtract_spectral_skewness(const float *data, const int N, const void *argv, float *result);
+
+/** \brief Extract the kurtosis of an input spectrum
+ *
+ * \param *data: a pointer to the first element in an array of floats representing the spectrum of an audio vector, (e.g. the array pointed to by *result from xtract_magnitude_spectrum(), xtract_spectral_peaks() or xtract_spectral_harmonics()).
+ * \param N: the size of the array pointed to by *data
+ * \param *argv: a pointer to an array of values representing the mean and standard deviation of the input spectrum
+ * \param *result: the kurtosis of the spectrum pointed to by *data
+ */
+int xtract_spectral_kurtosis(const float *data, const int N, const void *argv, float *result);
+
/** \brief Extract the centroid of an input vector
*
- * \param *data: a pointer to the first element in an array of floats representing the magnitude spectrum of an audio vector, (e.g. the array pointed to by *result from xtract_magnitude_spectrum().
+ * \param *data: a pointer to the first element in an array of floats representing the spectrum of an audio vector, (e.g. the array pointed to by *result from xtract_magnitude_spectrum(), xtract_spectral_peaks() or xtract_spectral_harmonics()).
* \param N: the number of elements to be considered
* \param *argv: a pointer to NULL
* \param *result: the centroid of the values pointed to by *data
*
- * Note: for a more 'accurate' result *result from xtract_peaks() can be passed in. This gives the interpolated peak frequency locations.
+ * Note: for a more 'accurate' result *result from xtract_spectral_peaks() can be passed in. This gives the interpolated peak frequency locations.
*
*/
-int xtract_centroid(const float *data, const int N, const void *argv, float *result);
+int xtract_spectral_centroid(const float *data, const int N, const void *argv, float *result);
/** \brief Calculate the Irregularity of an input vector using a method described by Krimphoff (1994)
*
@@ -226,7 +281,7 @@ int xtract_rms_amplitude(const float *data, const int N, const void *argv, float
* \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(const float *data, const int N, const void *argv, float *result);
+int xtract_spectral_inharmonicity(const float *data, const int N, const void *argv, float *result);
/** \brief Extract the spectral crest of an input vector using a method described by Peeters (2003)
*
@@ -272,7 +327,7 @@ int xtract_sharpness(const float *data, const int N, const void *argv, float *re
* \param *argv: a pointer to NULL
* \param *result: the Slope of N values from the array pointed to by *data
*/
-int xtract_slope(const float *data, const int N, const void *argv, float *result);
+int xtract_spectral_slope(const float *data, const int N, const void *argv, float *result);
/** \brief Extract the value of the lowest value in an input vector
*
diff --git a/xtract/xtract_vector.h b/xtract/xtract_vector.h
index 21947c5..388a0f2 100644
--- a/xtract/xtract_vector.h
+++ b/xtract/xtract_vector.h
@@ -38,9 +38,8 @@ extern "C" {
*
* \param *data: a pointer to the first element in an array of floats representing an audio vector
* \param N: the number of array elements to be considered
- * \param *argv: a pointer to a float representing the sample rate of the audio
- * \param *result: a pointer to an array containing N/2 bin frequencies, and N/2
- * magnitude coefficients.
+ * \param *argv: a pointer to a float representing (samplerate / N)
+ * \param *result: a pointer to an array of size N containing N/2 magnitude coefficients and N/2 bin frequencies.
*/
int xtract_magnitude_spectrum(const float *data, const int N, const void *argv, float *result);
@@ -110,23 +109,23 @@ int xtract_asdf(const float *data, const int N, const void *argv, float *result)
*/
int xtract_bark_coefficients(const float *data, const int N, const void *argv, float *result);
-/** \brief Extract the frequency and amplitude of spectral peaks from a magnitude spectrum
- * \param *data: a pointer to the first element in an array of floats representing the magnitude coefficients from the magnitude spectrum of an audio vector, (e.g. the second half of the array pointed to by *result from xtract_magnitude_spectrum().
- * \param N: the number of array elements to be considered
- * \param *argv: a pointer to an array containing the peak threshold as percentage of the magnitude of the maximum peak found, and the sample rate in Hz.
- * \param *result: a pointer to an array of size N, containing N/2 freqs and N/2 amplitudes
+/** \brief Extract the amplitude and frequency of spectral peaks from a magnitude spectrum
+ * \param *data: a pointer to the first element in an array of floats representing N/2 magnitude coefficients from the magnitude spectrum of an audio vector, (e.g. the first half of the array pointed to by *result from xtract_magnitude_spectrum(), or xtract_magnitudes().
+ * \param N: the size of the output array (note: the input array can be of size N/2)
+ * \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 *result: a pointer to an array of size N containing N/2 magnitude coefficients and N/2 bin frequencies.
*
*/
-int xtract_peaks(const float *data, const int N, const void *argv, float *result);
+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
- * \param *data: a pointer to the first element in an array of floats representing the peak spectrum of an audio vector (e.g. *result from xtract_peaks). It is expected that the first half of the array pointed to by *data will contain frequencies for each peak considered, and the the second half will contain the respective amplitudes
+ * \param *data: a pointer to the first element in an array of floats representing the peak spectrum of an audio vector (e.g. *result from xtract_peaks). It is expected that the first half of the array pointed to by *data will contain amplitudes for each peak considered, and the the second half will contain the respective frequencies
* \param N: the size of the array pointed to by *data
* \param *argv: a pointer to an array containing the fundamental (f0) of the spectrum, and a threshold (t) where 0<=t<=1.0, and t determines the distance from the nearest harmonic number within which a partial can be considered harmonic.
- * \param *result: a pointer to an array of size N containing N/2 freqs and N/2 amplitudes.
+ * \param *result: a pointer to an array of size N containing N/2 magnitude coefficients and N/2 bin frequencies.
*/
-int xtract_harmonics(const float *data, const int N, const void *argv, float *result);
+int xtract_harmonic_spectrum(const float *data, const int N, const void *argv, float *result);
/** @} */