comparison layer/WaveformLayer.cpp @ 1332:6dac67c3ed82 zoom

Refactor out paintChannel
author Chris Cannam
date Fri, 21 Sep 2018 14:01:09 +0100
parents bc2cb82050a0
children 59f6830be8d8
comparison
equal deleted inserted replaced
1331:9758dfc12555 1332:6dac67c3ed82
497 if (channels == 0) return; 497 if (channels == 0) return;
498 498
499 int w = v->getPaintWidth(); 499 int w = v->getPaintWidth();
500 int h = v->getPaintHeight(); 500 int h = v->getPaintHeight();
501 501
502 bool ready = m_model->isReady();
503 QPainter *paint; 502 QPainter *paint;
504 503
505 if (m_aggressive) { 504 if (m_aggressive) {
506 505
507 #ifdef DEBUG_WAVEFORM_PAINT 506 #ifdef DEBUG_WAVEFORM_PAINT
593 592
594 RangeSummarisableTimeValueModel::RangeBlock *ranges = 593 RangeSummarisableTimeValueModel::RangeBlock *ranges =
595 new RangeSummarisableTimeValueModel::RangeBlock; 594 new RangeSummarisableTimeValueModel::RangeBlock;
596 595
597 RangeSummarisableTimeValueModel::RangeBlock *otherChannelRanges = 0; 596 RangeSummarisableTimeValueModel::RangeBlock *otherChannelRanges = 0;
598 RangeSummarisableTimeValueModel::Range range;
599
600 QColor baseColour = getBaseQColor();
601 std::vector<QColor> greys = getPartialShades(v);
602
603 QColor midColour = baseColour;
604 if (midColour == Qt::black) {
605 midColour = Qt::gray;
606 } else if (v->hasLightBackground()) {
607 midColour = midColour.light(150);
608 } else {
609 midColour = midColour.light(50);
610 }
611 597
612 while ((int)m_effectiveGains.size() <= maxChannel) { 598 while ((int)m_effectiveGains.size() <= maxChannel) {
613 m_effectiveGains.push_back(m_gain); 599 m_effectiveGains.push_back(m_gain);
614 } 600 }
615 601
616 for (int ch = minChannel; ch <= maxChannel; ++ch) { 602 for (int ch = minChannel; ch <= maxChannel; ++ch) {
617
618 int prevRangeBottom = -1, prevRangeTop = -1;
619 QColor prevRangeBottomColour = baseColour, prevRangeTopColour = baseColour;
620
621 m_effectiveGains[ch] = m_gain;
622
623 if (m_autoNormalize) {
624 m_effectiveGains[ch] = getNormalizeGain(v, ch);
625 }
626
627 double gain = m_effectiveGains[ch];
628
629 int m = (h / channels) / 2;
630 int my = m + (((ch - minChannel) * h) / channels);
631
632 #ifdef DEBUG_WAVEFORM_PAINT
633 cerr << "ch = " << ch << ", channels = " << channels << ", m = " << m << ", my = " << my << ", h = " << h << endl;
634 #endif
635
636 if (my - m > y1 || my + m < y0) continue;
637
638 if ((m_scale == dBScale || m_scale == MeterScale) &&
639 m_channelMode != MergeChannels) {
640 m = (h / channels);
641 my = m + (((ch - minChannel) * h) / channels);
642 }
643
644 paint->setPen(greys[1]);
645 paint->drawLine(x0, my, x1, my);
646
647 int n = 10;
648 int py = -1;
649 603
650 if (v->hasLightBackground() &&
651 v->getViewManager() &&
652 v->getViewManager()->shouldShowScaleGuides()) {
653
654 paint->setPen(QColor(240, 240, 240));
655
656 for (int i = 1; i < n; ++i) {
657
658 double val = 0.0, nval = 0.0;
659
660 switch (m_scale) {
661
662 case LinearScale:
663 val = (i * gain) / n;
664 if (i > 0) nval = -val;
665 break;
666
667 case MeterScale:
668 val = AudioLevel::dB_to_multiplier(meterdbs[i]) * gain;
669 break;
670
671 case dBScale:
672 val = AudioLevel::dB_to_multiplier(-(10*n) + i * 10) * gain;
673 break;
674 }
675
676 if (val < -1.0 || val > 1.0) continue;
677
678 int y = getYForValue(v, val, ch);
679
680 if (py >= 0 && abs(y - py) < 10) continue;
681 else py = y;
682
683 int ny = y;
684 if (nval != 0.0) {
685 ny = getYForValue(v, nval, ch);
686 }
687
688 paint->drawLine(x0, y, x1, y);
689 if (ny != y) {
690 paint->drawLine(x0, ny, x1, ny);
691 }
692 }
693 }
694
695 m_model->getSummaries(ch, frame0, frame1 - frame0, 604 m_model->getSummaries(ch, frame0, frame1 - frame0,
696 *ranges, blockSize); 605 *ranges, blockSize);
697 606
698 #ifdef DEBUG_WAVEFORM_PAINT 607 #ifdef DEBUG_WAVEFORM_PAINT
699 cerr << "channel " << ch << ": " << ranges->size() << " ranges from " << frame0 << " to " << frame1 << " at zoom level " << blockSize << endl; 608 cerr << "channel " << ch << ": " << ranges->size() << " ranges from " << frame0 << " to " << frame1 << " at zoom level " << blockSize << endl;
712 if (otherChannelRanges != ranges) delete otherChannelRanges; 621 if (otherChannelRanges != ranges) delete otherChannelRanges;
713 otherChannelRanges = ranges; 622 otherChannelRanges = ranges;
714 } 623 }
715 } 624 }
716 625
717 for (int x = x0; x <= x1; ++x) { 626 paintChannel(v, paint, ch, ranges, otherChannelRanges,
718 627 blockSize, x0, y0, x1, y1, frame0, frame1);
719 range = RangeSummarisableTimeValueModel::Range();
720
721 sv_frame_t f0, f1;
722 if (!getSourceFramesForX(v, x, blockSize, f0, f1)) continue;
723 f1 = f1 - 1;
724
725 if (f0 < frame0) {
726 cerr << "ERROR: WaveformLayer::paint: pixel " << x << " has f0 = " << f0 << " which is less than range frame0 " << frame0 << " for x0 = " << x0 << endl;
727 continue;
728 }
729
730 sv_frame_t i0 = (f0 - frame0) / blockSize;
731 sv_frame_t i1 = (f1 - frame0) / blockSize;
732
733 #ifdef DEBUG_WAVEFORM_PAINT
734 cerr << "WaveformLayer::paint: pixel " << x << ": i0 " << i0 << " (f " << f0 << "), i1 " << i1 << " (f " << f1 << ")" << endl;
735 #endif
736
737 if (i1 > i0 + 1) {
738 cerr << "WaveformLayer::paint: ERROR: i1 " << i1 << " > i0 " << i0 << " plus one (zoom = " << zoomLevel << ", model zoom = " << blockSize << ")" << endl;
739 }
740
741 if (ranges && i0 < (sv_frame_t)ranges->size()) {
742
743 range = (*ranges)[size_t(i0)];
744
745 if (i1 > i0 && i1 < (int)ranges->size()) {
746 range.setMax(std::max(range.max(),
747 (*ranges)[size_t(i1)].max()));
748 range.setMin(std::min(range.min(),
749 (*ranges)[size_t(i1)].min()));
750 range.setAbsmean((range.absmean()
751 + (*ranges)[size_t(i1)].absmean()) / 2);
752 }
753
754 } else {
755 #ifdef DEBUG_WAVEFORM_PAINT
756 cerr << "No (or not enough) ranges for i0 = " << i0 << endl;
757 #endif
758 continue;
759 }
760
761 int rangeBottom = 0, rangeTop = 0, meanBottom = 0, meanTop = 0;
762
763 if (mergingChannels) {
764
765 if (otherChannelRanges && i0 < (sv_frame_t)otherChannelRanges->size()) {
766
767 range.setMax(fabsf(range.max()));
768 range.setMin(-fabsf((*otherChannelRanges)[size_t(i0)].max()));
769 range.setAbsmean
770 ((range.absmean() +
771 (*otherChannelRanges)[size_t(i0)].absmean()) / 2);
772
773 if (i1 > i0 && i1 < (sv_frame_t)otherChannelRanges->size()) {
774 // let's not concern ourselves about the mean
775 range.setMin
776 (std::min
777 (range.min(),
778 -fabsf((*otherChannelRanges)[size_t(i1)].max())));
779 }
780 }
781
782 } else if (mixingChannels) {
783
784 if (otherChannelRanges && i0 < (sv_frame_t)otherChannelRanges->size()) {
785
786 range.setMax((range.max()
787 + (*otherChannelRanges)[size_t(i0)].max()) / 2);
788 range.setMin((range.min()
789 + (*otherChannelRanges)[size_t(i0)].min()) / 2);
790 range.setAbsmean((range.absmean()
791 + (*otherChannelRanges)[size_t(i0)].absmean()) / 2);
792 }
793 }
794
795 int greyLevels = 1;
796 if (m_greyscale && (m_scale == LinearScale)) greyLevels = 4;
797
798 switch (m_scale) {
799
800 case LinearScale:
801 rangeBottom = int(double(m * greyLevels) * range.min() * gain);
802 rangeTop = int(double(m * greyLevels) * range.max() * gain);
803 meanBottom = int(double(-m) * range.absmean() * gain);
804 meanTop = int(double(m) * range.absmean() * gain);
805 break;
806
807 case dBScale:
808 if (!mergingChannels) {
809 int db0 = dBscale(range.min() * gain, m);
810 int db1 = dBscale(range.max() * gain, m);
811 rangeTop = std::max(db0, db1);
812 meanTop = std::min(db0, db1);
813 if (mixingChannels) rangeBottom = meanTop;
814 else rangeBottom = dBscale(range.absmean() * gain, m);
815 meanBottom = rangeBottom;
816 } else {
817 rangeBottom = -dBscale(range.min() * gain, m * greyLevels);
818 rangeTop = dBscale(range.max() * gain, m * greyLevels);
819 meanBottom = -dBscale(range.absmean() * gain, m);
820 meanTop = dBscale(range.absmean() * gain, m);
821 }
822 break;
823
824 case MeterScale:
825 if (!mergingChannels) {
826 int r0 = abs(AudioLevel::multiplier_to_preview(range.min() * gain, m));
827 int r1 = abs(AudioLevel::multiplier_to_preview(range.max() * gain, m));
828 rangeTop = std::max(r0, r1);
829 meanTop = std::min(r0, r1);
830 if (mixingChannels) rangeBottom = meanTop;
831 else rangeBottom = AudioLevel::multiplier_to_preview(range.absmean() * gain, m);
832 meanBottom = rangeBottom;
833 } else {
834 rangeBottom = -AudioLevel::multiplier_to_preview(range.min() * gain, m * greyLevels);
835 rangeTop = AudioLevel::multiplier_to_preview(range.max() * gain, m * greyLevels);
836 meanBottom = -AudioLevel::multiplier_to_preview(range.absmean() * gain, m);
837 meanTop = AudioLevel::multiplier_to_preview(range.absmean() * gain, m);
838 }
839 break;
840 }
841
842 rangeBottom = my * greyLevels - rangeBottom;
843 rangeTop = my * greyLevels - rangeTop;
844 meanBottom = my - meanBottom;
845 meanTop = my - meanTop;
846
847 int topFill = (rangeTop % greyLevels);
848 if (topFill > 0) topFill = greyLevels - topFill;
849
850 int bottomFill = (rangeBottom % greyLevels);
851
852 rangeTop = rangeTop / greyLevels;
853 rangeBottom = rangeBottom / greyLevels;
854
855 bool clipped = false;
856
857 if (rangeTop < my - m) { rangeTop = my - m; }
858 if (rangeTop > my + m) { rangeTop = my + m; }
859 if (rangeBottom < my - m) { rangeBottom = my - m; }
860 if (rangeBottom > my + m) { rangeBottom = my + m; }
861
862 if (range.max() <= -1.0 ||
863 range.max() >= 1.0) clipped = true;
864
865 if (meanBottom > rangeBottom) meanBottom = rangeBottom;
866 if (meanTop < rangeTop) meanTop = rangeTop;
867
868 bool drawMean = m_showMeans;
869 if (meanTop == rangeTop) {
870 if (meanTop < meanBottom) ++meanTop;
871 else drawMean = false;
872 }
873 if (meanBottom == rangeBottom && m_scale == LinearScale) {
874 if (meanBottom > meanTop) --meanBottom;
875 else drawMean = false;
876 }
877
878 if (x != x0 && prevRangeBottom != -1) {
879 if (prevRangeBottom > rangeBottom + 1 &&
880 prevRangeTop > rangeBottom + 1) {
881 // paint->setPen(midColour);
882 paint->setPen(baseColour);
883 paint->drawLine(x-1, prevRangeTop, x, rangeBottom + 1);
884 paint->setPen(prevRangeTopColour);
885 paint->drawPoint(x-1, prevRangeTop);
886 } else if (prevRangeBottom < rangeTop - 1 &&
887 prevRangeTop < rangeTop - 1) {
888 // paint->setPen(midColour);
889 paint->setPen(baseColour);
890 paint->drawLine(x-1, prevRangeBottom, x, rangeTop - 1);
891 paint->setPen(prevRangeBottomColour);
892 paint->drawPoint(x-1, prevRangeBottom);
893 }
894 }
895
896 if (ready) {
897 if (clipped /*!!! ||
898 range.min() * gain <= -1.0 ||
899 range.max() * gain >= 1.0 */) {
900 paint->setPen(Qt::red); //!!! getContrastingColour
901 } else {
902 paint->setPen(baseColour);
903 }
904 } else {
905 paint->setPen(midColour);
906 }
907
908 #ifdef DEBUG_WAVEFORM_PAINT
909 cerr << "range " << rangeBottom << " -> " << rangeTop << ", means " << meanBottom << " -> " << meanTop << ", raw range " << range.min() << " -> " << range.max() << endl;
910 #endif
911
912 if (rangeTop == rangeBottom) {
913 paint->drawPoint(x, rangeTop);
914 } else {
915 paint->drawLine(x, rangeBottom, x, rangeTop);
916 }
917
918 prevRangeTopColour = baseColour;
919 prevRangeBottomColour = baseColour;
920
921 if (m_greyscale && (m_scale == LinearScale) && ready) {
922 if (!clipped) {
923 if (rangeTop < rangeBottom) {
924 if (topFill > 0 &&
925 (!drawMean || (rangeTop < meanTop - 1))) {
926 paint->setPen(greys[topFill - 1]);
927 paint->drawPoint(x, rangeTop);
928 prevRangeTopColour = greys[topFill - 1];
929 }
930 if (bottomFill > 0 &&
931 (!drawMean || (rangeBottom > meanBottom + 1))) {
932 paint->setPen(greys[bottomFill - 1]);
933 paint->drawPoint(x, rangeBottom);
934 prevRangeBottomColour = greys[bottomFill - 1];
935 }
936 }
937 }
938 }
939
940 if (drawMean) {
941 paint->setPen(midColour);
942 paint->drawLine(x, meanBottom, x, meanTop);
943 }
944
945 prevRangeBottom = rangeBottom;
946 prevRangeTop = rangeTop;
947 }
948 } 628 }
949 629
950 if (m_middleLineHeight != 0.5) { 630 if (m_middleLineHeight != 0.5) {
951 paint->restore(); 631 paint->restore();
952 } 632 }
953 633
954 if (m_aggressive) { 634 if (m_aggressive) {
955 635
956 if (ready && rect == v->getPaintRect()) { 636 if (m_model->isReady() && rect == v->getPaintRect()) {
957 m_cacheValid = true; 637 m_cacheValid = true;
958 m_cacheZoomLevel = zoomLevel; 638 m_cacheZoomLevel = zoomLevel;
959 } 639 }
960 paint->end(); 640 paint->end();
961 delete paint; 641 delete paint;
962 viewPainter.drawPixmap(rect, *m_cache, rect); 642 viewPainter.drawPixmap(rect, *m_cache, rect);
963 } 643 }
964 644
965 if (otherChannelRanges != ranges) delete otherChannelRanges; 645 if (otherChannelRanges != ranges) delete otherChannelRanges;
966 delete ranges; 646 delete ranges;
647 }
648
649 void
650 WaveformLayer::paintChannel(LayerGeometryProvider *v, QPainter *paint, int ch,
651 const RangeSummarisableTimeValueModel::RangeBlock *ranges,
652 const RangeSummarisableTimeValueModel::RangeBlock *otherChannelRanges,
653 int blockSize, int x0, int y0, int x1, int y1,
654 sv_frame_t frame0, sv_frame_t frame1)
655 const
656 {
657 int w = v->getPaintWidth();
658 int h = v->getPaintHeight();
659
660 int channels = 0, minChannel = 0, maxChannel = 0;
661 bool mergingChannels = false, mixingChannels = false;
662
663 channels = getChannelArrangement(minChannel, maxChannel,
664 mergingChannels, mixingChannels);
665 if (channels == 0) return;
666
667 QColor baseColour = getBaseQColor();
668 std::vector<QColor> greys = getPartialShades(v);
669
670 QColor midColour = baseColour;
671 if (midColour == Qt::black) {
672 midColour = Qt::gray;
673 } else if (v->hasLightBackground()) {
674 midColour = midColour.light(150);
675 } else {
676 midColour = midColour.light(50);
677 }
678
679 int prevRangeBottom = -1, prevRangeTop = -1;
680 QColor prevRangeBottomColour = baseColour, prevRangeTopColour = baseColour;
681
682 m_effectiveGains[ch] = m_gain;
683
684 if (m_autoNormalize) {
685 m_effectiveGains[ch] = getNormalizeGain(v, ch);
686 }
687
688 double gain = m_effectiveGains[ch];
689
690 int m = (h / channels) / 2;
691 int my = m + (((ch - minChannel) * h) / channels);
692
693 #ifdef DEBUG_WAVEFORM_PAINT
694 cerr << "ch = " << ch << ", channels = " << channels << ", m = " << m << ", my = " << my << ", h = " << h << endl;
695 #endif
696
697 if (my - m > y1 || my + m < y0) return;
698
699 if ((m_scale == dBScale || m_scale == MeterScale) &&
700 m_channelMode != MergeChannels) {
701 m = (h / channels);
702 my = m + (((ch - minChannel) * h) / channels);
703 }
704
705 paint->setPen(greys[1]);
706 paint->drawLine(x0, my, x1, my);
707
708 int n = 10;
709 int py = -1;
710
711 if (v->hasLightBackground() &&
712 v->getViewManager() &&
713 v->getViewManager()->shouldShowScaleGuides()) {
714
715 paint->setPen(QColor(240, 240, 240));
716
717 for (int i = 1; i < n; ++i) {
718
719 double val = 0.0, nval = 0.0;
720
721 switch (m_scale) {
722
723 case LinearScale:
724 val = (i * gain) / n;
725 if (i > 0) nval = -val;
726 break;
727
728 case MeterScale:
729 val = AudioLevel::dB_to_multiplier(meterdbs[i]) * gain;
730 break;
731
732 case dBScale:
733 val = AudioLevel::dB_to_multiplier(-(10*n) + i * 10) * gain;
734 break;
735 }
736
737 if (val < -1.0 || val > 1.0) continue;
738
739 int y = getYForValue(v, val, ch);
740
741 if (py >= 0 && abs(y - py) < 10) continue;
742 else py = y;
743
744 int ny = y;
745 if (nval != 0.0) {
746 ny = getYForValue(v, nval, ch);
747 }
748
749 paint->drawLine(x0, y, x1, y);
750 if (ny != y) {
751 paint->drawLine(x0, ny, x1, ny);
752 }
753 }
754 }
755
756 for (int x = x0; x <= x1; ++x) {
757
758 RangeSummarisableTimeValueModel::Range range;
759
760 sv_frame_t f0, f1;
761 if (!getSourceFramesForX(v, x, blockSize, f0, f1)) continue;
762 f1 = f1 - 1;
763
764 if (f0 < frame0) {
765 cerr << "ERROR: WaveformLayer::paint: pixel " << x << " has f0 = " << f0 << " which is less than range frame0 " << frame0 << " for x0 = " << x0 << endl;
766 continue;
767 }
768
769 sv_frame_t i0 = (f0 - frame0) / blockSize;
770 sv_frame_t i1 = (f1 - frame0) / blockSize;
771
772 #ifdef DEBUG_WAVEFORM_PAINT
773 cerr << "WaveformLayer::paint: pixel " << x << ": i0 " << i0 << " (f " << f0 << "), i1 " << i1 << " (f " << f1 << ")" << endl;
774 #endif
775
776 if (i1 > i0 + 1) {
777 cerr << "WaveformLayer::paint: ERROR: i1 " << i1 << " > i0 " << i0 << " plus one (zoom = " << v->getZoomLevel() << ", model zoom = " << blockSize << ")" << endl;
778 }
779
780 if (ranges && i0 < (sv_frame_t)ranges->size()) {
781
782 range = (*ranges)[size_t(i0)];
783
784 if (i1 > i0 && i1 < (int)ranges->size()) {
785 range.setMax(std::max(range.max(),
786 (*ranges)[size_t(i1)].max()));
787 range.setMin(std::min(range.min(),
788 (*ranges)[size_t(i1)].min()));
789 range.setAbsmean((range.absmean()
790 + (*ranges)[size_t(i1)].absmean()) / 2);
791 }
792
793 } else {
794 #ifdef DEBUG_WAVEFORM_PAINT
795 cerr << "No (or not enough) ranges for i0 = " << i0 << endl;
796 #endif
797 continue;
798 }
799
800 int rangeBottom = 0, rangeTop = 0, meanBottom = 0, meanTop = 0;
801
802 if (mergingChannels) {
803
804 if (otherChannelRanges && i0 < (sv_frame_t)otherChannelRanges->size()) {
805
806 range.setMax(fabsf(range.max()));
807 range.setMin(-fabsf((*otherChannelRanges)[size_t(i0)].max()));
808 range.setAbsmean
809 ((range.absmean() +
810 (*otherChannelRanges)[size_t(i0)].absmean()) / 2);
811
812 if (i1 > i0 && i1 < (sv_frame_t)otherChannelRanges->size()) {
813 // let's not concern ourselves about the mean
814 range.setMin
815 (std::min
816 (range.min(),
817 -fabsf((*otherChannelRanges)[size_t(i1)].max())));
818 }
819 }
820
821 } else if (mixingChannels) {
822
823 if (otherChannelRanges && i0 < (sv_frame_t)otherChannelRanges->size()) {
824
825 range.setMax((range.max()
826 + (*otherChannelRanges)[size_t(i0)].max()) / 2);
827 range.setMin((range.min()
828 + (*otherChannelRanges)[size_t(i0)].min()) / 2);
829 range.setAbsmean((range.absmean()
830 + (*otherChannelRanges)[size_t(i0)].absmean()) / 2);
831 }
832 }
833
834 int greyLevels = 1;
835 if (m_greyscale && (m_scale == LinearScale)) greyLevels = 4;
836
837 switch (m_scale) {
838
839 case LinearScale:
840 rangeBottom = int(double(m * greyLevels) * range.min() * gain);
841 rangeTop = int(double(m * greyLevels) * range.max() * gain);
842 meanBottom = int(double(-m) * range.absmean() * gain);
843 meanTop = int(double(m) * range.absmean() * gain);
844 break;
845
846 case dBScale:
847 if (!mergingChannels) {
848 int db0 = dBscale(range.min() * gain, m);
849 int db1 = dBscale(range.max() * gain, m);
850 rangeTop = std::max(db0, db1);
851 meanTop = std::min(db0, db1);
852 if (mixingChannels) rangeBottom = meanTop;
853 else rangeBottom = dBscale(range.absmean() * gain, m);
854 meanBottom = rangeBottom;
855 } else {
856 rangeBottom = -dBscale(range.min() * gain, m * greyLevels);
857 rangeTop = dBscale(range.max() * gain, m * greyLevels);
858 meanBottom = -dBscale(range.absmean() * gain, m);
859 meanTop = dBscale(range.absmean() * gain, m);
860 }
861 break;
862
863 case MeterScale:
864 if (!mergingChannels) {
865 int r0 = abs(AudioLevel::multiplier_to_preview(range.min() * gain, m));
866 int r1 = abs(AudioLevel::multiplier_to_preview(range.max() * gain, m));
867 rangeTop = std::max(r0, r1);
868 meanTop = std::min(r0, r1);
869 if (mixingChannels) rangeBottom = meanTop;
870 else rangeBottom = AudioLevel::multiplier_to_preview(range.absmean() * gain, m);
871 meanBottom = rangeBottom;
872 } else {
873 rangeBottom = -AudioLevel::multiplier_to_preview(range.min() * gain, m * greyLevels);
874 rangeTop = AudioLevel::multiplier_to_preview(range.max() * gain, m * greyLevels);
875 meanBottom = -AudioLevel::multiplier_to_preview(range.absmean() * gain, m);
876 meanTop = AudioLevel::multiplier_to_preview(range.absmean() * gain, m);
877 }
878 break;
879 }
880
881 rangeBottom = my * greyLevels - rangeBottom;
882 rangeTop = my * greyLevels - rangeTop;
883 meanBottom = my - meanBottom;
884 meanTop = my - meanTop;
885
886 int topFill = (rangeTop % greyLevels);
887 if (topFill > 0) topFill = greyLevels - topFill;
888
889 int bottomFill = (rangeBottom % greyLevels);
890
891 rangeTop = rangeTop / greyLevels;
892 rangeBottom = rangeBottom / greyLevels;
893
894 bool clipped = false;
895
896 if (rangeTop < my - m) { rangeTop = my - m; }
897 if (rangeTop > my + m) { rangeTop = my + m; }
898 if (rangeBottom < my - m) { rangeBottom = my - m; }
899 if (rangeBottom > my + m) { rangeBottom = my + m; }
900
901 if (range.max() <= -1.0 ||
902 range.max() >= 1.0) clipped = true;
903
904 if (meanBottom > rangeBottom) meanBottom = rangeBottom;
905 if (meanTop < rangeTop) meanTop = rangeTop;
906
907 bool drawMean = m_showMeans;
908 if (meanTop == rangeTop) {
909 if (meanTop < meanBottom) ++meanTop;
910 else drawMean = false;
911 }
912 if (meanBottom == rangeBottom && m_scale == LinearScale) {
913 if (meanBottom > meanTop) --meanBottom;
914 else drawMean = false;
915 }
916
917 if (x != x0 && prevRangeBottom != -1) {
918 if (prevRangeBottom > rangeBottom + 1 &&
919 prevRangeTop > rangeBottom + 1) {
920 // paint->setPen(midColour);
921 paint->setPen(baseColour);
922 paint->drawLine(x-1, prevRangeTop, x, rangeBottom + 1);
923 paint->setPen(prevRangeTopColour);
924 paint->drawPoint(x-1, prevRangeTop);
925 } else if (prevRangeBottom < rangeTop - 1 &&
926 prevRangeTop < rangeTop - 1) {
927 // paint->setPen(midColour);
928 paint->setPen(baseColour);
929 paint->drawLine(x-1, prevRangeBottom, x, rangeTop - 1);
930 paint->setPen(prevRangeBottomColour);
931 paint->drawPoint(x-1, prevRangeBottom);
932 }
933 }
934
935 if (m_model->isReady()) {
936 if (clipped /*!!! ||
937 range.min() * gain <= -1.0 ||
938 range.max() * gain >= 1.0 */) {
939 paint->setPen(Qt::red); //!!! getContrastingColour
940 } else {
941 paint->setPen(baseColour);
942 }
943 } else {
944 paint->setPen(midColour);
945 }
946
947 #ifdef DEBUG_WAVEFORM_PAINT
948 cerr << "range " << rangeBottom << " -> " << rangeTop << ", means " << meanBottom << " -> " << meanTop << ", raw range " << range.min() << " -> " << range.max() << endl;
949 #endif
950
951 if (rangeTop == rangeBottom) {
952 paint->drawPoint(x, rangeTop);
953 } else {
954 paint->drawLine(x, rangeBottom, x, rangeTop);
955 }
956
957 prevRangeTopColour = baseColour;
958 prevRangeBottomColour = baseColour;
959
960 if (m_greyscale && (m_scale == LinearScale) && m_model->isReady()) {
961 if (!clipped) {
962 if (rangeTop < rangeBottom) {
963 if (topFill > 0 &&
964 (!drawMean || (rangeTop < meanTop - 1))) {
965 paint->setPen(greys[topFill - 1]);
966 paint->drawPoint(x, rangeTop);
967 prevRangeTopColour = greys[topFill - 1];
968 }
969 if (bottomFill > 0 &&
970 (!drawMean || (rangeBottom > meanBottom + 1))) {
971 paint->setPen(greys[bottomFill - 1]);
972 paint->drawPoint(x, rangeBottom);
973 prevRangeBottomColour = greys[bottomFill - 1];
974 }
975 }
976 }
977 }
978
979 if (drawMean) {
980 paint->setPen(midColour);
981 paint->drawLine(x, meanBottom, x, meanTop);
982 }
983
984 prevRangeBottom = rangeBottom;
985 prevRangeTop = rangeTop;
986 }
967 } 987 }
968 988
969 QString 989 QString
970 WaveformLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &pos) const 990 WaveformLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &pos) const
971 { 991 {