comparison layer/WaveformLayer.cpp @ 1333:59f6830be8d8 zoom

A further refactor with range blocks
author Chris Cannam
date Fri, 21 Sep 2018 14:22:53 +0100
parents 6dac67c3ed82
children 0e4551fd7f14
comparison
equal deleted inserted replaced
1332:6dac67c3ed82 1333:59f6830be8d8
31 #include <iostream> 31 #include <iostream>
32 #include <cmath> 32 #include <cmath>
33 33
34 //#define DEBUG_WAVEFORM_PAINT 1 34 //#define DEBUG_WAVEFORM_PAINT 1
35 35
36 36 using std::vector;
37 37
38 38
39 WaveformLayer::WaveformLayer() : 39 WaveformLayer::WaveformLayer() :
40 SingleColourLayer(), 40 SingleColourLayer(),
41 m_model(0), 41 m_model(0),
588 588
589 #ifdef DEBUG_WAVEFORM_PAINT 589 #ifdef DEBUG_WAVEFORM_PAINT
590 cerr << "Painting waveform from " << frame0 << " to " << frame1 << " (" << (x1-x0+1) << " pixels at zoom " << zoomLevel << " and model zoom " << blockSize << ")" << endl; 590 cerr << "Painting waveform from " << frame0 << " to " << frame1 << " (" << (x1-x0+1) << " pixels at zoom " << zoomLevel << " and model zoom " << blockSize << ")" << endl;
591 #endif 591 #endif
592 592
593 RangeSummarisableTimeValueModel::RangeBlock *ranges =
594 new RangeSummarisableTimeValueModel::RangeBlock;
595
596 RangeSummarisableTimeValueModel::RangeBlock *otherChannelRanges = 0;
597
598 while ((int)m_effectiveGains.size() <= maxChannel) { 593 while ((int)m_effectiveGains.size() <= maxChannel) {
599 m_effectiveGains.push_back(m_gain); 594 m_effectiveGains.push_back(m_gain);
600 } 595 }
601 596
597 vector<RangeSummarisableTimeValueModel::RangeBlock> ranges;
598
602 for (int ch = minChannel; ch <= maxChannel; ++ch) { 599 for (int ch = minChannel; ch <= maxChannel; ++ch) {
603 600 ranges.push_back({});
604 m_model->getSummaries(ch, frame0, frame1 - frame0, 601 m_model->getSummaries(ch, frame0, frame1 - frame0,
605 *ranges, blockSize); 602 ranges[ch - minChannel], blockSize);
606
607 #ifdef DEBUG_WAVEFORM_PAINT 603 #ifdef DEBUG_WAVEFORM_PAINT
608 cerr << "channel " << ch << ": " << ranges->size() << " ranges from " << frame0 << " to " << frame1 << " at zoom level " << blockSize << endl; 604 cerr << "channel " << ch << ": " << ranges[ch - minChannel].size() << " ranges from " << frame0 << " to " << frame1 << " at zoom level " << blockSize << endl;
609 #endif 605 #endif
610 606 }
611 if (mergingChannels || mixingChannels) { 607
612 if (m_model->getChannelCount() > 1) { 608 if (mergingChannels || mixingChannels) {
613 if (!otherChannelRanges) { 609 if (minChannel != 0 || maxChannel != 0) {
614 otherChannelRanges = 610 SVCERR << "Internal error: min & max channels should be 0 when merging or mixing all channels" << endl;
615 new RangeSummarisableTimeValueModel::RangeBlock; 611 } else if (m_model->getChannelCount() > 1) {
616 } 612 ranges.push_back({});
617 m_model->getSummaries 613 m_model->getSummaries
618 (1, frame0, frame1 - frame0, *otherChannelRanges, 614 (1, frame0, frame1 - frame0, ranges[1], blockSize);
619 blockSize); 615 }
620 } else { 616 }
621 if (otherChannelRanges != ranges) delete otherChannelRanges; 617
622 otherChannelRanges = ranges; 618 for (int ch = minChannel; ch <= maxChannel; ++ch) {
623 } 619 paintChannel(v, paint, ch, ranges,
624 }
625
626 paintChannel(v, paint, ch, ranges, otherChannelRanges,
627 blockSize, x0, y0, x1, y1, frame0, frame1); 620 blockSize, x0, y0, x1, y1, frame0, frame1);
628 } 621 }
629 622
630 if (m_middleLineHeight != 0.5) { 623 if (m_middleLineHeight != 0.5) {
631 paint->restore(); 624 paint->restore();
632 } 625 }
633 626
634 if (m_aggressive) { 627 if (m_aggressive) {
635
636 if (m_model->isReady() && rect == v->getPaintRect()) { 628 if (m_model->isReady() && rect == v->getPaintRect()) {
637 m_cacheValid = true; 629 m_cacheValid = true;
638 m_cacheZoomLevel = zoomLevel; 630 m_cacheZoomLevel = zoomLevel;
639 } 631 }
640 paint->end(); 632 paint->end();
641 delete paint; 633 delete paint;
642 viewPainter.drawPixmap(rect, *m_cache, rect); 634 viewPainter.drawPixmap(rect, *m_cache, rect);
643 } 635 }
644
645 if (otherChannelRanges != ranges) delete otherChannelRanges;
646 delete ranges;
647 } 636 }
648 637
649 void 638 void
650 WaveformLayer::paintChannel(LayerGeometryProvider *v, QPainter *paint, int ch, 639 WaveformLayer::paintChannel(LayerGeometryProvider *v, QPainter *paint, int ch,
651 const RangeSummarisableTimeValueModel::RangeBlock *ranges, 640 const vector<RangeSummarisableTimeValueModel::RangeBlock> &ranges,
652 const RangeSummarisableTimeValueModel::RangeBlock *otherChannelRanges,
653 int blockSize, int x0, int y0, int x1, int y1, 641 int blockSize, int x0, int y0, int x1, int y1,
654 sv_frame_t frame0, sv_frame_t frame1) 642 sv_frame_t frame0, sv_frame_t frame1)
655 const 643 const
656 { 644 {
657 int w = v->getPaintWidth(); 645 int w = v->getPaintWidth();
663 channels = getChannelArrangement(minChannel, maxChannel, 651 channels = getChannelArrangement(minChannel, maxChannel,
664 mergingChannels, mixingChannels); 652 mergingChannels, mixingChannels);
665 if (channels == 0) return; 653 if (channels == 0) return;
666 654
667 QColor baseColour = getBaseQColor(); 655 QColor baseColour = getBaseQColor();
668 std::vector<QColor> greys = getPartialShades(v); 656 vector<QColor> greys = getPartialShades(v);
669 657
670 QColor midColour = baseColour; 658 QColor midColour = baseColour;
671 if (midColour == Qt::black) { 659 if (midColour == Qt::black) {
672 midColour = Qt::gray; 660 midColour = Qt::gray;
673 } else if (v->hasLightBackground()) { 661 } else if (v->hasLightBackground()) {
751 paint->drawLine(x0, ny, x1, ny); 739 paint->drawLine(x0, ny, x1, ny);
752 } 740 }
753 } 741 }
754 } 742 }
755 743
744 int rangeix = ch - minChannel;
745
756 for (int x = x0; x <= x1; ++x) { 746 for (int x = x0; x <= x1; ++x) {
757
758 RangeSummarisableTimeValueModel::Range range;
759 747
760 sv_frame_t f0, f1; 748 sv_frame_t f0, f1;
761 if (!getSourceFramesForX(v, x, blockSize, f0, f1)) continue; 749 if (!getSourceFramesForX(v, x, blockSize, f0, f1)) continue;
762 f1 = f1 - 1; 750 f1 = f1 - 1;
763 751
775 763
776 if (i1 > i0 + 1) { 764 if (i1 > i0 + 1) {
777 cerr << "WaveformLayer::paint: ERROR: i1 " << i1 << " > i0 " << i0 << " plus one (zoom = " << v->getZoomLevel() << ", model zoom = " << blockSize << ")" << endl; 765 cerr << "WaveformLayer::paint: ERROR: i1 " << i1 << " > i0 " << i0 << " plus one (zoom = " << v->getZoomLevel() << ", model zoom = " << blockSize << ")" << endl;
778 } 766 }
779 767
780 if (ranges && i0 < (sv_frame_t)ranges->size()) { 768 const auto &r = ranges[rangeix];
781 769 RangeSummarisableTimeValueModel::Range range;
782 range = (*ranges)[size_t(i0)]; 770
783 771 if (in_range_for(r, i0)) {
784 if (i1 > i0 && i1 < (int)ranges->size()) { 772
785 range.setMax(std::max(range.max(), 773 range = r[i0];
786 (*ranges)[size_t(i1)].max())); 774
787 range.setMin(std::min(range.min(), 775 if (i1 > i0 && in_range_for(r, i1)) {
788 (*ranges)[size_t(i1)].min())); 776 range.setMax(std::max(range.max(), r[i1].max()));
789 range.setAbsmean((range.absmean() 777 range.setMin(std::min(range.min(), r[i1].min()));
790 + (*ranges)[size_t(i1)].absmean()) / 2); 778 range.setAbsmean((range.absmean() + r[i1].absmean()) / 2);
791 } 779 }
792 780
793 } else { 781 } else {
794 #ifdef DEBUG_WAVEFORM_PAINT 782 #ifdef DEBUG_WAVEFORM_PAINT
795 cerr << "No (or not enough) ranges for i0 = " << i0 << endl; 783 cerr << "No (or not enough) ranges for i0 = " << i0 << endl;
797 continue; 785 continue;
798 } 786 }
799 787
800 int rangeBottom = 0, rangeTop = 0, meanBottom = 0, meanTop = 0; 788 int rangeBottom = 0, rangeTop = 0, meanBottom = 0, meanTop = 0;
801 789
802 if (mergingChannels) { 790 if (mergingChannels && ranges.size() > 1) {
803 791
804 if (otherChannelRanges && i0 < (sv_frame_t)otherChannelRanges->size()) { 792 const auto &other = ranges[1];
793
794 if (in_range_for(other, i0)) {
805 795
806 range.setMax(fabsf(range.max())); 796 range.setMax(fabsf(range.max()));
807 range.setMin(-fabsf((*otherChannelRanges)[size_t(i0)].max())); 797 range.setMin(-fabsf(other[i0].max()));
808 range.setAbsmean 798 range.setAbsmean
809 ((range.absmean() + 799 ((range.absmean() + other[i0].absmean()) / 2);
810 (*otherChannelRanges)[size_t(i0)].absmean()) / 2); 800
811 801 if (i1 > i0 && in_range_for(other, i1)) {
812 if (i1 > i0 && i1 < (sv_frame_t)otherChannelRanges->size()) {
813 // let's not concern ourselves about the mean 802 // let's not concern ourselves about the mean
814 range.setMin 803 range.setMin(std::min(range.min(),
815 (std::min 804 -fabsf(other[i1].max())));
816 (range.min(),
817 -fabsf((*otherChannelRanges)[size_t(i1)].max())));
818 } 805 }
819 } 806 }
820 807
821 } else if (mixingChannels) { 808 } else if (mixingChannels && ranges.size() > 1) {
822 809
823 if (otherChannelRanges && i0 < (sv_frame_t)otherChannelRanges->size()) { 810 const auto &other = ranges[1];
824 811
825 range.setMax((range.max() 812 if (in_range_for(other, i0)) {
826 + (*otherChannelRanges)[size_t(i0)].max()) / 2); 813
827 range.setMin((range.min() 814 range.setMax((range.max() + other[i0].max()) / 2);
828 + (*otherChannelRanges)[size_t(i0)].min()) / 2); 815 range.setMin((range.min() + other[i0].min()) / 2);
829 range.setAbsmean((range.absmean() 816 range.setAbsmean((range.absmean() + other[i0].absmean()) / 2);
830 + (*otherChannelRanges)[size_t(i0)].absmean()) / 2);
831 } 817 }
832 } 818 }
833 819
834 int greyLevels = 1; 820 int greyLevels = 1;
835 if (m_greyscale && (m_scale == LinearScale)) greyLevels = 4; 821 if (m_greyscale && (m_scale == LinearScale)) greyLevels = 4;