Chris@181
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@181
|
2
|
Chris@181
|
3 /*
|
Chris@181
|
4 Silvet
|
Chris@181
|
5
|
Chris@181
|
6 A Vamp plugin for note transcription.
|
Chris@181
|
7 Centre for Digital Music, Queen Mary University of London.
|
Chris@181
|
8 This file Copyright 2012 Chris Cannam.
|
Chris@181
|
9
|
Chris@181
|
10 This program is free software; you can redistribute it and/or
|
Chris@181
|
11 modify it under the terms of the GNU General Public License as
|
Chris@181
|
12 published by the Free Software Foundation; either version 2 of the
|
Chris@181
|
13 License, or (at your option) any later version. See the file
|
Chris@181
|
14 COPYING included with this distribution for more information.
|
Chris@181
|
15 */
|
Chris@181
|
16
|
Chris@181
|
17 #ifndef AGENT_FEEDER_MONO_H
|
Chris@181
|
18 #define AGENT_FEEDER_MONO_H
|
Chris@181
|
19
|
Chris@181
|
20 #include "AgentFeeder.h"
|
Chris@181
|
21
|
Chris@181
|
22 //#define DEBUG_FEEDER 1
|
Chris@181
|
23
|
Chris@181
|
24 /**
|
Chris@181
|
25 * Take a series of observations or estimates (one at a time) and feed
|
Chris@181
|
26 * them to a set of agent hypotheses, creating a new candidate agent
|
Chris@181
|
27 * for each observation and also testing the observation against the
|
Chris@181
|
28 * existing set of hypotheses.
|
Chris@181
|
29 *
|
Chris@181
|
30 * One satisfied hypothesis is considered to be "accepted" at any
|
Chris@181
|
31 * moment (that is, the earliest contemporary hypothesis to have
|
Chris@181
|
32 * become satisfied). The series of accepted and completed hypotheses
|
Chris@181
|
33 * from construction to the present time can be queried through
|
Chris@181
|
34 * getAcceptedHypotheses().
|
Chris@181
|
35 *
|
Chris@181
|
36 * Call feed() to provide a new observation. Call finish() when all
|
Chris@181
|
37 * observations have been provided. The set of hypotheses returned by
|
Chris@181
|
38 * getAcceptedHypotheses() will not be complete unless finish() has
|
Chris@181
|
39 * been called.
|
Chris@181
|
40 */
|
Chris@181
|
41 template <typename Hypothesis>
|
Chris@181
|
42 class AgentFeederMono : public AgentFeeder
|
Chris@181
|
43 {
|
Chris@181
|
44 public:
|
Chris@181
|
45 AgentFeederMono() { }
|
Chris@181
|
46
|
Chris@181
|
47 typedef std::set<Hypothesis> Hypotheses;
|
Chris@181
|
48
|
Chris@181
|
49 virtual void feed(AgentHypothesis::Observation o) {
|
Chris@181
|
50
|
Chris@181
|
51 #ifdef DEBUG_FEEDER
|
Chris@181
|
52 std::cerr << "feed: have observation [value = " << o.value << ", time = " << o.time << "]" << std::endl;
|
Chris@181
|
53 #endif
|
Chris@181
|
54
|
Chris@181
|
55 if (!m_current.accept(o)) {
|
Chris@181
|
56
|
Chris@181
|
57 if (m_current.getState() == Hypothesis::Expired) {
|
Chris@181
|
58 m_accepted.insert(m_current);
|
Chris@181
|
59 #ifdef DEBUG_FEEDER
|
Chris@181
|
60 std::cerr << "current has expired, pushing to accepted" << std::endl;
|
Chris@181
|
61 #endif
|
Chris@181
|
62 }
|
Chris@181
|
63
|
Chris@181
|
64 bool swallowed = false;
|
Chris@181
|
65
|
Chris@181
|
66 #ifdef DEBUG_FEEDER
|
Chris@181
|
67 std::cerr << "not swallowed by current" << std::endl;
|
Chris@181
|
68 #endif
|
Chris@181
|
69
|
Chris@181
|
70 Hypotheses newCandidates;
|
Chris@181
|
71
|
Chris@181
|
72 for (typename Hypotheses::iterator i = m_candidates.begin();
|
Chris@181
|
73 i != m_candidates.end(); ++i) {
|
Chris@181
|
74
|
Chris@181
|
75 Hypothesis h = *i;
|
Chris@181
|
76
|
Chris@181
|
77 if (swallowed) {
|
Chris@181
|
78
|
Chris@181
|
79 // don't offer: each observation can only belong to one
|
Chris@181
|
80 // satisfied hypothesis
|
Chris@181
|
81 newCandidates.insert(h);
|
Chris@181
|
82
|
Chris@181
|
83 } else {
|
Chris@181
|
84
|
Chris@181
|
85 if (h.accept(o)) {
|
Chris@181
|
86 #ifdef DEBUG_FEEDER
|
Chris@181
|
87 std::cerr << "accepted, state is " << h.getState() << std::endl;
|
Chris@181
|
88 #endif
|
Chris@181
|
89 if (h.getState() == Hypothesis::Satisfied) {
|
Chris@181
|
90
|
Chris@181
|
91 swallowed = true;
|
Chris@181
|
92
|
Chris@181
|
93 if (m_current.getState() == Hypothesis::Expired ||
|
Chris@181
|
94 m_current.getState() == Hypothesis::Rejected) {
|
Chris@181
|
95 #ifdef DEBUG_FEEDER
|
Chris@181
|
96 std::cerr << "current has ended, updating from candidate" << std::endl;
|
Chris@181
|
97 #endif
|
Chris@181
|
98 m_current = h;
|
Chris@181
|
99 } else {
|
Chris@181
|
100 newCandidates.insert(h);
|
Chris@181
|
101 }
|
Chris@181
|
102
|
Chris@181
|
103 } else {
|
Chris@181
|
104 newCandidates.insert(h);
|
Chris@181
|
105 }
|
Chris@181
|
106 }
|
Chris@181
|
107 }
|
Chris@181
|
108 }
|
Chris@181
|
109
|
Chris@181
|
110 if (!swallowed) {
|
Chris@181
|
111 Hypothesis h;
|
Chris@181
|
112 h.accept(o); // must succeed, as h is new
|
Chris@181
|
113 newCandidates.insert(h);
|
Chris@181
|
114 #ifdef DEBUG_FEEDER
|
Chris@181
|
115 std::cerr << "not swallowed, creating new hypothesis" << std::endl;
|
Chris@181
|
116 #endif
|
Chris@181
|
117 }
|
Chris@181
|
118
|
Chris@181
|
119 // reap rejected/expired hypotheses from candidates list,
|
Chris@181
|
120 // and assign back to m_candidates
|
Chris@181
|
121
|
Chris@181
|
122 m_candidates.clear();
|
Chris@181
|
123
|
Chris@181
|
124 for (typename Hypotheses::const_iterator i = newCandidates.begin();
|
Chris@181
|
125 i != newCandidates.end(); ++i) {
|
Chris@181
|
126 Hypothesis h = *i;
|
Chris@181
|
127 if (h.getState() != Hypothesis::Rejected &&
|
Chris@181
|
128 h.getState() != Hypothesis::Expired) {
|
Chris@181
|
129 m_candidates.insert(h);
|
Chris@181
|
130 } else {
|
Chris@181
|
131 #ifdef DEBUG_FEEDER
|
Chris@181
|
132 std::cerr << "reaping a candidate" << std::endl;
|
Chris@181
|
133 #endif
|
Chris@181
|
134 }
|
Chris@181
|
135 }
|
Chris@181
|
136 }
|
Chris@181
|
137 #ifdef DEBUG_FEEDER
|
Chris@181
|
138 std::cerr << "have " << m_candidates.size() << " candidates" << std::endl;
|
Chris@181
|
139 #endif
|
Chris@181
|
140 }
|
Chris@181
|
141
|
Chris@181
|
142 virtual void finish() {
|
Chris@181
|
143 if (m_current.getState() == Hypothesis::Satisfied) {
|
Chris@181
|
144 #ifdef DEBUG_FEEDER
|
Chris@181
|
145 std::cerr << "finish: current is satisfied, pushing to accepted" << std::endl;
|
Chris@181
|
146 #endif
|
Chris@181
|
147 m_accepted.insert(m_current);
|
Chris@181
|
148 }
|
Chris@181
|
149 }
|
Chris@181
|
150
|
Chris@187
|
151 Hypotheses retrieveAcceptedHypotheses() {
|
Chris@187
|
152 Hypotheses aa = m_accepted;
|
Chris@187
|
153 m_accepted.clear();
|
Chris@187
|
154 return aa;
|
Chris@181
|
155 }
|
Chris@181
|
156
|
Chris@181
|
157 private:
|
Chris@181
|
158 Hypotheses m_candidates;
|
Chris@181
|
159 Hypothesis m_current;
|
Chris@181
|
160 Hypotheses m_accepted;
|
Chris@181
|
161 };
|
Chris@181
|
162
|
Chris@181
|
163 #endif
|