changeset 130:8e240bbea845 refactors

FeatureConditioner tests
author Chris Cannam
date Thu, 11 Dec 2014 13:53:16 +0000
parents dad9fdc32a6a
children 57cda698c225
files src/FeatureConditioner.cpp src/FeatureConditioner.h test/TestFeatureConditioner test/TestFeatureConditioner.cpp test/TestFeatureExtractor test/TestFeatureExtractor.cpp
diffstat 6 files changed, 201 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/FeatureConditioner.cpp	Thu Dec 11 12:54:46 2014 +0000
+++ b/src/FeatureConditioner.cpp	Thu Dec 11 13:53:16 2014 +0000
@@ -16,6 +16,7 @@
 #include "FeatureConditioner.h"
 
 #include <iostream>
+#include <cmath>
 
 using namespace std;
 
@@ -54,7 +55,7 @@
     case OutputDerivative:
         for (int i = 0; i < size; i++) {
             totalEnergy += feature[i];
-            out[i] = feature[i] - m_prev[i];
+            out[i] = fabs(feature[i] - m_prev[i]);
         }
         break;
         
--- a/src/FeatureConditioner.h	Thu Dec 11 12:54:46 2014 +0000
+++ b/src/FeatureConditioner.h	Thu Dec 11 13:53:16 2014 +0000
@@ -52,8 +52,9 @@
 	 *  feature values. */
 	OutputRectifiedDerivative,
 
-	/** Output the difference between the previous and current
-	 *  features instead of the straight feature values. */
+	/** Output the absolute difference between the previous and
+	 *  current features instead of the straight feature
+	 *  values. */
 	OutputDerivative,
     };
 
@@ -74,7 +75,9 @@
 
 	/** Silence threshold. If non-zero, any feature whose total
 	 *  energy (simply the sum of feature values) is below that
-	 *  threshold will be rounded down to all zeros. */
+	 *  threshold will be rounded down to all zeros. Note that
+	 *  this refers to the energy of the feature, not its
+	 *  derivative even if that is what is being returned. */
 	double silenceThreshold;
 
         /** Frame-to-frame decay factor in calculating long-term average */
