Mercurial > hg > vamp-plugin-sdk
comparison vamp-sdk/hostext/PluginSummarisingAdapter.cpp @ 174:a6346812db44
* PluginSummarisingAdapter now compiles -- though doesn't actually work
yet
author | cannam |
---|---|
date | Tue, 05 Aug 2008 13:38:30 +0000 |
parents | a6981e5dafe5 |
children | 4811fb599a97 |
comparison
equal
deleted
inserted
replaced
173:a6981e5dafe5 | 174:a6346812db44 |
---|---|
34 authorization. | 34 authorization. |
35 */ | 35 */ |
36 | 36 |
37 #include "PluginSummarisingAdapter.h" | 37 #include "PluginSummarisingAdapter.h" |
38 | 38 |
39 #include <map> | |
40 | |
39 namespace Vamp { | 41 namespace Vamp { |
40 | 42 |
41 namespace HostExt { | 43 namespace HostExt { |
42 | 44 |
43 class PluginSummarisingAdapter::Impl | 45 class PluginSummarisingAdapter::Impl |
52 void setSummarySegmentBoundaries(const SegmentBoundaries &); | 54 void setSummarySegmentBoundaries(const SegmentBoundaries &); |
53 | 55 |
54 FeatureSet getSummary(SummaryType type); | 56 FeatureSet getSummary(SummaryType type); |
55 | 57 |
56 protected: | 58 protected: |
59 Plugin *m_plugin; | |
60 | |
57 SegmentBoundaries m_boundaries; | 61 SegmentBoundaries m_boundaries; |
62 | |
63 typedef std::vector<float> ValueList; | |
64 typedef std::map<int, ValueList> BinValueMap; | |
65 | |
66 struct OutputAccumulator { | |
67 int count; | |
68 BinValueMap values; | |
69 }; | |
70 | |
71 typedef std::map<int, OutputAccumulator> OutputAccumulatorMap; | |
72 OutputAccumulatorMap m_accumulators; | |
73 | |
74 struct OutputBinSummary { | |
75 float minimum; | |
76 float maximum; | |
77 float median; | |
78 float mode; | |
79 float sum; | |
80 float variance; | |
81 int count; | |
82 }; | |
83 | |
84 typedef std::map<int, OutputBinSummary> OutputSummary; | |
85 typedef std::map<RealTime, OutputSummary> SummarySegmentMap; | |
86 typedef std::map<int, SummarySegmentMap> OutputSummarySegmentMap; | |
87 | |
88 OutputSummarySegmentMap m_summaries; | |
89 | |
90 RealTime m_lastTimestamp; | |
91 | |
92 void accumulate(const FeatureSet &fs, RealTime); | |
93 void accumulate(int output, const Feature &f, RealTime); | |
94 void reduce(); | |
58 }; | 95 }; |
59 | 96 |
60 PluginSummarisingAdapter::PluginSummarisingAdapter(Plugin *plugin) : | 97 PluginSummarisingAdapter::PluginSummarisingAdapter(Plugin *plugin) : |
61 PluginWrapper(plugin) | 98 PluginWrapper(plugin) |
62 { | 99 { |
72 PluginSummarisingAdapter::process(const float *const *inputBuffers, RealTime timestamp) | 109 PluginSummarisingAdapter::process(const float *const *inputBuffers, RealTime timestamp) |
73 { | 110 { |
74 return m_impl->process(inputBuffers, timestamp); | 111 return m_impl->process(inputBuffers, timestamp); |
75 } | 112 } |
76 | 113 |
114 Plugin::FeatureSet | |
115 PluginSummarisingAdapter::getRemainingFeatures() | |
116 { | |
117 return m_impl->getRemainingFeatures(); | |
118 } | |
119 | |
77 | 120 |
78 PluginSummarisingAdapter::Impl::Impl(Plugin *plugin, float inputSampleRate) : | 121 PluginSummarisingAdapter::Impl::Impl(Plugin *plugin, float inputSampleRate) : |
79 m_plugin(plugin), | 122 m_plugin(plugin) |
80 m_inputSampleRate(inputSampleRate) | |
81 { | 123 { |
82 } | 124 } |
83 | 125 |
84 PluginSummarisingAdapter::Impl::~Impl() | 126 PluginSummarisingAdapter::Impl::~Impl() |
85 { | 127 { |
86 } | 128 } |
87 | 129 |
130 Plugin::FeatureSet | |
131 PluginSummarisingAdapter::Impl::process(const float *const *inputBuffers, RealTime timestamp) | |
132 { | |
133 FeatureSet fs = m_plugin->process(inputBuffers, timestamp); | |
134 accumulate(fs, timestamp); | |
135 m_lastTimestamp = timestamp; | |
136 return fs; | |
137 } | |
138 | |
139 Plugin::FeatureSet | |
140 PluginSummarisingAdapter::Impl::getRemainingFeatures() | |
141 { | |
142 FeatureSet fs = m_plugin->getRemainingFeatures(); | |
143 accumulate(fs, m_lastTimestamp); | |
144 reduce(); | |
145 return fs; | |
146 } | |
147 | |
148 void | |
149 PluginSummarisingAdapter::Impl::accumulate(const FeatureSet &fs, | |
150 RealTime timestamp) | |
151 { | |
152 for (FeatureSet::const_iterator i = fs.begin(); i != fs.end(); ++i) { | |
153 for (FeatureList::const_iterator j = i->second.begin(); | |
154 j != i->second.end(); ++j) { | |
155 accumulate(i->first, *j, timestamp); | |
156 } | |
157 } | |
158 } | |
159 | |
160 void | |
161 PluginSummarisingAdapter::Impl::accumulate(int output, | |
162 const Feature &f, | |
163 RealTime timestamp) | |
164 { | |
165 //!!! use timestamp to determine which segment we're on | |
166 m_accumulators[output].count++; | |
167 for (int i = 0; i < int(f.values.size()); ++i) { | |
168 m_accumulators[output].values[i].push_back(f.values[i]); | |
169 } | |
170 } | |
171 | |
172 void | |
173 PluginSummarisingAdapter::Impl::reduce() | |
174 { | |
175 RealTime segmentStart = RealTime::zeroTime; //!!! | |
176 | |
177 for (OutputAccumulatorMap::iterator i = m_accumulators.begin(); | |
178 i != m_accumulators.end(); ++i) { | |
179 | |
180 int output = i->first; | |
181 OutputAccumulator &accumulator = i->second; | |
182 | |
183 for (BinValueMap::iterator j = accumulator.values.begin(); | |
184 j != accumulator.values.end(); ++j) { | |
185 | |
186 int bin = j->first; | |
187 ValueList &values = j->second; | |
188 | |
189 OutputBinSummary summary; | |
190 summary.minimum = 0.f; | |
191 summary.maximum = 0.f; | |
192 summary.median = 0.f; | |
193 summary.mode = 0.f; | |
194 summary.sum = 0.f; | |
195 summary.variance = 0.f; | |
196 summary.count = accumulator.count; | |
197 if (summary.count == 0 || values.empty()) continue; | |
198 | |
199 std::sort(values.begin(), values.end()); | |
200 int sz = values.size(); | |
201 | |
202 summary.minimum = values[0]; | |
203 summary.maximum = values[sz-1]; | |
204 | |
205 if (sz % 2 == 1) { | |
206 summary.median = values[sz/2]; | |
207 } else { | |
208 summary.median = (values[sz/2] + values[sz/2 + 1]) / 2; | |
209 } | |
210 | |
211 std::map<float, int> distribution; | |
212 | |
213 for (int k = 0; k < sz; ++k) { | |
214 summary.sum += values[k]; | |
215 ++distribution[values[k]]; | |
216 } | |
217 | |
218 int md = 0; | |
219 | |
220 //!!! I don't like this. Really the mode should be the | |
221 //!!! value that spans the longest period of time, not the | |
222 //!!! one that appears in the largest number of distinct | |
223 //!!! features. | |
224 | |
225 for (std::map<float, int>::iterator di = distribution.begin(); | |
226 di != distribution.end(); ++di) { | |
227 if (di->second > md) { | |
228 md = di->second; | |
229 summary.mode = di->first; | |
230 } | |
231 } | |
232 | |
233 distribution.clear(); | |
234 | |
235 float mean = summary.sum / summary.count; | |
236 | |
237 for (int k = 0; k < sz; ++k) { | |
238 summary.variance += (values[k] - mean) * (values[k] - mean); | |
239 } | |
240 summary.variance /= summary.count; | |
241 | |
242 m_summaries[output][segmentStart][bin] = summary; | |
243 } | |
244 } | |
245 } | |
246 | |
247 | |
248 } | |
249 | |
250 } | |
251 |