Mercurial > hg > vamp-plugin-sdk
comparison vamp-sdk/hostext/PluginSummarisingAdapter.cpp @ 194:27cfae2a4155
* Make summarising adapter debug optional
* Tidy up template generator output a bit
* Clarify an error message
author | cannam |
---|---|
date | Tue, 30 Sep 2008 13:24:41 +0000 |
parents | d1bdcd4a226f |
children | 1e4c6f25ded6 |
comparison
equal
deleted
inserted
replaced
193:20393d30baee | 194:27cfae2a4155 |
---|---|
38 | 38 |
39 #include <map> | 39 #include <map> |
40 #include <cmath> | 40 #include <cmath> |
41 #include <climits> | 41 #include <climits> |
42 | 42 |
43 //#define DEBUG_PLUGIN_SUMMARISING_ADAPTER 1 | |
44 | |
43 namespace Vamp { | 45 namespace Vamp { |
44 | 46 |
45 namespace HostExt { | 47 namespace HostExt { |
46 | 48 |
47 class PluginSummarisingAdapter::Impl | 49 class PluginSummarisingAdapter::Impl |
216 | 218 |
217 void | 219 void |
218 PluginSummarisingAdapter::Impl::setSummarySegmentBoundaries(const SegmentBoundaries &b) | 220 PluginSummarisingAdapter::Impl::setSummarySegmentBoundaries(const SegmentBoundaries &b) |
219 { | 221 { |
220 m_boundaries = b; | 222 m_boundaries = b; |
223 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER | |
221 std::cerr << "PluginSummarisingAdapter::setSummarySegmentBoundaries: boundaries are:" << std::endl; | 224 std::cerr << "PluginSummarisingAdapter::setSummarySegmentBoundaries: boundaries are:" << std::endl; |
222 for (SegmentBoundaries::const_iterator i = m_boundaries.begin(); | 225 for (SegmentBoundaries::const_iterator i = m_boundaries.begin(); |
223 i != m_boundaries.end(); ++i) { | 226 i != m_boundaries.end(); ++i) { |
224 std::cerr << *i << " "; | 227 std::cerr << *i << " "; |
225 } | 228 } |
226 std::cerr << std::endl; | 229 std::cerr << std::endl; |
230 #endif | |
227 } | 231 } |
228 | 232 |
229 Plugin::FeatureList | 233 Plugin::FeatureList |
230 PluginSummarisingAdapter::Impl::getSummaryForOutput(int output, | 234 PluginSummarisingAdapter::Impl::getSummaryForOutput(int output, |
231 SummaryType type, | 235 SummaryType type, |
379 // need a separate phase to split the accumulator up into segments). | 383 // need a separate phase to split the accumulator up into segments). |
380 // If features spanning a boundary should be counted only in the first | 384 // If features spanning a boundary should be counted only in the first |
381 // segment, with their full duration, then we should store them in a | 385 // segment, with their full duration, then we should store them in a |
382 // single accumulator and distribute into segments only on reduce. | 386 // single accumulator and distribute into segments only on reduce. |
383 | 387 |
388 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER | |
384 std::cerr << "output " << output << ": timestamp " << timestamp << ", prev timestamp " << m_prevTimestamps[output] << ", final " << final << std::endl; | 389 std::cerr << "output " << output << ": timestamp " << timestamp << ", prev timestamp " << m_prevTimestamps[output] << ", final " << final << std::endl; |
390 #endif | |
385 | 391 |
386 // At each process step, accumulate() is called once for each | 392 // At each process step, accumulate() is called once for each |
387 // feature on each output within that process's returned feature | 393 // feature on each output within that process's returned feature |
388 // list, and with the timestamp passed in being that of the start | 394 // list, and with the timestamp passed in being that of the start |
389 // of the process block. | 395 // of the process block. |
418 // will have to calculate the duration from the previous and | 424 // will have to calculate the duration from the previous and |
419 // current timestamps. | 425 // current timestamps. |
420 | 426 |
421 if (m_prevDurations[output] != INVALID_DURATION) { | 427 if (m_prevDurations[output] != INVALID_DURATION) { |
422 prevDuration = m_prevDurations[output]; | 428 prevDuration = m_prevDurations[output]; |
429 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER | |
423 std::cerr << "Previous duration from previous feature: " << prevDuration << std::endl; | 430 std::cerr << "Previous duration from previous feature: " << prevDuration << std::endl; |
431 #endif | |
424 } else { | 432 } else { |
425 prevDuration = timestamp - m_prevTimestamps[output]; | 433 prevDuration = timestamp - m_prevTimestamps[output]; |
434 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER | |
426 std::cerr << "Previous duration from diff: " << timestamp << " - " | 435 std::cerr << "Previous duration from diff: " << timestamp << " - " |
427 << m_prevTimestamps[output] << std::endl; | 436 << m_prevTimestamps[output] << std::endl; |
437 #endif | |
428 } | 438 } |
429 | 439 |
440 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER | |
430 std::cerr << "output " << output << ": "; | 441 std::cerr << "output " << output << ": "; |
431 | |
432 std::cerr << "Pushing previous duration as " << prevDuration << std::endl; | 442 std::cerr << "Pushing previous duration as " << prevDuration << std::endl; |
443 #endif | |
433 | 444 |
434 m_accumulators[output].results | 445 m_accumulators[output].results |
435 [m_accumulators[output].results.size() - 1] | 446 [m_accumulators[output].results.size() - 1] |
436 .duration = prevDuration; | 447 .duration = prevDuration; |
437 } | 448 } |
471 | 482 |
472 if (acount == 0) continue; | 483 if (acount == 0) continue; |
473 | 484 |
474 RealTime prevTimestamp = i->second; | 485 RealTime prevTimestamp = i->second; |
475 | 486 |
487 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER | |
476 std::cerr << "output " << output << ": "; | 488 std::cerr << "output " << output << ": "; |
489 #endif | |
477 | 490 |
478 if (m_prevDurations.find(output) != m_prevDurations.end() && | 491 if (m_prevDurations.find(output) != m_prevDurations.end() && |
479 m_prevDurations[output] != INVALID_DURATION) { | 492 m_prevDurations[output] != INVALID_DURATION) { |
480 | 493 |
494 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER | |
481 std::cerr << "Pushing final duration from feature as " << m_prevDurations[output] << std::endl; | 495 std::cerr << "Pushing final duration from feature as " << m_prevDurations[output] << std::endl; |
496 #endif | |
482 | 497 |
483 m_accumulators[output].results[acount - 1].duration = | 498 m_accumulators[output].results[acount - 1].duration = |
484 m_prevDurations[output]; | 499 m_prevDurations[output]; |
485 | 500 |
486 } else { | 501 } else { |
487 | 502 |
503 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER | |
488 std::cerr << "Pushing final duration from diff as " << m_lastTimestamp << " - " << m_prevTimestamps[output] << std::endl; | 504 std::cerr << "Pushing final duration from diff as " << m_lastTimestamp << " - " << m_prevTimestamps[output] << std::endl; |
505 #endif | |
489 | 506 |
490 m_accumulators[output].results[acount - 1].duration = | 507 m_accumulators[output].results[acount - 1].duration = |
491 m_lastTimestamp - m_prevTimestamps[output]; | 508 m_lastTimestamp - m_prevTimestamps[output]; |
492 } | 509 } |
493 | 510 |
511 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER | |
494 std::cerr << "so duration for result no " << acount-1 << " is " | 512 std::cerr << "so duration for result no " << acount-1 << " is " |
495 << m_accumulators[output].results[acount-1].duration | 513 << m_accumulators[output].results[acount-1].duration |
496 << std::endl; | 514 << std::endl; |
515 #endif | |
497 } | 516 } |
498 } | 517 } |
499 | 518 |
500 void | 519 void |
501 PluginSummarisingAdapter::Impl::findSegmentBounds(RealTime t, | 520 PluginSummarisingAdapter::Impl::findSegmentBounds(RealTime t, |
502 RealTime &start, | 521 RealTime &start, |
503 RealTime &end) | 522 RealTime &end) |
504 { | 523 { |
524 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER | |
505 std::cerr << "findSegmentBounds: t = " << t << std::endl; | 525 std::cerr << "findSegmentBounds: t = " << t << std::endl; |
526 #endif | |
506 | 527 |
507 SegmentBoundaries::const_iterator i = std::upper_bound | 528 SegmentBoundaries::const_iterator i = std::upper_bound |
508 (m_boundaries.begin(), m_boundaries.end(), t); | 529 (m_boundaries.begin(), m_boundaries.end(), t); |
509 | 530 |
510 start = RealTime::zeroTime; | 531 start = RealTime::zeroTime; |
515 } | 536 } |
516 | 537 |
517 if (i != m_boundaries.begin()) { | 538 if (i != m_boundaries.begin()) { |
518 start = *--i; | 539 start = *--i; |
519 } | 540 } |
520 | 541 |
542 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER | |
521 std::cerr << "findSegmentBounds: " << t << " is in segment " << start << " -> " << end << std::endl; | 543 std::cerr << "findSegmentBounds: " << t << " is in segment " << start << " -> " << end << std::endl; |
544 #endif | |
522 } | 545 } |
523 | 546 |
524 void | 547 void |
525 PluginSummarisingAdapter::Impl::segment() | 548 PluginSummarisingAdapter::Impl::segment() |
526 { | 549 { |
531 i != m_accumulators.end(); ++i) { | 554 i != m_accumulators.end(); ++i) { |
532 | 555 |
533 int output = i->first; | 556 int output = i->first; |
534 OutputAccumulator &source = i->second; | 557 OutputAccumulator &source = i->second; |
535 | 558 |
559 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER | |
536 std::cerr << "segment: total results for output " << output << " = " | 560 std::cerr << "segment: total results for output " << output << " = " |
537 << source.results.size() << std::endl; | 561 << source.results.size() << std::endl; |
562 #endif | |
538 | 563 |
539 //!!! This is basically nonsense if the results have no values | 564 //!!! This is basically nonsense if the results have no values |
540 //!!! (i.e. their times and counts are the only things of | 565 //!!! (i.e. their times and counts are the only things of |
541 //!!! interest) but perhaps it's the user's problem if they | 566 //!!! interest) but perhaps it's the user's problem if they |
542 //!!! ask for segmentation in that case | 567 //!!! ask for segmentation in that case |
548 // We need to dispose it into segments appropriately | 573 // We need to dispose it into segments appropriately |
549 | 574 |
550 RealTime resultStart = source.results[n].time; | 575 RealTime resultStart = source.results[n].time; |
551 RealTime resultEnd = resultStart + source.results[n].duration; | 576 RealTime resultEnd = resultStart + source.results[n].duration; |
552 | 577 |
578 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER | |
553 std::cerr << "output: " << output << ", result start = " << resultStart << ", end = " << resultEnd << std::endl; | 579 std::cerr << "output: " << output << ", result start = " << resultStart << ", end = " << resultEnd << std::endl; |
580 #endif | |
554 | 581 |
555 RealTime segmentStart = RealTime::zeroTime; | 582 RealTime segmentStart = RealTime::zeroTime; |
556 RealTime segmentEnd = resultEnd - RealTime(1, 0); | 583 RealTime segmentEnd = resultEnd - RealTime(1, 0); |
557 | 584 |
558 while (segmentEnd < resultEnd) { | 585 while (segmentEnd < resultEnd) { |
570 Result chunk; | 597 Result chunk; |
571 chunk.time = chunkStart; | 598 chunk.time = chunkStart; |
572 chunk.duration = chunkEnd - chunkStart; | 599 chunk.duration = chunkEnd - chunkStart; |
573 chunk.values = source.results[n].values; | 600 chunk.values = source.results[n].values; |
574 | 601 |
602 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER | |
575 std::cerr << "chunk for segment " << segmentStart << ": from " << chunk.time << ", duration " << chunk.duration << std::endl; | 603 std::cerr << "chunk for segment " << segmentStart << ": from " << chunk.time << ", duration " << chunk.duration << std::endl; |
604 #endif | |
576 | 605 |
577 m_segmentedAccumulators[output][segmentStart].results | 606 m_segmentedAccumulators[output][segmentStart].results |
578 .push_back(chunk); | 607 .push_back(chunk); |
579 | 608 |
580 resultStart = chunkEnd; | 609 resultStart = chunkEnd; |
635 RealTime segmentStart = j->first; | 664 RealTime segmentStart = j->first; |
636 OutputAccumulator &accumulator = j->second; | 665 OutputAccumulator &accumulator = j->second; |
637 | 666 |
638 int sz = accumulator.results.size(); | 667 int sz = accumulator.results.size(); |
639 | 668 |
669 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER | |
640 std::cerr << "reduce: segment starting at " << segmentStart | 670 std::cerr << "reduce: segment starting at " << segmentStart |
641 << " on output " << output << " has " << sz << " result(s)" << std::endl; | 671 << " on output " << output << " has " << sz << " result(s)" << std::endl; |
672 #endif | |
642 | 673 |
643 double totalDuration = 0.0; | 674 double totalDuration = 0.0; |
644 //!!! is this right? | 675 //!!! is this right? |
645 if (sz > 0) { | 676 if (sz > 0) { |
677 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER | |
646 std::cerr << "last time = " << accumulator.results[sz-1].time | 678 std::cerr << "last time = " << accumulator.results[sz-1].time |
647 << ", duration = " << accumulator.results[sz-1].duration | 679 << ", duration = " << accumulator.results[sz-1].duration |
648 << std::endl; | 680 << std::endl; |
681 #endif | |
649 totalDuration = toSec((accumulator.results[sz-1].time + | 682 totalDuration = toSec((accumulator.results[sz-1].time + |
650 accumulator.results[sz-1].duration) - | 683 accumulator.results[sz-1].duration) - |
651 segmentStart); | 684 segmentStart); |
652 } | 685 } |
653 | 686 |
693 std::sort(valvec.begin(), valvec.end()); | 726 std::sort(valvec.begin(), valvec.end()); |
694 | 727 |
695 summary.minimum = valvec[0].value; | 728 summary.minimum = valvec[0].value; |
696 summary.maximum = valvec[sz-1].value; | 729 summary.maximum = valvec[sz-1].value; |
697 | 730 |
731 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER | |
698 std::cerr << "total duration = " << totalDuration << std::endl; | 732 std::cerr << "total duration = " << totalDuration << std::endl; |
699 | 733 #endif |
734 | |
735 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER | |
700 std::cerr << "value vector for medians:" << std::endl; | 736 std::cerr << "value vector for medians:" << std::endl; |
701 for (int k = 0; k < sz; ++k) { | 737 for (int k = 0; k < sz; ++k) { |
702 std::cerr << "(" << valvec[k].value << "," << valvec[k].duration << ") "; | 738 std::cerr << "(" << valvec[k].value << "," << valvec[k].duration << ") "; |
703 } | 739 } |
704 std::cerr << std::endl; | 740 std::cerr << std::endl; |
741 #endif | |
705 | 742 |
706 if (sz % 2 == 1) { | 743 if (sz % 2 == 1) { |
707 summary.median = valvec[sz/2].value; | 744 summary.median = valvec[sz/2].value; |
708 } else { | 745 } else { |
709 summary.median = (valvec[sz/2].value + valvec[sz/2 + 1].value) / 2; | 746 summary.median = (valvec[sz/2].value + valvec[sz/2 + 1].value) / 2; |
718 summary.median_c = valvec[k].value; | 755 summary.median_c = valvec[k].value; |
719 break; | 756 break; |
720 } | 757 } |
721 } | 758 } |
722 | 759 |
760 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER | |
723 std::cerr << "median_c = " << summary.median_c << std::endl; | 761 std::cerr << "median_c = " << summary.median_c << std::endl; |
724 std::cerr << "median = " << summary.median << std::endl; | 762 std::cerr << "median = " << summary.median << std::endl; |
763 #endif | |
725 | 764 |
726 std::map<float, int> distribution; | 765 std::map<float, int> distribution; |
727 | 766 |
728 for (int k = 0; k < sz; ++k) { | 767 for (int k = 0; k < sz; ++k) { |
729 summary.sum += accumulator.results[k].values[bin]; | 768 summary.sum += accumulator.results[k].values[bin]; |
769 double value = accumulator.results[k].values[bin] | 808 double value = accumulator.results[k].values[bin] |
770 * toSec(accumulator.results[k].duration); | 809 * toSec(accumulator.results[k].duration); |
771 sum_c += value; | 810 sum_c += value; |
772 } | 811 } |
773 | 812 |
813 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER | |
774 std::cerr << "mean_c = " << sum_c << " / " << totalDuration << " = " | 814 std::cerr << "mean_c = " << sum_c << " / " << totalDuration << " = " |
775 << sum_c / totalDuration << " (sz = " << sz << ")" << std::endl; | 815 << sum_c / totalDuration << " (sz = " << sz << ")" << std::endl; |
816 #endif | |
776 | 817 |
777 summary.mean_c = sum_c / totalDuration; | 818 summary.mean_c = sum_c / totalDuration; |
778 | 819 |
779 for (int k = 0; k < sz; ++k) { | 820 for (int k = 0; k < sz; ++k) { |
780 double value = accumulator.results[k].values[bin] | 821 double value = accumulator.results[k].values[bin] |
786 summary.variance_c /= summary.count; | 827 summary.variance_c /= summary.count; |
787 } | 828 } |
788 | 829 |
789 float mean = summary.sum / summary.count; | 830 float mean = summary.sum / summary.count; |
790 | 831 |
832 #ifdef DEBUG_PLUGIN_SUMMARISING_ADAPTER | |
791 std::cerr << "mean = " << summary.sum << " / " << summary.count << " = " | 833 std::cerr << "mean = " << summary.sum << " / " << summary.count << " = " |
792 << summary.sum / summary.count << std::endl; | 834 << summary.sum / summary.count << std::endl; |
835 #endif | |
793 | 836 |
794 for (int k = 0; k < sz; ++k) { | 837 for (int k = 0; k < sz; ++k) { |
795 float value = accumulator.results[k].values[bin]; | 838 float value = accumulator.results[k].values[bin]; |
796 summary.variance += (value - mean) * (value - mean); | 839 summary.variance += (value - mean) * (value - mean); |
797 } | 840 } |