Chris@32
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@32
|
2 /* Copyright Chris Cannam - All Rights Reserved */
|
Chris@32
|
3
|
Chris@32
|
4 #ifndef _NOTE_HYPOTHESIS_H_
|
Chris@32
|
5 #define _NOTE_HYPOTHESIS_H_
|
Chris@32
|
6
|
Chris@32
|
7 #include "base/RealTime.h"
|
Chris@32
|
8 #include <vector>
|
Chris@32
|
9
|
Chris@32
|
10 namespace Turbot {
|
Chris@32
|
11
|
Chris@32
|
12 /**
|
Chris@32
|
13 * An agent used to test an incoming series of instantaneous pitch
|
Chris@32
|
14 * estimates to see whether they fit a consistent single-note
|
Chris@32
|
15 * relationship. Contains rules specific to testing note pitch and
|
Chris@32
|
16 * timing.
|
Chris@32
|
17 */
|
Chris@32
|
18
|
Chris@32
|
19 class NoteHypothesis
|
Chris@32
|
20 {
|
Chris@32
|
21 public:
|
Chris@32
|
22 enum State {
|
Chris@32
|
23
|
Chris@32
|
24 /// Just constructed, will provisionally accept any estimate
|
Chris@32
|
25 New,
|
Chris@32
|
26
|
Chris@32
|
27 /// Accepted at least one estimate, but not enough evidence to satisfy
|
Chris@32
|
28 Provisional,
|
Chris@32
|
29
|
Chris@32
|
30 /// Could not find enough consistency in offered estimates
|
Chris@32
|
31 Rejected,
|
Chris@32
|
32
|
Chris@32
|
33 /// Have accepted enough consistent estimates to satisfy hypothesis
|
Chris@32
|
34 Satisfied,
|
Chris@32
|
35
|
Chris@32
|
36 /// Have been satisfied, but evidence has now changed: we're done
|
Chris@32
|
37 Expired
|
Chris@32
|
38 };
|
Chris@32
|
39
|
Chris@32
|
40 /**
|
Chris@32
|
41 * Construct an empty hypothesis. This will be in New state and
|
Chris@32
|
42 * will provisionally accept any estimate.
|
Chris@32
|
43 */
|
Chris@32
|
44 NoteHypothesis();
|
Chris@32
|
45
|
Chris@32
|
46 /**
|
Chris@32
|
47 * Destroy the hypothesis
|
Chris@32
|
48 */
|
Chris@32
|
49 ~NoteHypothesis();
|
Chris@32
|
50
|
Chris@32
|
51 struct Estimate {
|
Chris@32
|
52 double freq;
|
Chris@32
|
53 RealTime time;
|
Chris@32
|
54 double confidence;
|
Chris@32
|
55 };
|
Chris@32
|
56 typedef std::vector<Estimate> Estimates;
|
Chris@32
|
57
|
Chris@32
|
58 /**
|
Chris@32
|
59 * Test the given estimate to see whether it is consistent with
|
Chris@32
|
60 * this hypothesis, and adjust the hypothesis' internal state
|
Chris@32
|
61 * accordingly. If the estimate is not inconsistent with the
|
Chris@32
|
62 * hypothesis, return true.
|
Chris@32
|
63 */
|
Chris@32
|
64 bool accept(Estimate);
|
Chris@32
|
65
|
Chris@32
|
66 /**
|
Chris@32
|
67 * Return the current state of this hypothesis.
|
Chris@32
|
68 */
|
Chris@32
|
69 State getState() const;
|
Chris@32
|
70
|
Chris@32
|
71 /**
|
Chris@32
|
72 * If the hypothesis has been satisfied (i.e. is in Satisfied or
|
Chris@32
|
73 * Expired state), return the series of estimates that it
|
Chris@32
|
74 * accepted. Otherwise return an empty list
|
Chris@32
|
75 */
|
Chris@32
|
76 Estimates getAcceptedEstimates() const;
|
Chris@32
|
77
|
Chris@32
|
78 struct Note {
|
Chris@32
|
79 double freq;
|
Chris@32
|
80 RealTime time;
|
Chris@32
|
81 RealTime duration;
|
Chris@32
|
82 };
|
Chris@32
|
83
|
Chris@32
|
84 /**
|
Chris@32
|
85 * Return a single note roughly matching this hypothesis
|
Chris@32
|
86 */
|
Chris@32
|
87 Note getAveragedNote() const;
|
Chris@32
|
88
|
Chris@32
|
89 private:
|
Chris@32
|
90 bool isWithinTolerance(Estimate) const;
|
Chris@32
|
91 bool isOutOfDateFor(Estimate) const;
|
Chris@32
|
92 bool isSatisfied() const;
|
Chris@32
|
93 double getMeanFrequency() const;
|
Chris@32
|
94
|
Chris@32
|
95 State m_state;
|
Chris@32
|
96 Estimates m_pending;
|
Chris@32
|
97 };
|
Chris@32
|
98
|
Chris@32
|
99 }
|
Chris@32
|
100
|
Chris@32
|
101 #endif
|