aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--TODO2
-rw-r--r--examples/puredata/xtract~.c8
-rw-r--r--src/scalar.c120
-rw-r--r--src/vector.c6
-rw-r--r--xtract/xtract_scalar.h12
-rw-r--r--xtract/xtract_vector.h2
7 files changed, 107 insertions, 50 deletions
diff --git a/ChangeLog b/ChangeLog
index 62c2815..487a667 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2006-12-12 Jamie Bullock <jamie@postlude.co.uk>
+ * version 0.3.3
+ * Fixed errors in skewnes, kurtosis, irregularity_k, irregularity_j,
+ tristimulus_1, tristimulus_2, and tristimulus_3.
+ * Tested the above
+ * Changed rolloff so output is in Hz. This means that a second
+ argument (samplerate) needs to be passed in as argv[1]
2006-12-11 Jamie Bullock <jamie@postlude.co.uk>
* version 0.3.2
* changed xtract_inharmonicity so that it takes frequencies AND
diff --git a/TODO b/TODO
index c184b84..2cb124b 100644
--- a/TODO
+++ b/TODO
@@ -4,5 +4,7 @@ Fix xtract_hps - it doesn't work!
Add Pure Data help file
Add delta functions
Add Max/MSP external example
+Add self documentation
+Check sfm and tonality
...do other stuff and eventually...
...optimise!
diff --git a/examples/puredata/xtract~.c b/examples/puredata/xtract~.c
index 575a170..77945f8 100644
--- a/examples/puredata/xtract~.c
+++ b/examples/puredata/xtract~.c
@@ -19,6 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
/* calculates the spectral xtract of one frame, given peak frequency and amplitude to first and second inputs respectively */
#include "m_pd.h"
+#include <math.h>
#define XTRACT
#include "xtract/libxtract.h"
@@ -53,6 +54,9 @@ static t_int *xtract_perform(t_int *w) {
if(return_code == FEATURE_NOT_IMPLEMENTED)
pd_error(x, "Feature not implemented");
+
+ /* set nan, inf or -inf to 0 */
+ result = (isinf(result) || isnan(result) ? 0 : result);
outlet_float(x->x_obj.ob_outlet, result);
return (w+4);
@@ -166,6 +170,7 @@ static void *xtract_new(t_symbol *me, t_int argc, t_atom *argv) {
case INHARMONICITY:
case LOWEST_MATCH:
case F0:
+ case TONALITY:
floatargs = 1;
break;
case SKEWNESS:
@@ -185,7 +190,6 @@ static void *xtract_new(t_symbol *me, t_int argc, t_atom *argv) {
case ZCR:
case LOUDNESS:
case FLATNESS:
- case TONALITY:
case CREST:
case NOISINESS:
case RMS_AMPLITUDE:
@@ -218,7 +222,7 @@ static void *xtract_new(t_symbol *me, t_int argc, t_atom *argv) {
x->argv = (xtract_mel_filter *)getbytes(x->memory.argv);
}
else if(x->feature == BARK_COEFFICIENTS){
- x->memory.argv = (size_t)(sizeof(BARK_BANDS * sizeof(t_int)));
+ x->memory.argv = (size_t)(BARK_BANDS * sizeof(t_int));
x->argv = (t_int *)getbytes(x->memory.argv);
}
else if (floatargs){
diff --git a/src/scalar.c b/src/scalar.c
index 8d0f821..476b843 100644
--- a/src/scalar.c
+++ b/src/scalar.c
@@ -30,7 +30,7 @@ int xtract_mean(float *data, int N, void *argv, float *result){
int n = N;
while(n--)
- *result += *data++;
+ *result += data[n];
*result /= N;
@@ -42,7 +42,7 @@ int xtract_variance(float *data, int N, void *argv, float *result){
int n = N;
while(n--)
- *result += *data++ - *(float *)argv;
+ *result += data[n] - *(float *)argv;
*result = SQ(*result) / (N - 1);
@@ -59,9 +59,9 @@ int xtract_standard_deviation(float *data, int N, void *argv, float *result){
int xtract_average_deviation(float *data, int N, void *argv, float *result){
int n = N;
-
+
while(n--)
- *result += fabs(*data++ - *(float *)argv);
+ *result += fabs(data[n] - *(float *)argv);
*result /= N;
@@ -72,11 +72,15 @@ int xtract_skewness(float *data, int N, void *argv, float *result){
int n = N;
- while(n--)
- *result += (*data++ - ((float *)argv)[0]) / ((float *)argv)[1];
+ float temp;
- *result = pow(*result, 3) / N;
+ while(n--){
+ temp = (data[n] - ((float *)argv)[0]) / ((float *)argv)[1];
+ *result += pow(temp, 3);
+ }
+ *result /= N;
+
return SUCCESS;
}
@@ -84,11 +88,16 @@ int xtract_kurtosis(float *data, int N, void *argv, float *result){
int n = N;
- while(n--)
- *result += (*data++ - ((float *)argv)[0]) / ((float *)argv)[1];
+ float temp;
- *result = pow(*result, 4) / N - 3;
+ while(n--){
+ temp = (data[n] - ((float *)argv)[0]) / ((float *)argv)[1];
+ *result += pow(temp, 4);
+ }
+ *result /= N;
+ *result -= 3.0f;
+
return SUCCESS;
}
@@ -118,7 +127,7 @@ int xtract_irregularity_k(float *data, int N, void *argv, float *result){
M = N - 1;
for(n = 1; n < M; n++)
- *result += abs(data[n] - (data[n-1] + data[n] + data[n+1]) / 3);
+ *result += fabs(data[n] - (data[n-1] + data[n] + data[n+1]) / 3);
return SUCCESS;
}
@@ -130,8 +139,8 @@ int xtract_irregularity_j(float *data, int N, void *argv, float *result){
float num = 0.f, den = 0.f;
while(n--){
- num += data[n] - data[n+1];
- den += data[n] * data[n];
+ num += pow(data[n] - data[n+1], 2);
+ den += pow(data[n], 2);
}
*result = num / den;
@@ -143,12 +152,19 @@ int xtract_tristimulus_1(float *data, int N, void *argv, float *result){
int n = N;
- float den = 0.f;
+ float den, p1, temp;
- while(n--)
- den += data[n];
+ den = p1 = temp = 0.f;
- *result = data[0] / den;
+ for(n = 0; n < N; n++){
+ if((temp = data[n])){
+ den += temp;
+ if(!p1)
+ p1 = temp;
+ }
+ }
+
+ *result = p1 / den;
return SUCCESS;
}
@@ -157,26 +173,43 @@ int xtract_tristimulus_2(float *data, int N, void *argv, float *result){
int n = N;
- float den = 0.f;
+ float den, p2, p3, p4, temp;
- while(n--)
- den += data[n];
+ den = p2 = p3 = p4 = temp = 0.f;
- *result = (data[1] + data[2] + data[3]) / den;
+ for(n = 0; n < N; n++){
+ if((temp = data[n])){
+ den += temp;
+ if(!p2)
+ p2 = temp;
+ else if(!p3)
+ p3 = temp;
+ else if(!p4)
+ p4 = temp;
+ }
+ }
+
+ *result = (p2 + p3 + p4) / den;
return SUCCESS;
}
int xtract_tristimulus_3(float *data, int N, void *argv, float *result){
- int n = N;
+ int n = N, count = 0;
- float den = 0.f, num = 0.f;
+ float den, num, temp;
- while(n--)
- den += data[n];
+ den = num = temp = 0.f;
- num = den - data[0] + data[1] + data[2] + data[3];
+ for(n = 0; n < N; n++){
+ if((temp = data[n])){
+ den += temp;
+ if(count >= 5)
+ num += temp;
+ count++;
+ }
+ }
*result = num / den;
@@ -231,15 +264,18 @@ int xtract_zcr(float *data, int N, void *argv, float *result){
int xtract_rolloff(float *data, int N, void *argv, float *result){
int n = N;
- float pivot = 0.f, temp = 0.f;
+ float pivot, temp;
+
+ pivot = temp = 0.f;
while(n--) pivot += data[n];
- pivot *= *(float *)argv;
+ pivot *= ((float *)argv)[0];
- for(n = 0; temp < pivot; temp += data[n++]);
+ for(n = 0; temp < pivot; n++)
+ temp += data[n];
- *result = n;
+ *result = (n / (float)N) * (((float *)argv)[1] * .5);
return SUCCESS;
}
@@ -259,21 +295,27 @@ int xtract_loudness(float *data, int N, void *argv, float *result){
int xtract_flatness(float *data, int N, void *argv, float *result){
- int n = N;
+ int n;
- float num = 0.f, den = 0.f;
+ float num, den, temp;
- while(n--){
- if(data[n] !=0){
- num *= data[n];
- den += data[n];
+ den = temp = num = 0.f;
+
+ for(n = 0; n < N; n++){
+ if((temp = data[n])){
+ if(!num)
+ num = den = temp;
+ else{
+ num *= temp;
+ den += temp;
+ }
}
}
-
- num = pow(num, 1 / N);
+
+ num = powf(num, 1.0f / N);
den /= N;
- *result = 10 * log10(num / den);
+ *result = num / den;
return SUCCESS;
}
diff --git a/src/vector.c b/src/vector.c
index 72e97f8..275b2b7 100644
--- a/src/vector.c
+++ b/src/vector.c
@@ -292,8 +292,10 @@ int xtract_harmonics(float *data, int N, void *argv, float *result){
distance = fabs(nearest - ratio);
if(distance > thresh)
result[n] = result[M + n] = 0.f;
- else
- result[n] = result[M + n] = freqs[n];
+ else {
+ result[n] = freqs[n];
+ result[M + n] = amps[n];
+ }
}
else
result[n] = result[M + n] = 0.f;
diff --git a/xtract/xtract_scalar.h b/xtract/xtract_scalar.h
index 9d95c09..8beceec 100644
--- a/xtract/xtract_scalar.h
+++ b/xtract/xtract_scalar.h
@@ -117,7 +117,7 @@ int xtract_irregularity_j(float *data, int N, void *argv, float *result);
/** \brief Calculate the Tristimulus of an input vector using a method described by Pollard and Jansson (1982)
*
- * \param *data: a pointer to the first element in an array of floats representing the amplitudes of the harmonic spectrum of an audio vector e.g. a pointer to the second half of the array pointed to by *result from xtract_harmonics()
+ * \param *data: a pointer to the first element in an array of floats representing the amplitudes of the harmonic spectrum of an audio vector e.g. a pointer to the second half of the array pointed to by *result from xtract_harmonics(). The amplitudes of the peak spectrum (e.g. *result from xtract_peaks()) can be used if one wishes to consider all partials not just harmonics.
* \param N: the number of elements to be considered
* \param *argv: a pointer to NULL
* \param *result: the tristimulus of N values from the array pointed to by *data
@@ -162,8 +162,8 @@ int xtract_zcr(float *data, int N, void *argv, float *result);
*
* \param *data: a pointer to the first element in an array of floats representing the magnitude spectrum of an audio vector
* \param N: the number of elements to be considered
- * \param *argv: a pointer to a floating point value representing the threshold for rolloff, i.e. the percentile at which the rolloff is determined
- * \param *result: the spectral rolloff of N values from the array pointed to by *data
+ * \param *argv: a pointer to an array containing a floating point value representing the threshold for rolloff, i.e. the percentile at which the rolloff is determined, expressed in the range 0-1.0, and a float representing the sample rate in Hz
+ * \param *result: the spectral rolloff in Hz of N values from the array pointed to by *data. This is the point in the spectrum below which argv[0] of the energy is distributed.
*/
int xtract_rolloff(float *data, int N, void *argv, float *result);
@@ -191,9 +191,9 @@ int xtract_flatness(float *data, int N, void *argv, float *result);
/** \brief Extract the tonality factor of an input vector using a method described by Tristan Jehan (2005)
*
- * \param *data: a pointer to the first element in an array of floats representing the spectral peaks of an audio vector
- * \param N: the number of elements to be considered
- * \param *argv: a pointer to NULL
+ * \param *data: not used.
+ * \param N: not used
+ * \param *argv: a pointer to the spectral flatness measure of an audio vector (e.g. the output from xtract_flatness)
* \param *result: the tonality factor of N values from the array pointed to by *data
*/
int xtract_tonality(float *data, int N, void *argv, float *result);
diff --git a/xtract/xtract_vector.h b/xtract/xtract_vector.h
index 21cc8a3..a8b0550 100644
--- a/xtract/xtract_vector.h
+++ b/xtract/xtract_vector.h
@@ -101,7 +101,7 @@ int xtract_asdf(float *data, int N, void *argv, float *result);
/** \brief Extract Bark band coefficients based on a method
* \param *data: a pointer to the first element in an array of floats representing the magnitude spectrum of an audio vector
* \param N: the number of array elements to be considered
- * \param *argv: a pointer to an array of ints representing the limits of each bark band
+ * \param *argv: a pointer to an array of ints representing the limits of each bark band. This can be obtained by calling xtract_init_bark.
* \param *result: a pointer to an array containing resultant bark coefficients
*
* The limits array pointed to by *argv must be obtained by first calling xtract_init_bark