Mercurial > hg > vamp-plugin-sdk
diff 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 |
line wrap: on
line diff
--- a/vamp-sdk/hostext/PluginSummarisingAdapter.cpp Mon Aug 04 16:13:14 2008 +0000 +++ b/vamp-sdk/hostext/PluginSummarisingAdapter.cpp Tue Aug 05 13:38:30 2008 +0000 @@ -36,6 +36,8 @@ #include "PluginSummarisingAdapter.h" +#include <map> + namespace Vamp { namespace HostExt { @@ -54,7 +56,42 @@ FeatureSet getSummary(SummaryType type); protected: + Plugin *m_plugin; + SegmentBoundaries m_boundaries; + + typedef std::vector<float> ValueList; + typedef std::map<int, ValueList> BinValueMap; + + struct OutputAccumulator { + int count; + BinValueMap values; + }; + + typedef std::map<int, OutputAccumulator> OutputAccumulatorMap; + OutputAccumulatorMap m_accumulators; + + struct OutputBinSummary { + float minimum; + float maximum; + float median; + float mode; + float sum; + float variance; + int count; + }; + + typedef std::map<int, OutputBinSummary> OutputSummary; + typedef std::map<RealTime, OutputSummary> SummarySegmentMap; + typedef std::map<int, SummarySegmentMap> OutputSummarySegmentMap; + + OutputSummarySegmentMap m_summaries; + + RealTime m_lastTimestamp; + + void accumulate(const FeatureSet &fs, RealTime); + void accumulate(int output, const Feature &f, RealTime); + void reduce(); }; PluginSummarisingAdapter::PluginSummarisingAdapter(Plugin *plugin) : @@ -74,10 +111,15 @@ return m_impl->process(inputBuffers, timestamp); } +Plugin::FeatureSet +PluginSummarisingAdapter::getRemainingFeatures() +{ + return m_impl->getRemainingFeatures(); +} + PluginSummarisingAdapter::Impl::Impl(Plugin *plugin, float inputSampleRate) : - m_plugin(plugin), - m_inputSampleRate(inputSampleRate) + m_plugin(plugin) { } @@ -85,3 +127,125 @@ { } +Plugin::FeatureSet +PluginSummarisingAdapter::Impl::process(const float *const *inputBuffers, RealTime timestamp) +{ + FeatureSet fs = m_plugin->process(inputBuffers, timestamp); + accumulate(fs, timestamp); + m_lastTimestamp = timestamp; + return fs; +} + +Plugin::FeatureSet +PluginSummarisingAdapter::Impl::getRemainingFeatures() +{ + FeatureSet fs = m_plugin->getRemainingFeatures(); + accumulate(fs, m_lastTimestamp); + reduce(); + return fs; +} + +void +PluginSummarisingAdapter::Impl::accumulate(const FeatureSet &fs, + RealTime timestamp) +{ + for (FeatureSet::const_iterator i = fs.begin(); i != fs.end(); ++i) { + for (FeatureList::const_iterator j = i->second.begin(); + j != i->second.end(); ++j) { + accumulate(i->first, *j, timestamp); + } + } +} + +void +PluginSummarisingAdapter::Impl::accumulate(int output, + const Feature &f, + RealTime timestamp) +{ +//!!! use timestamp to determine which segment we're on + m_accumulators[output].count++; + for (int i = 0; i < int(f.values.size()); ++i) { + m_accumulators[output].values[i].push_back(f.values[i]); + } +} + +void +PluginSummarisingAdapter::Impl::reduce() +{ + RealTime segmentStart = RealTime::zeroTime; //!!! + + for (OutputAccumulatorMap::iterator i = m_accumulators.begin(); + i != m_accumulators.end(); ++i) { + + int output = i->first; + OutputAccumulator &accumulator = i->second; + + for (BinValueMap::iterator j = accumulator.values.begin(); + j != accumulator.values.end(); ++j) { + + int bin = j->first; + ValueList &values = j->second; + + OutputBinSummary summary; + summary.minimum = 0.f; + summary.maximum = 0.f; + summary.median = 0.f; + summary.mode = 0.f; + summary.sum = 0.f; + summary.variance = 0.f; + summary.count = accumulator.count; + if (summary.count == 0 || values.empty()) continue; + + std::sort(values.begin(), values.end()); + int sz = values.size(); + + summary.minimum = values[0]; + summary.maximum = values[sz-1]; + + if (sz % 2 == 1) { + summary.median = values[sz/2]; + } else { + summary.median = (values[sz/2] + values[sz/2 + 1]) / 2; + } + + std::map<float, int> distribution; + + for (int k = 0; k < sz; ++k) { + summary.sum += values[k]; + ++distribution[values[k]]; + } + + int md = 0; + + //!!! I don't like this. Really the mode should be the + //!!! value that spans the longest period of time, not the + //!!! one that appears in the largest number of distinct + //!!! features. + + for (std::map<float, int>::iterator di = distribution.begin(); + di != distribution.end(); ++di) { + if (di->second > md) { + md = di->second; + summary.mode = di->first; + } + } + + distribution.clear(); + + float mean = summary.sum / summary.count; + + for (int k = 0; k < sz; ++k) { + summary.variance += (values[k] - mean) * (values[k] - mean); + } + summary.variance /= summary.count; + + m_summaries[output][segmentStart][bin] = summary; + } + } +} + + +} + +} +