Binary file test/TestFeatureConditioner has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/TestFeatureConditioner.cpp	Thu Dec 11 13:53:16 2014 +0000
@@ -0,0 +1,176 @@
+
+#include "FeatureConditioner.h"
+
+#include <vector>
+#include <iostream>
+#include <cmath>
+
+using namespace std;
+
+#define BOOST_TEST_DYN_LINK
+#define BOOST_TEST_MAIN
+
+#include <boost/test/unit_test.hpp>
+
+static vector<double> getTestFeature(double m)
+{
+    vector<double> f;
+    double fd[] = { 0, 1, 2, 3 };
+    for (int i = 0; i < 4; ++i) {
+	f.push_back(fd[i] * m);
+    }
+    return f;
+}
+
+BOOST_AUTO_TEST_SUITE(TestFeatureConditioner)
+
+BOOST_AUTO_TEST_CASE(nonorm_features)
+{
+    FeatureConditioner::Parameters params;
+    params.norm = FeatureConditioner::NoNormalisation;
+    params.order = FeatureConditioner::OutputFeatures;
+    vector<double>
+	e1 = getTestFeature(1),
+	e2 = getTestFeature(2),
+	e0 = getTestFeature(0);
+
+    params.silenceThreshold = 1.0;
+    FeatureConditioner fc(params);
+    vector<double> out = fc.process(e1);
+    BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), e1.begin(), e1.end());
+    out = fc.process(e2);
+    BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), e2.begin(), e2.end());
+
+    params.silenceThreshold = 7.0;
+    fc = FeatureConditioner(params);
+    out = fc.process(e1);
+    BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), e0.begin(), e0.end());
+    out = fc.process(e2);
+    BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), e2.begin(), e2.end());
+}
+    
+BOOST_AUTO_TEST_CASE(nonorm_rectderiv)
+{
+    FeatureConditioner::Parameters params;
+    params.norm = FeatureConditioner::NoNormalisation;
+    params.order = FeatureConditioner::OutputRectifiedDerivative;
+    vector<double>
+	e1 = getTestFeature(1),
+	e2 = getTestFeature(2),
+	e0 = getTestFeature(0);
+
+    params.silenceThreshold = 1.0;
+    FeatureConditioner fc(params);
+    vector<double> out = fc.process(e1);
+    BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), e1.begin(), e1.end());
+    out = fc.process(e2);
+    BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), e1.begin(), e1.end());
+    out = fc.process(e1);
+    BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), e0.begin(), e0.end());
+
+    params.silenceThreshold = 7.0;
+    fc = FeatureConditioner(params);
+    out = fc.process(e1);
+    BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), e0.begin(), e0.end());
+    out = fc.process(e2);
+    BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), e1.begin(), e1.end());
+    out = fc.process(e1);
+    BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), e0.begin(), e0.end());
+    out = fc.process(e2);
+    BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), e1.begin(), e1.end());
+}
+    
+BOOST_AUTO_TEST_CASE(nonorm_deriv)
+{
+    FeatureConditioner::Parameters params;
+    params.norm = FeatureConditioner::NoNormalisation;
+    params.order = FeatureConditioner::OutputDerivative;
+    vector<double>
+	e1 = getTestFeature(1),
+	e2 = getTestFeature(2),
+	e3 = getTestFeature(3),
+	e0 = getTestFeature(0);
+
+    params.silenceThreshold = 1.0;
+    FeatureConditioner fc(params);
+    vector<double> out = fc.process(e1);
+    BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), e1.begin(), e1.end());
+    out = fc.process(e2);
+    BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), e1.begin(), e1.end());
+    out = fc.process(e1);
+    BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), e1.begin(), e1.end());
+
+    params.silenceThreshold = 7.0;
+    fc = FeatureConditioner(params);
+    out = fc.process(e1);
+    BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), e0.begin(), e0.end());
+    out = fc.process(e3);
+    BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), e2.begin(), e2.end());
+    out = fc.process(e2);
+    BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), e1.begin(), e1.end());
+    out = fc.process(e1);
+    BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), e0.begin(), e0.end());
+}
+    
+BOOST_AUTO_TEST_CASE(sum1_features)
+{
+    FeatureConditioner::Parameters params;
+    params.norm = FeatureConditioner::NormaliseToSum1;
+    params.order = FeatureConditioner::OutputFeatures;
+    vector<double>
+	e1 = getTestFeature(1),
+	e2 = getTestFeature(2),
+	en = getTestFeature(1.0/6.0),
+	e0 = getTestFeature(0);
+
+    params.silenceThreshold = 1.0;
+    FeatureConditioner fc(params);
+    vector<double> out = fc.process(e1);
+    BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), en.begin(), en.end());
+    out = fc.process(e2);
+    BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), en.begin(), en.end());
+
+    params.silenceThreshold = 7.0;
+    fc = FeatureConditioner(params);
+    out = fc.process(e1);
+    BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), e0.begin(), e0.end());
+    out = fc.process(e2);
+    BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), en.begin(), en.end());
+}
+    
+BOOST_AUTO_TEST_CASE(sum1_rectderiv)
+{
+    FeatureConditioner::Parameters params;
+    params.norm = FeatureConditioner::NormaliseToSum1;
+    params.order = FeatureConditioner::OutputRectifiedDerivative;
+    vector<double>
+	e1 = getTestFeature(1),
+	e2 = getTestFeature(2),
+	en = getTestFeature(1.0/6.0),
+	en2 = getTestFeature(1.0/12.0),
+	e0 = getTestFeature(0);
+
+    params.silenceThreshold = 1.0;
+    FeatureConditioner fc(params);
+    vector<double> out = fc.process(e1);
+    BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), en.begin(), en.end());
+    out = fc.process(e2);
+    BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), en2.begin(), en2.end());
+    out = fc.process(e1);
+    BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), e0.begin(), e0.end());
+
+    params.silenceThreshold = 7.0;
+    fc = FeatureConditioner(params);
+    out = fc.process(e1);
+    BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), e0.begin(), e0.end());
+    out = fc.process(e2);
+    BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), en2.begin(), en2.end());
+    out = fc.process(e1);
+    BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), e0.begin(), e0.end());
+    out = fc.process(e2);
+    BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), en2.begin(), en2.end());
+}
+    
+
+BOOST_AUTO_TEST_SUITE_END()
+
Binary file test/TestFeatureExtractor has changed
--- a/test/TestFeatureExtractor.cpp	Thu Dec 11 12:54:46 2014 +0000
+++ b/test/TestFeatureExtractor.cpp	Thu Dec 11 13:53:16 2014 +0000
@@ -35,6 +35,19 @@
 
 BOOST_AUTO_TEST_SUITE(TestFeatureExtractor)
 
+void checkAlternateProcessType(FeatureExtractor &fe, vector<double> expected,
+			       vector<double> real, vector<double> imag)
+{
+    vector<float> in;
+    for (int i = 0; i < (int)real.size(); ++i) {
+	in.push_back(float(real[i]));
+	in.push_back(float(imag[i]));
+    }
+    vector<double> alt = fe.process(&in[0]);
+    BOOST_CHECK_EQUAL_COLLECTIONS(alt.begin(), alt.end(),
+				  expected.begin(), expected.end());
+}
+
 BOOST_AUTO_TEST_CASE(chroma)
 {
     int szs[] = { 1024, 2048, 4000 };
@@ -72,6 +85,8 @@
 	
 		vector<double> out = fe.process(real, imag);
 
+		checkAlternateProcessType(fe, out, real, imag);
+
 		// We expect to find all bins are 0 except for:
 		// 
 		// * two bins of 200 and 50 respectively, if the two input
@@ -146,6 +161,8 @@
 
 	vector<double> out = fe.process(real, imag);
 
+	checkAlternateProcessType(fe, out, real, imag);
+
 	// We expect to find all bins are 0 except for:
 	// 
 	// * two bins of 200 and 50 respectively, if the two input