Mercurial > hg > vamp-plugin-sdk
comparison vamp-sdk/hostext/PluginSummarisingAdapter.cpp @ 184:26c200c3fc42
* Fixes to summarisation (calculation of durations)
author | cannam |
---|---|
date | Wed, 10 Sep 2008 14:54:25 +0000 |
parents | c053ababbf7e |
children | 701505ac170c |
comparison
equal
deleted
inserted
replaced
183:c053ababbf7e | 184:26c200c3fc42 |
---|---|
36 | 36 |
37 #include "PluginSummarisingAdapter.h" | 37 #include "PluginSummarisingAdapter.h" |
38 | 38 |
39 #include <map> | 39 #include <map> |
40 #include <cmath> | 40 #include <cmath> |
41 #include <climits> | |
41 | 42 |
42 namespace Vamp { | 43 namespace Vamp { |
43 | 44 |
44 namespace HostExt { | 45 namespace HostExt { |
45 | 46 |
115 bool m_reduced; | 116 bool m_reduced; |
116 RealTime m_lastTimestamp; | 117 RealTime m_lastTimestamp; |
117 | 118 |
118 void accumulate(const FeatureSet &fs, RealTime, bool final); | 119 void accumulate(const FeatureSet &fs, RealTime, bool final); |
119 void accumulate(int output, const Feature &f, RealTime, bool final); | 120 void accumulate(int output, const Feature &f, RealTime, bool final); |
121 void accumulateFinalDurations(); | |
120 void reduce(); | 122 void reduce(); |
121 }; | 123 }; |
124 | |
125 static RealTime INVALID_DURATION(INT_MIN, INT_MIN); | |
122 | 126 |
123 PluginSummarisingAdapter::PluginSummarisingAdapter(Plugin *plugin) : | 127 PluginSummarisingAdapter::PluginSummarisingAdapter(Plugin *plugin) : |
124 PluginWrapper(plugin) | 128 PluginWrapper(plugin) |
125 { | 129 { |
126 m_impl = new Impl(plugin, m_inputSampleRate); | 130 m_impl = new Impl(plugin, m_inputSampleRate); |
318 { | 322 { |
319 //!!! to do: use timestamp to determine which segment we're on | 323 //!!! to do: use timestamp to determine which segment we're on |
320 | 324 |
321 m_accumulators[output].count++; | 325 m_accumulators[output].count++; |
322 | 326 |
323 std::cerr << "output " << output << ": timestamp " << timestamp << ", prev timestamp " << m_prevTimestamps[output] << std::endl; | 327 std::cerr << "output " << output << ": timestamp " << timestamp << ", prev timestamp " << m_prevTimestamps[output] << ", final " << final << std::endl; |
324 | 328 |
325 //!!! also, this will not work if we are called repeatedly with | 329 // At each process step, accumulate() is called once for each |
326 //!!! the same timestamp -- no values will be registered until a | 330 // feature on each output within that process's returned feature |
327 //!!! new timestamp is seen -- we need a better test for "not | 331 // list, and with the timestamp passed in being that of the start |
328 //!!! first result" below | 332 // of the process block. |
329 | 333 |
330 if (m_prevDurations[output] == RealTime::zeroTime) { | 334 // At the end (in getRemainingFeatures), accumulate() is called |
331 if (m_prevTimestamps.find(output) != m_prevTimestamps.end()) { | 335 // once for each feature on each output within the feature list |
332 m_prevDurations[output] = timestamp - m_prevTimestamps[output]; | 336 // returned by getRemainingFeatures, and with the timestamp being |
337 // the same as the last process block and final set to true. | |
338 | |
339 // (What if getRemainingFeatures doesn't return any features? We | |
340 // still need to ensure that the final duration is written. Need | |
341 // a separate function to close the durations.) | |
342 | |
343 // At each call, we pull out the value for the feature and stuff | |
344 // it into the accumulator's appropriate values array; and we | |
345 // calculate the duration for the _previous_ feature, or pull it | |
346 // from the prevDurations array if the previous feature had a | |
347 // duration in its structure, and stuff that into the | |
348 // accumulator's appropriate durations array. | |
349 | |
350 if (m_prevDurations.find(output) != m_prevDurations.end()) { | |
351 | |
352 // Not the first time accumulate has been called for this | |
353 // output -- there has been a previous feature | |
354 | |
355 RealTime prevDuration; | |
356 | |
357 // Note that m_prevDurations[output] only contains the | |
358 // duration field that was contained in the previous feature. | |
359 // If it didn't have an explicit duration, | |
360 // m_prevDurations[output] should be INVALID_DURATION and we | |
361 // will have to calculate the duration from the previous and | |
362 // current timestamps. | |
363 | |
364 if (m_prevDurations[output] != INVALID_DURATION) { | |
365 prevDuration = m_prevDurations[output]; | |
366 std::cerr << "Previous duration from previous feature: " << prevDuration << std::endl; | |
367 } else { | |
368 prevDuration = timestamp - m_prevTimestamps[output]; | |
369 std::cerr << "Previous duration from diff: " << timestamp << " - " | |
370 << m_prevTimestamps[output] << std::endl; | |
333 } | 371 } |
334 } | 372 |
335 if (m_prevDurations[output] != RealTime::zeroTime || | 373 std::cerr << "output " << output << ": "; |
336 !m_accumulators[output].durations.empty()) { | 374 |
337 // ... i.e. if not first result. We don't push a duration | 375 std::cerr << "Pushing previous duration as " << prevDuration << std::endl; |
338 // when we process the first result; then the duration we push | 376 m_accumulators[output].durations.push_back(prevDuration); |
339 // each time is that for the result before the one we're | 377 } |
340 // processing, and we push an extra one at the end. This | 378 |
341 // permits handling the case where the feature itself doesn't | 379 if (f.hasDuration) m_prevDurations[output] = f.duration; |
342 // have a duration field, and we have to calculate it from the | 380 else m_prevDurations[output] = INVALID_DURATION; |
343 // time to the following feature. The net effect is simply | |
344 // that values[n] and durations[n] refer to the same result. | |
345 m_accumulators[output].durations.push_back(m_prevDurations[output]); | |
346 } | |
347 | 381 |
348 m_prevTimestamps[output] = timestamp; | 382 m_prevTimestamps[output] = timestamp; |
383 if (timestamp > m_lastTimestamp) m_lastTimestamp = timestamp; | |
349 | 384 |
350 for (int i = 0; i < int(f.values.size()); ++i) { | 385 for (int i = 0; i < int(f.values.size()); ++i) { |
351 m_accumulators[output].values[i].push_back(f.values[i]); | 386 m_accumulators[output].values[i].push_back(f.values[i]); |
352 } | 387 } |
353 | 388 } |
354 if (final) { | 389 |
355 RealTime finalDuration; | 390 void |
356 if (f.hasDuration) finalDuration = f.duration; | 391 PluginSummarisingAdapter::Impl::accumulateFinalDurations() |
357 m_accumulators[output].durations.push_back(finalDuration); | 392 { |
358 } | 393 for (OutputTimestampMap::iterator i = m_prevTimestamps.begin(); |
359 | 394 i != m_prevTimestamps.end(); ++i) { |
360 if (f.hasDuration) m_prevDurations[output] = f.duration; | 395 |
361 else m_prevDurations[output] = RealTime::zeroTime; | 396 int output = i->first; |
397 RealTime prevTimestamp = i->second; | |
398 | |
399 std::cerr << "output " << output << ": "; | |
400 | |
401 if (m_prevDurations.find(output) != m_prevDurations.end() && | |
402 m_prevDurations[output] != INVALID_DURATION) { | |
403 | |
404 std::cerr << "Pushing final duration from feature as " << m_prevDurations[output] << std::endl; | |
405 | |
406 m_accumulators[output].durations.push_back(m_prevDurations[output]); | |
407 | |
408 } else { | |
409 | |
410 std::cerr << "Pushing final duration from diff as " << m_lastTimestamp << " - " << m_prevTimestamps[output] << std::endl; | |
411 | |
412 m_accumulators[output].durations.push_back | |
413 (m_lastTimestamp - m_prevTimestamps[output]); | |
414 } | |
415 } | |
362 } | 416 } |
363 | 417 |
364 struct ValueDurationFloatPair | 418 struct ValueDurationFloatPair |
365 { | 419 { |
366 float value; | 420 float value; |
384 } | 438 } |
385 | 439 |
386 void | 440 void |
387 PluginSummarisingAdapter::Impl::reduce() | 441 PluginSummarisingAdapter::Impl::reduce() |
388 { | 442 { |
443 accumulateFinalDurations(); | |
444 | |
389 RealTime segmentStart = RealTime::zeroTime; //!!! | 445 RealTime segmentStart = RealTime::zeroTime; //!!! |
390 | 446 |
391 for (OutputAccumulatorMap::iterator i = m_accumulators.begin(); | 447 for (OutputAccumulatorMap::iterator i = m_accumulators.begin(); |
392 i != m_accumulators.end(); ++i) { | 448 i != m_accumulators.end(); ++i) { |
393 | 449 |
515 double value = values[k] * toSec(durations[k]); | 571 double value = values[k] * toSec(durations[k]); |
516 sum_c += value; | 572 sum_c += value; |
517 } | 573 } |
518 | 574 |
519 std::cerr << "mean_c = " << sum_c << " / " << totalDuration << " = " | 575 std::cerr << "mean_c = " << sum_c << " / " << totalDuration << " = " |
520 << sum_c / totalDuration << std::endl; | 576 << sum_c / totalDuration << " (sz = " << sz << ")" << std::endl; |
521 | 577 |
522 summary.mean_c = sum_c / totalDuration; | 578 summary.mean_c = sum_c / totalDuration; |
523 | 579 |
524 for (int k = 0; k < sz; ++k) { | 580 for (int k = 0; k < sz; ++k) { |
525 double value = values[k] * toSec(durations[k]); | 581 double value = values[k] * toSec(durations[k]); |