changeset 45:8db4a1f096f0

Comments
author Chris Cannam
date Tue, 14 Aug 2012 16:48:19 +0100
parents c5cd88de5809
children c666067fb8da
files NoteHypothesis.h test/TestNoteHypothesis.cpp
diffstat 2 files changed, 85 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/NoteHypothesis.h	Fri Jul 20 22:12:29 2012 +0100
+++ b/NoteHypothesis.h	Tue Aug 14 16:48:19 2012 +0100
@@ -40,20 +40,20 @@
 public:
     enum State {
 
-	/// Just constructed, will provisionally accept any estimate
-	New,
+        /// Just constructed, will provisionally accept any estimate
+        New,
 
-	/// Accepted at least one estimate, but not enough evidence to satisfy
-	Provisional,
+        /// Accepted at least one estimate, but not enough evidence to satisfy
+        Provisional,
 
-	/// Could not find enough consistency in offered estimates
-	Rejected,
+        /// Could not find enough consistency in offered estimates
+        Rejected,
 
-	/// Have accepted enough consistent estimates to satisfy hypothesis
-	Satisfied,
+        /// Have accepted enough consistent estimates to satisfy hypothesis
+        Satisfied,
 
-	/// Have been satisfied, but evidence has now changed: we're done
-	Expired
+        /// Have been satisfied, but evidence has now changed: we're done
+        Expired
     };
     
     /**
@@ -74,9 +74,9 @@
         bool operator==(const Estimate &e) const {
             return e.freq == freq && e.time == time && e.confidence == confidence;
         }
-	double freq;
+        double freq;
         Vamp::RealTime time;
-	double confidence;
+        double confidence;
     };
     typedef std::vector<Estimate> Estimates;
 
@@ -107,9 +107,9 @@
         bool operator==(const Note &e) const {
             return e.freq == freq && e.time == time && e.duration == duration;
         }
-	double freq;
-	Vamp::RealTime time;
-	Vamp::RealTime duration;
+        double freq;
+        Vamp::RealTime time;
+        Vamp::RealTime duration;
     };
     
     /**
--- a/test/TestNoteHypothesis.cpp	Fri Jul 20 22:12:29 2012 +0100
+++ b/test/TestNoteHypothesis.cpp	Tue Aug 14 16:48:19 2012 +0100
@@ -53,15 +53,57 @@
 
 BOOST_AUTO_TEST_CASE(emptyAccept)
 {
+    // An empty hypothesis should accept any estimate and enter
+    // provisional state
     NoteHypothesis h;
     NoteHypothesis::Estimate e;
     BOOST_CHECK_EQUAL(h.getState(), NoteHypothesis::New);
     BOOST_CHECK(h.accept(e));
     BOOST_CHECK_EQUAL(h.getState(), NoteHypothesis::Provisional);
 }
+		
+BOOST_AUTO_TEST_CASE(tooSlow)
+{
+    // Having accepted a first estimate, a hypothesis should reject a
+    // second (and enter rejected state) if there is too long a gap
+    // between them for them to belong to a single note
+    NoteHypothesis h;
+    NoteHypothesis::Estimate e1(500, RealTime::fromMilliseconds(0), 1);
+    NoteHypothesis::Estimate e2(500, RealTime::fromMilliseconds(50), 1);
+    BOOST_CHECK_EQUAL(h.getState(), NoteHypothesis::New);
+    BOOST_CHECK(h.accept(e1));
+    BOOST_CHECK_EQUAL(h.getState(), NoteHypothesis::Provisional);
+    BOOST_CHECK(!h.accept(e2));
+    BOOST_CHECK_EQUAL(h.getState(), NoteHypothesis::Rejected);
+}
 
 BOOST_AUTO_TEST_CASE(simpleSatisfy)
 {
+    // A hypothesis should enter satisfied state after accepting three
+    // consistent estimates, and then remain satisfied while accepting
+    // further consistent estimates
+    NoteHypothesis h;
+    NoteHypothesis::Estimate e1(500, RealTime::fromMilliseconds(0), 1);
+    NoteHypothesis::Estimate e2(500, RealTime::fromMilliseconds(10), 1);
+    NoteHypothesis::Estimate e3(500, RealTime::fromMilliseconds(20), 1);
+    NoteHypothesis::Estimate e4(500, RealTime::fromMilliseconds(30), 1);
+    BOOST_CHECK_EQUAL(h.getState(), NoteHypothesis::New);
+    BOOST_CHECK(h.accept(e1));
+    BOOST_CHECK_EQUAL(h.getState(), NoteHypothesis::Provisional);
+    BOOST_CHECK(h.accept(e2));
+    BOOST_CHECK_EQUAL(h.getState(), NoteHypothesis::Provisional);
+    BOOST_CHECK(h.accept(e3));
+    BOOST_CHECK_EQUAL(h.getState(), NoteHypothesis::Satisfied);
+    BOOST_CHECK(h.accept(e4));
+    BOOST_CHECK_EQUAL(h.getState(), NoteHypothesis::Satisfied);
+}
+
+BOOST_AUTO_TEST_CASE(expiry)
+{
+    // A hypothesis that has been satisfied, but that is subsequently
+    // offered an estimate that follows too long a gap, should enter
+    // expired state rather than rejected state (showing that it has a
+    // valid note but that the note has apparently finished)
     NoteHypothesis h;
     NoteHypothesis::Estimate e1(500, RealTime::fromMilliseconds(0), 1);
     NoteHypothesis::Estimate e2(500, RealTime::fromMilliseconds(10), 1);
@@ -84,8 +126,10 @@
     BOOST_CHECK_EQUAL(h.getState(), NoteHypothesis::Expired);
 }
 	
-BOOST_AUTO_TEST_CASE(strayReject)
+BOOST_AUTO_TEST_CASE(strayReject1)
 {
+    // A wildly different frequency occurring in the middle of a
+    // provisionally accepted note should be ignored
     NoteHypothesis h;
     NoteHypothesis::Estimate e1(500, RealTime::fromMilliseconds(0), 1);
     NoteHypothesis::Estimate e2(1000, RealTime::fromMilliseconds(10), 1);
@@ -101,21 +145,34 @@
     BOOST_CHECK(h.accept(e4));
     BOOST_CHECK_EQUAL(h.getState(), NoteHypothesis::Satisfied);
 }
-		
-BOOST_AUTO_TEST_CASE(tooSlow)
+
+BOOST_AUTO_TEST_CASE(strayReject2)
 {
+    // A wildly different frequency occurring in the middle of a
+    // satisfied note should be ignored
     NoteHypothesis h;
     NoteHypothesis::Estimate e1(500, RealTime::fromMilliseconds(0), 1);
-    NoteHypothesis::Estimate e2(500, RealTime::fromMilliseconds(50), 1);
+    NoteHypothesis::Estimate e2(500, RealTime::fromMilliseconds(10), 1);
+    NoteHypothesis::Estimate e3(500, RealTime::fromMilliseconds(20), 1);
+    NoteHypothesis::Estimate e4(1000, RealTime::fromMilliseconds(30), 1);
+    NoteHypothesis::Estimate e5(500, RealTime::fromMilliseconds(40), 1);
     BOOST_CHECK_EQUAL(h.getState(), NoteHypothesis::New);
     BOOST_CHECK(h.accept(e1));
     BOOST_CHECK_EQUAL(h.getState(), NoteHypothesis::Provisional);
-    BOOST_CHECK(!h.accept(e2));
-    BOOST_CHECK_EQUAL(h.getState(), NoteHypothesis::Rejected);
+    BOOST_CHECK(h.accept(e2));
+    BOOST_CHECK_EQUAL(h.getState(), NoteHypothesis::Provisional);
+    BOOST_CHECK(h.accept(e3));
+    BOOST_CHECK_EQUAL(h.getState(), NoteHypothesis::Satisfied);
+    BOOST_CHECK(!h.accept(e4));
+    BOOST_CHECK_EQUAL(h.getState(), NoteHypothesis::Satisfied);
+    BOOST_CHECK(h.accept(e5));
+    BOOST_CHECK_EQUAL(h.getState(), NoteHypothesis::Satisfied);
 }
 	
 BOOST_AUTO_TEST_CASE(weakSatisfy)
 {
+    // Behaviour with slightly varying frequencies should be as for
+    // that with fixed frequency
     NoteHypothesis h;
     NoteHypothesis::Estimate e1(500, RealTime::fromMilliseconds(0), 0.5);
     NoteHypothesis::Estimate e2(502, RealTime::fromMilliseconds(10), 0.5);
@@ -140,6 +197,8 @@
 	
 BOOST_AUTO_TEST_CASE(frequencyRange)
 {
+    // But there's a limit: outside a certain range we should reject
+    //!!! (but what is this range? is it part of the spec?)
     NoteHypothesis h;
     NoteHypothesis::Estimate e1(440, RealTime::fromMilliseconds(0), 1);
     NoteHypothesis::Estimate e2(448, RealTime::fromMilliseconds(10), 1);
@@ -158,6 +217,7 @@
 
 BOOST_AUTO_TEST_CASE(acceptedEstimates)
 {
+    // Check that getAcceptedEstimates() returns the right result
     NoteHypothesis h;
     NoteHypothesis::Estimate e1(440, RealTime::fromMilliseconds(0), 1);
     NoteHypothesis::Estimate e2(448, RealTime::fromMilliseconds(10), 1);
@@ -189,6 +249,7 @@
 	
 BOOST_AUTO_TEST_CASE(meanFrequency)
 {
+    // Check that the mean frequency is the mean of the frequencies
     NoteHypothesis h;
     NoteHypothesis::Estimate e1(440, RealTime::fromMilliseconds(0), 1);
     NoteHypothesis::Estimate e2(448, RealTime::fromMilliseconds(10), 1);
@@ -201,6 +262,7 @@
 
 BOOST_AUTO_TEST_CASE(averagedNote)
 {
+    // Check that getAveragedNote returns something sane
     NoteHypothesis h;
     NoteHypothesis::Estimate e1(440, RealTime::fromMilliseconds(10), 1);
     NoteHypothesis::Estimate e2(448, RealTime::fromMilliseconds(20), 1);
@@ -214,5 +276,7 @@
                        RealTime::fromMilliseconds(20)));
 }
 
+//!!! Not yet tested: Confidence scores
+
 BOOST_AUTO_TEST_SUITE_END()