changeset 42:84e69b155098

Numerous fixes, see ChangeLog
author Jamie Bullock <jamie@postlude.co.uk>
date Tue, 12 Dec 2006 21:47:42 +0000
parents afb9e6fee244
children 4a36f70a76e9
files ChangeLog TODO examples/puredata/xtract~.c src/scalar.c src/vector.c xtract/xtract_scalar.h xtract/xtract_vector.h
diffstat 7 files changed, 107 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Mon Dec 11 17:57:27 2006 +0000
+++ b/ChangeLog	Tue Dec 12 21:47:42 2006 +0000
@@ -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
--- a/TODO	Mon Dec 11 17:57:27 2006 +0000
+++ b/TODO	Tue Dec 12 21:47:42 2006 +0000
@@ -4,5 +4,7 @@
 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!
--- a/examples/puredata/xtract~.c	Mon Dec 11 17:57:27 2006 +0000
+++ b/examples/puredata/xtract~.c	Tue Dec 12 21:47:42 2006 +0000
@@ -19,6 +19,7 @@
 /* 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 @@
 
     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 @@
 	case  INHARMONICITY:
 	case  LOWEST_MATCH:
 	case  F0:
+	case  TONALITY:
 	    floatargs = 1;
 	    break;
 	case  SKEWNESS:
@@ -185,7 +190,6 @@
 	case  ZCR:
 	case  LOUDNESS:
 	case  FLATNESS:
-	case  TONALITY:
 	case  CREST:
 	case  NOISINESS:
 	case  RMS_AMPLITUDE:
@@ -218,7 +222,7 @@
 	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){
--- a/src/scalar.c	Mon Dec 11 17:57:27 2006 +0000
+++ b/src/scalar.c	Tue Dec 12 21:47:42 2006 +0000
@@ -30,7 +30,7 @@
     int n = N;
 
     while(n--)
-	*result += *data++;
+	*result += data[n];
 
     *result /= N;
 
@@ -42,7 +42,7 @@
     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_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 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 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 @@
 	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 @@
     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 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 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_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_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;
 }
--- a/src/vector.c	Mon Dec 11 17:57:27 2006 +0000
+++ b/src/vector.c	Tue Dec 12 21:47:42 2006 +0000
@@ -292,8 +292,10 @@
 	    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;
--- a/xtract/xtract_scalar.h	Mon Dec 11 17:57:27 2006 +0000
+++ b/xtract/xtract_scalar.h	Tue Dec 12 21:47:42 2006 +0000
@@ -117,7 +117,7 @@
 
 /** \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 @@
  * 
  * \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 @@
 
 /** \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);
--- a/xtract/xtract_vector.h	Mon Dec 11 17:57:27 2006 +0000
+++ b/xtract/xtract_vector.h	Tue Dec 12 21:47:42 2006 +0000
@@ -101,7 +101,7 @@
 /** \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