changeset 244:8c768f32a6a8

Add new helper function xtract_smoothed(), e.g. can be used to extract smoothed spectrum
author Jamie Bullock <jamie@jamiebullock.com>
date Fri, 06 Jun 2014 09:55:01 +0100
parents d13189c1005c
children 8fc9a0462c6e bde5fa8692ff
files examples/simpletest/simpletest.cpp src/helper.c src/libxtract.c xtract/libxtract.h xtract/xtract_helper.h
diffstat 5 files changed, 54 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/examples/simpletest/simpletest.cpp	Thu Jun 05 20:31:33 2014 +0100
+++ b/examples/simpletest/simpletest.cpp	Fri Jun 06 09:55:01 2014 +0100
@@ -31,6 +31,7 @@
 #include "xtract/libxtract.h"
 #include "xtract/xtract_stateful.h"
 #include "xtract/xtract_scalar.h"
+#include "xtract/xtract_helper.h"
 #include "WaveFile.h"
 
 #ifndef M_PI
@@ -50,7 +51,7 @@
 
 #define BLOCKSIZE 512
 #define MAVG_COUNT 10
-#define HALF_BLOCKSIZE BLOCKSIZE >> 1
+#define HALF_BLOCKSIZE (BLOCKSIZE >> 1)
 #define SAMPLERATE 44100
 #define PERIOD 102
 #define MFCC_FREQ_BANDS 13
@@ -202,7 +203,6 @@
         xtract_free_fft();
 
         xtract[XTRACT_SPECTRAL_CENTROID](spectrum, BLOCKSIZE, NULL, &centroid);
-//        printf("\nSpectral Centroid: %f\t", centroid);
 
         argd[1] = 10.0; /* peak threshold as %  of maximum peak */
         xtract[XTRACT_PEAK_SPECTRUM](spectrum, BLOCKSIZE / 2, argd, peaks);
@@ -250,6 +250,13 @@
         xtract_features_from_subframes(subframes_windowed, BLOCKSIZE, XTRACT_SPECTRUM, argd, subframes_spectrum);
         xtract_free_fft();
         
+        argd[0] = 0.5; /* smoothing factor */
+        
+        /* smooth the amplitude components of the first and second spectra */
+        xtract_smoothed(subframes_spectrum, HALF_BLOCKSIZE >> 1, argd, subframes_spectrum);
+        xtract_smoothed(subframes_spectrum + HALF_BLOCKSIZE, HALF_BLOCKSIZE >> 1, argd, subframes_spectrum + HALF_BLOCKSIZE);
+        
+        /* difference between the two spectra */
         xtract_difference_vector(subframes_spectrum, BLOCKSIZE, NULL, difference);
         
         argd[0] = .25; /* norm order */
--- a/src/helper.c	Thu Jun 05 20:31:33 2014 +0100
+++ b/src/helper.c	Fri Jun 06 09:55:01 2014 +0100
@@ -75,6 +75,32 @@
 
 }
 
+
+/*
+ * Implements y[n] = k * x[n] + (1-k) * y[n-1]
+ */
+int xtract_smoothed(const double *data, const int N, const void *argv, double *result)
+{
+    double gain = *(double *)argv;
+    double oneminusgain = 1.0 - gain;
+    int i;
+    
+    // reverse filtering first
+    for (i = N - 2; i >= 0; i--)
+    {
+        result[i] = gain * data[i] + oneminusgain * data[i+1];
+    }
+    
+    // then forward filtering
+    for (i = 1; i < N; i++)
+    {
+        result[i] = gain * result[i] + oneminusgain * result[i-1];
+    }
+
+    return XTRACT_SUCCESS;
+}
+
+
 //inline int xtract_is_denormal(double const d)
 int xtract_is_denormal(double const d)
 {
--- a/src/libxtract.c	Thu Jun 05 20:31:33 2014 +0100
+++ b/src/libxtract.c	Fri Jun 06 09:55:01 2014 +0100
@@ -90,6 +90,7 @@
     xtract_lpcc,
     xtract_subbands,
     /* xtract_helper.h */
-    xtract_windowed
+    xtract_windowed,
+    xtract_smoothed
 };
 
--- a/xtract/libxtract.h	Thu Jun 05 20:31:33 2014 +0100
+++ b/xtract/libxtract.h	Fri Jun 06 09:55:01 2014 +0100
@@ -71,7 +71,7 @@
   * @{
   */
 
-#define XTRACT_FEATURES 61
+#define XTRACT_FEATURES 62
     
 /** \brief Enumeration of features, elements are used as indixes to an array of pointers to feature extracton functions */
 enum xtract_features_ {
@@ -137,7 +137,8 @@
     XTRACT_LPCC,
     XTRACT_SUBBANDS,
     /* Helper functions */
-    XTRACT_WINDOWED
+    XTRACT_WINDOWED,
+    XTRACT_SMOOTHED
 };
 
 /** \brief Enumeration of feature initialisation functions */
--- a/xtract/xtract_helper.h	Thu Jun 05 20:31:33 2014 +0100
+++ b/xtract/xtract_helper.h	Fri Jun 06 09:55:01 2014 +0100
@@ -83,6 +83,20 @@
 /** \brief Test whether a number is a power of two */
 bool xtract_is_poweroftwo(unsigned int x);
 
+    
+/** \brief Smooth a vector
+ *
+ * \param *data a pointer to an array of doubles
+ * \param N the number of elements in the array pointed to by *data to be smoothed
+ * \param *argv a pointer to a double giving the smoothing gain
+ * \param *result a pointer to the first element an array containing the smoothed data
+ *
+ * \note if passing in a spectrum e.g. *result from xtract_spectrum(), then N for xtract_smoothed() should be N / 2 with respect to the N for xtract_spectrum() so only amplitude components are smoothed, not frequencies!
+ *
+ */
+    int xtract_smoothed(const double *data, const int N, const void *argv, double *result);
+    
+    
 /** @} */
 
 #ifdef __cplusplus