Chris@32
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@37
|
2 /*
|
Chris@37
|
3 This file is Copyright (c) 2012 Chris Cannam
|
Chris@37
|
4
|
Chris@37
|
5 Permission is hereby granted, free of charge, to any person
|
Chris@37
|
6 obtaining a copy of this software and associated documentation
|
Chris@37
|
7 files (the "Software"), to deal in the Software without
|
Chris@37
|
8 restriction, including without limitation the rights to use, copy,
|
Chris@37
|
9 modify, merge, publish, distribute, sublicense, and/or sell copies
|
Chris@37
|
10 of the Software, and to permit persons to whom the Software is
|
Chris@37
|
11 furnished to do so, subject to the following conditions:
|
Chris@37
|
12
|
Chris@37
|
13 The above copyright notice and this permission notice shall be
|
Chris@37
|
14 included in all copies or substantial portions of the Software.
|
Chris@37
|
15
|
Chris@37
|
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
Chris@37
|
17 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
Chris@37
|
18 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
Chris@37
|
19 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
|
Chris@37
|
20 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
Chris@37
|
21 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
Chris@37
|
22 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
Chris@37
|
23 */
|
Chris@32
|
24
|
Chris@32
|
25 #ifndef _NOTE_HYPOTHESIS_H_
|
Chris@32
|
26 #define _NOTE_HYPOTHESIS_H_
|
Chris@32
|
27
|
Chris@35
|
28 #include "vamp-sdk/RealTime.h"
|
Chris@32
|
29 #include <vector>
|
Chris@32
|
30
|
Chris@32
|
31 /**
|
Chris@32
|
32 * An agent used to test an incoming series of instantaneous pitch
|
Chris@32
|
33 * estimates to see whether they fit a consistent single-note
|
Chris@32
|
34 * relationship. Contains rules specific to testing note pitch and
|
Chris@32
|
35 * timing.
|
Chris@32
|
36 */
|
Chris@32
|
37
|
Chris@32
|
38 class NoteHypothesis
|
Chris@32
|
39 {
|
Chris@32
|
40 public:
|
Chris@32
|
41 enum State {
|
Chris@32
|
42
|
Chris@45
|
43 /// Just constructed, will provisionally accept any estimate
|
Chris@45
|
44 New,
|
Chris@32
|
45
|
Chris@45
|
46 /// Accepted at least one estimate, but not enough evidence to satisfy
|
Chris@45
|
47 Provisional,
|
Chris@32
|
48
|
Chris@45
|
49 /// Could not find enough consistency in offered estimates
|
Chris@45
|
50 Rejected,
|
Chris@32
|
51
|
Chris@45
|
52 /// Have accepted enough consistent estimates to satisfy hypothesis
|
Chris@45
|
53 Satisfied,
|
Chris@32
|
54
|
Chris@45
|
55 /// Have been satisfied, but evidence has now changed: we're done
|
Chris@45
|
56 Expired
|
Chris@32
|
57 };
|
Chris@32
|
58
|
Chris@32
|
59 /**
|
Chris@32
|
60 * Construct an empty hypothesis. This will be in New state and
|
Chris@32
|
61 * will provisionally accept any estimate.
|
Chris@32
|
62 */
|
Chris@32
|
63 NoteHypothesis();
|
Chris@32
|
64
|
Chris@32
|
65 /**
|
Chris@32
|
66 * Destroy the hypothesis
|
Chris@32
|
67 */
|
Chris@32
|
68 ~NoteHypothesis();
|
Chris@32
|
69
|
Chris@32
|
70 struct Estimate {
|
Chris@58
|
71 Estimate() : freq(0), time(), confidence(1) { }
|
Chris@35
|
72 Estimate(double _f, Vamp::RealTime _t, double _c) :
|
Chris@33
|
73 freq(_f), time(_t), confidence(_c) { }
|
Chris@34
|
74 bool operator==(const Estimate &e) const {
|
Chris@34
|
75 return e.freq == freq && e.time == time && e.confidence == confidence;
|
Chris@34
|
76 }
|
Chris@45
|
77 double freq;
|
Chris@35
|
78 Vamp::RealTime time;
|
Chris@45
|
79 double confidence;
|
Chris@32
|
80 };
|
Chris@32
|
81 typedef std::vector<Estimate> Estimates;
|
Chris@32
|
82
|
Chris@32
|
83 /**
|
Chris@32
|
84 * Test the given estimate to see whether it is consistent with
|
Chris@32
|
85 * this hypothesis, and adjust the hypothesis' internal state
|
Chris@32
|
86 * accordingly. If the estimate is not inconsistent with the
|
Chris@32
|
87 * hypothesis, return true.
|
Chris@32
|
88 */
|
Chris@32
|
89 bool accept(Estimate);
|
Chris@32
|
90
|
Chris@32
|
91 /**
|
Chris@32
|
92 * Return the current state of this hypothesis.
|
Chris@32
|
93 */
|
Chris@32
|
94 State getState() const;
|
Chris@32
|
95
|
Chris@32
|
96 /**
|
Chris@32
|
97 * If the hypothesis has been satisfied (i.e. is in Satisfied or
|
Chris@32
|
98 * Expired state), return the series of estimates that it
|
Chris@32
|
99 * accepted. Otherwise return an empty list
|
Chris@32
|
100 */
|
Chris@32
|
101 Estimates getAcceptedEstimates() const;
|
Chris@32
|
102
|
Chris@32
|
103 struct Note {
|
Chris@33
|
104 Note() : freq(0), time(), duration() { }
|
Chris@35
|
105 Note(double _f, Vamp::RealTime _t, Vamp::RealTime _d) :
|
Chris@33
|
106 freq(_f), time(_t), duration(_d) { }
|
Chris@34
|
107 bool operator==(const Note &e) const {
|
Chris@34
|
108 return e.freq == freq && e.time == time && e.duration == duration;
|
Chris@34
|
109 }
|
Chris@45
|
110 double freq;
|
Chris@45
|
111 Vamp::RealTime time;
|
Chris@45
|
112 Vamp::RealTime duration;
|
Chris@32
|
113 };
|
Chris@32
|
114
|
Chris@32
|
115 /**
|
Chris@52
|
116 * Return the time of the first accepted estimate
|
Chris@52
|
117 */
|
Chris@52
|
118 Vamp::RealTime getStartTime() const;
|
Chris@52
|
119
|
Chris@52
|
120 /**
|
Chris@34
|
121 * Return the mean frequency of the accepted estimates
|
Chris@34
|
122 */
|
Chris@34
|
123 double getMeanFrequency() const;
|
Chris@34
|
124
|
Chris@34
|
125 /**
|
Chris@32
|
126 * Return a single note roughly matching this hypothesis
|
Chris@32
|
127 */
|
Chris@32
|
128 Note getAveragedNote() const;
|
Chris@32
|
129
|
Chris@32
|
130 private:
|
Chris@32
|
131 bool isWithinTolerance(Estimate) const;
|
Chris@32
|
132 bool isOutOfDateFor(Estimate) const;
|
Chris@32
|
133 bool isSatisfied() const;
|
Chris@32
|
134
|
Chris@32
|
135 State m_state;
|
Chris@32
|
136 Estimates m_pending;
|
Chris@32
|
137 };
|
Chris@32
|
138
|
Chris@32
|
139 #endif
|