# HG changeset patch # User cannam # Date 1223398630 0 # Node ID 1e4c6f25ded693b8246c3d165c79b92b2cd0ecbc # Parent 27cfae2a4155c232236af9290a31d40a488f57f2 * More accurate calculation of summaries in continuous-time mode * Labels * Make some debug output optional diff -r 27cfae2a4155 -r 1e4c6f25ded6 vamp-sdk/hostext/PluginSummarisingAdapter.cpp --- a/vamp-sdk/hostext/PluginSummarisingAdapter.cpp Tue Sep 30 13:24:41 2008 +0000 +++ b/vamp-sdk/hostext/PluginSummarisingAdapter.cpp Tue Oct 07 16:57:10 2008 +0000 @@ -40,7 +40,8 @@ #include #include -//#define DEBUG_PLUGIN_SUMMARISING_ADAPTER 1 +#define DEBUG_PLUGIN_SUMMARISING_ADAPTER 1 +//#define DEBUG_PLUGIN_SUMMARISING_ADAPTER_SEGMENT 1 namespace Vamp { @@ -52,6 +53,8 @@ Impl(Plugin *plugin, float inputSampleRate); ~Impl(); + bool initialise(size_t channels, size_t stepSize, size_t blockSize); + FeatureSet process(const float *const *inputBuffers, RealTime timestamp); FeatureSet getRemainingFeatures(); @@ -67,6 +70,8 @@ protected: Plugin *m_plugin; float m_inputSampleRate; + size_t m_stepSize; + size_t m_blockSize; SegmentBoundaries m_boundaries; @@ -102,20 +107,20 @@ int count; // extents - float minimum; - float maximum; - float sum; + double minimum; + double maximum; + double sum; // sample-average results - float median; - float mode; - float variance; + double median; + double mode; + double variance; // continuous-time average results - float median_c; - float mode_c; - float mean_c; - float variance_c; + double median_c; + double mode_c; + double mean_c; + double variance_c; }; typedef std::map OutputSummary; @@ -125,7 +130,7 @@ OutputSummarySegmentMap m_summaries; bool m_reduced; - RealTime m_lastTimestamp; + RealTime m_endTime; void accumulate(const FeatureSet &fs, RealTime, bool final); void accumulate(int output, const Feature &f, RealTime, bool final); @@ -133,6 +138,8 @@ void findSegmentBounds(RealTime t, RealTime &start, RealTime &end); void segment(); void reduce(); + + std::string getSummaryLabel(SummaryType type, AveragingMethod avg); }; static RealTime INVALID_DURATION(INT_MIN, INT_MIN); @@ -148,6 +155,15 @@ delete m_impl; } +bool +PluginSummarisingAdapter::initialise(size_t channels, + size_t stepSize, size_t blockSize) +{ + return + PluginWrapper::initialise(channels, stepSize, blockSize) && + m_impl->initialise(channels, stepSize, blockSize); +} + Plugin::FeatureSet PluginSummarisingAdapter::process(const float *const *inputBuffers, RealTime timestamp) { @@ -192,16 +208,26 @@ { } +bool +PluginSummarisingAdapter::Impl::initialise(size_t channels, + size_t stepSize, size_t blockSize) +{ + m_stepSize = stepSize; + m_blockSize = blockSize; + return true; +} + Plugin::FeatureSet -PluginSummarisingAdapter::Impl::process(const float *const *inputBuffers, RealTime timestamp) +PluginSummarisingAdapter::Impl::process(const float *const *inputBuffers, + RealTime timestamp) { if (m_reduced) { std::cerr << "WARNING: Cannot call PluginSummarisingAdapter::process() or getRemainingFeatures() after one of the getSummary methods" << std::endl; } FeatureSet fs = m_plugin->process(inputBuffers, timestamp); accumulate(fs, timestamp, false); - //!!! should really be "timestamp plus step size" - m_lastTimestamp = timestamp; + m_endTime = timestamp + + RealTime::frame2RealTime(m_stepSize, m_inputSampleRate); return fs; } @@ -212,7 +238,7 @@ std::cerr << "WARNING: Cannot call PluginSummarisingAdapter::process() or getRemainingFeatures() after one of the getSummary methods" << std::endl; } FeatureSet fs = m_plugin->getRemainingFeatures(); - accumulate(fs, m_lastTimestamp, true); + accumulate(fs, m_endTime, true); return fs; } @@ -249,9 +275,19 @@ i != m_summaries[output].end(); ++i) { Feature f; + f.hasTimestamp = true; f.timestamp = i->first; - f.hasDuration = false; + + f.hasDuration = true; + SummarySegmentMap::const_iterator ii = i; + if (++ii == m_summaries[output].end()) { + f.duration = m_endTime - f.timestamp; + } else { + f.duration = ii->first - f.timestamp; + } + + f.label = getSummaryLabel(type, avg); for (OutputSummary::const_iterator j = i->second.begin(); j != i->second.end(); ++j) { @@ -261,7 +297,7 @@ // the accumulators were initially filled in accumulate()) const OutputBinSummary &summary = j->second; - float result = 0.f; + double result = 0.f; switch (type) { @@ -361,6 +397,32 @@ } } +std::string +PluginSummarisingAdapter::Impl::getSummaryLabel(SummaryType type, + AveragingMethod avg) +{ + std::string label; + std::string avglabel; + + if (avg == SampleAverage) avglabel = ", sample average"; + else avglabel = ", continuous-time average"; + + switch (type) { + case Minimum: label = "(minimum value)"; break; + case Maximum: label = "(maximum value)"; break; + case Mean: label = "(mean value" + avglabel + ")"; break; + case Median: label = "(median value" + avglabel + ")"; break; + case Mode: label = "(modal value" + avglabel + ")"; break; + case Sum: label = "(sum)"; break; + case Variance: label = "(variance" + avglabel + ")"; break; + case StandardDeviation: label = "(standard deviation" + avglabel + ")"; break; + case Count: label = "(count)"; break; + case UnknownSummaryType: label = "(unknown summary)"; break; + } + + return label; +} + void PluginSummarisingAdapter::Impl::accumulate(int output, const Feature &f, @@ -452,8 +514,11 @@ m_prevTimestamps[output] = timestamp; - //!!! should really be "timestamp plus duration" or "timestamp plus output resolution" - if (timestamp > m_lastTimestamp) m_lastTimestamp = timestamp; + if (f.hasDuration) { + RealTime et = timestamp; + et = et + f.duration; + if (et > m_endTime) m_endTime = et; + } Result result; result.time = timestamp; @@ -501,11 +566,11 @@ } else { #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER - std::cerr << "Pushing final duration from diff as " << m_lastTimestamp << " - " << m_prevTimestamps[output] << std::endl; + std::cerr << "Pushing final duration from diff as " << m_endTime << " - " << m_prevTimestamps[output] << std::endl; #endif m_accumulators[output].results[acount - 1].duration = - m_lastTimestamp - m_prevTimestamps[output]; + m_endTime - m_prevTimestamps[output]; } #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER @@ -521,7 +586,7 @@ RealTime &start, RealTime &end) { -#ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER +#ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER_SEGMENT std::cerr << "findSegmentBounds: t = " << t << std::endl; #endif @@ -529,7 +594,7 @@ (m_boundaries.begin(), m_boundaries.end(), t); start = RealTime::zeroTime; - end = m_lastTimestamp; + end = m_endTime; if (i != m_boundaries.end()) { end = *i; @@ -539,7 +604,7 @@ start = *--i; } -#ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER +#ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER_SEGMENT std::cerr << "findSegmentBounds: " << t << " is in segment " << start << " -> " << end << std::endl; #endif } @@ -556,7 +621,7 @@ int output = i->first; OutputAccumulator &source = i->second; -#ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER +#ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER_SEGMENT std::cerr << "segment: total results for output " << output << " = " << source.results.size() << std::endl; #endif @@ -575,7 +640,7 @@ RealTime resultStart = source.results[n].time; RealTime resultEnd = resultStart + source.results[n].duration; -#ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER +#ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER_SEGMENT std::cerr << "output: " << output << ", result start = " << resultStart << ", end = " << resultEnd << std::endl; #endif @@ -599,7 +664,7 @@ chunk.duration = chunkEnd - chunkStart; chunk.values = source.results[n].values; -#ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER +#ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER_SEGMENT std::cerr << "chunk for segment " << segmentStart << ": from " << chunk.time << ", duration " << chunk.duration << std::endl; #endif @@ -610,20 +675,6 @@ } } } - - - -/* - if (boundaryitr == m_boundaries.end()) { - m_segmentedAccumulators[output][segmentStart] = source; - source.clear(); - continue; - } -*/ - - - - } struct ValueDurationFloatPair @@ -677,6 +728,7 @@ #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER std::cerr << "last time = " << accumulator.results[sz-1].time << ", duration = " << accumulator.results[sz-1].duration + << " (step = " << m_stepSize << ", block = " << m_blockSize << ")" << std::endl; #endif totalDuration = toSec((accumulator.results[sz-1].time + @@ -733,11 +785,13 @@ #endif #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER +/* std::cerr << "value vector for medians:" << std::endl; for (int k = 0; k < sz; ++k) { std::cerr << "(" << valvec[k].value << "," << valvec[k].duration << ") "; } std::cerr << std::endl; +*/ #endif if (sz % 2 == 1) { @@ -818,16 +872,18 @@ summary.mean_c = sum_c / totalDuration; for (int k = 0; k < sz; ++k) { - double value = accumulator.results[k].values[bin] + double value = accumulator.results[k].values[bin]; +// * toSec(accumulator.results[k].duration); + summary.variance_c += + (value - summary.mean_c) * (value - summary.mean_c) * toSec(accumulator.results[k].duration); - summary.variance_c += - (value - summary.mean_c) * (value - summary.mean_c); } - summary.variance_c /= summary.count; +// summary.variance_c /= summary.count; + summary.variance_c /= totalDuration; } - float mean = summary.sum / summary.count; + double mean = summary.sum / summary.count; #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER std::cerr << "mean = " << summary.sum << " / " << summary.count << " = " diff -r 27cfae2a4155 -r 1e4c6f25ded6 vamp-sdk/hostext/PluginSummarisingAdapter.h --- a/vamp-sdk/hostext/PluginSummarisingAdapter.h Tue Sep 30 13:24:41 2008 +0000 +++ b/vamp-sdk/hostext/PluginSummarisingAdapter.h Tue Oct 07 16:57:10 2008 +0000 @@ -51,15 +51,7 @@ PluginSummarisingAdapter(Plugin *plugin); // I take ownership of plugin virtual ~PluginSummarisingAdapter(); - //!!! perhaps it should return the summaries as if they were the - //!!! original features? if so, it will need to be told in - //!!! advance which summaries you want. and that won't work if - //!!! you want more than one. so, probably, no. - - //!!! however, it is useful to have results in the same FeatureSet - //!!! structure as the original results -- rather than a single - //!!! FeatureList. perhaps even useful to get a summary for all - //!!! outputs? + bool initialise(size_t channels, size_t stepSize, size_t blockSize); FeatureSet process(const float *const *inputBuffers, RealTime timestamp); FeatureSet getRemainingFeatures();