Mercurial > hg > svgui
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 { |