Mercurial > hg > svgui
comparison layer/SpectrogramLayer.cpp @ 478:0990b95140e3
* incremental commit
author | Chris Cannam |
---|---|
date | Tue, 03 Feb 2009 12:02:17 +0000 |
parents | 92f4d88241b8 |
children | 0033dbfb92e3 |
comparison
equal
deleted
inserted
replaced
477:92f4d88241b8 | 478:0990b95140e3 |
---|---|
551 setNormalizeVisibleArea(value ? true : false); | 551 setNormalizeVisibleArea(value ? true : false); |
552 } | 552 } |
553 } | 553 } |
554 | 554 |
555 void | 555 void |
556 SpectrogramLayer::invalidatePixmapCaches() | 556 SpectrogramLayer::invalidateImageCaches() |
557 { | 557 { |
558 for (ViewPixmapCache::iterator i = m_pixmapCaches.begin(); | 558 for (ViewImageCache::iterator i = m_imageCaches.begin(); |
559 i != m_pixmapCaches.end(); ++i) { | 559 i != m_imageCaches.end(); ++i) { |
560 i->second.validArea = QRect(); | 560 i->second.validArea = QRect(); |
561 } | 561 } |
562 } | 562 } |
563 | 563 |
564 void | 564 void |
565 SpectrogramLayer::invalidatePixmapCaches(size_t startFrame, size_t endFrame) | 565 SpectrogramLayer::invalidateImageCaches(size_t startFrame, size_t endFrame) |
566 { | 566 { |
567 for (ViewPixmapCache::iterator i = m_pixmapCaches.begin(); | 567 for (ViewImageCache::iterator i = m_imageCaches.begin(); |
568 i != m_pixmapCaches.end(); ++i) { | 568 i != m_imageCaches.end(); ++i) { |
569 | 569 |
570 //!!! when are views removed from the map? on setLayerDormant? | 570 //!!! when are views removed from the map? on setLayerDormant? |
571 const View *v = i->first; | 571 const View *v = i->first; |
572 | 572 |
573 #ifdef DEBUG_SPECTROGRAM_REPAINT | 573 #ifdef DEBUG_SPECTROGRAM_REPAINT |
574 std::cerr << "SpectrogramLayer::invalidatePixmapCaches(" | 574 std::cerr << "SpectrogramLayer::invalidateImageCaches(" |
575 << startFrame << ", " << endFrame << "): view range is " | 575 << startFrame << ", " << endFrame << "): view range is " |
576 << v->getStartFrame() << ", " << v->getEndFrame() | 576 << v->getStartFrame() << ", " << v->getEndFrame() |
577 << std::endl; | 577 << std::endl; |
578 | 578 |
579 std::cerr << "Valid area was: " << i->second.validArea.x() << ", " | 579 std::cerr << "Valid area was: " << i->second.validArea.x() << ", " |
636 if (name == "Window Type") { | 636 if (name == "Window Type") { |
637 setWindowType(Preferences::getInstance()->getWindowType()); | 637 setWindowType(Preferences::getInstance()->getWindowType()); |
638 return; | 638 return; |
639 } | 639 } |
640 if (name == "Spectrogram Smoothing") { | 640 if (name == "Spectrogram Smoothing") { |
641 invalidatePixmapCaches(); | 641 invalidateImageCaches(); |
642 invalidateMagnitudes(); | 642 invalidateMagnitudes(); |
643 emit layerParametersChanged(); | 643 emit layerParametersChanged(); |
644 } | 644 } |
645 if (name == "Tuning Frequency") { | 645 if (name == "Tuning Frequency") { |
646 emit layerParametersChanged(); | 646 emit layerParametersChanged(); |
650 void | 650 void |
651 SpectrogramLayer::setChannel(int ch) | 651 SpectrogramLayer::setChannel(int ch) |
652 { | 652 { |
653 if (m_channel == ch) return; | 653 if (m_channel == ch) return; |
654 | 654 |
655 invalidatePixmapCaches(); | 655 invalidateImageCaches(); |
656 m_channel = ch; | 656 m_channel = ch; |
657 invalidateFFTModels(); | 657 invalidateFFTModels(); |
658 | 658 |
659 emit layerParametersChanged(); | 659 emit layerParametersChanged(); |
660 } | 660 } |
668 void | 668 void |
669 SpectrogramLayer::setWindowSize(size_t ws) | 669 SpectrogramLayer::setWindowSize(size_t ws) |
670 { | 670 { |
671 if (m_windowSize == ws) return; | 671 if (m_windowSize == ws) return; |
672 | 672 |
673 invalidatePixmapCaches(); | 673 invalidateImageCaches(); |
674 | 674 |
675 m_windowSize = ws; | 675 m_windowSize = ws; |
676 m_fftSize = ws * (m_zeroPadLevel + 1); | 676 m_fftSize = ws * (m_zeroPadLevel + 1); |
677 | 677 |
678 invalidateFFTModels(); | 678 invalidateFFTModels(); |
689 void | 689 void |
690 SpectrogramLayer::setWindowHopLevel(size_t v) | 690 SpectrogramLayer::setWindowHopLevel(size_t v) |
691 { | 691 { |
692 if (m_windowHopLevel == v) return; | 692 if (m_windowHopLevel == v) return; |
693 | 693 |
694 invalidatePixmapCaches(); | 694 invalidateImageCaches(); |
695 | 695 |
696 m_windowHopLevel = v; | 696 m_windowHopLevel = v; |
697 | 697 |
698 invalidateFFTModels(); | 698 invalidateFFTModels(); |
699 | 699 |
711 void | 711 void |
712 SpectrogramLayer::setZeroPadLevel(size_t v) | 712 SpectrogramLayer::setZeroPadLevel(size_t v) |
713 { | 713 { |
714 if (m_zeroPadLevel == v) return; | 714 if (m_zeroPadLevel == v) return; |
715 | 715 |
716 invalidatePixmapCaches(); | 716 invalidateImageCaches(); |
717 | 717 |
718 m_zeroPadLevel = v; | 718 m_zeroPadLevel = v; |
719 m_fftSize = m_windowSize * (v + 1); | 719 m_fftSize = m_windowSize * (v + 1); |
720 | 720 |
721 invalidateFFTModels(); | 721 invalidateFFTModels(); |
732 void | 732 void |
733 SpectrogramLayer::setWindowType(WindowType w) | 733 SpectrogramLayer::setWindowType(WindowType w) |
734 { | 734 { |
735 if (m_windowType == w) return; | 735 if (m_windowType == w) return; |
736 | 736 |
737 invalidatePixmapCaches(); | 737 invalidateImageCaches(); |
738 | 738 |
739 m_windowType = w; | 739 m_windowType = w; |
740 | 740 |
741 invalidateFFTModels(); | 741 invalidateFFTModels(); |
742 | 742 |
755 // std::cerr << "SpectrogramLayer::setGain(" << gain << ") (my gain is now " | 755 // std::cerr << "SpectrogramLayer::setGain(" << gain << ") (my gain is now " |
756 // << m_gain << ")" << std::endl; | 756 // << m_gain << ")" << std::endl; |
757 | 757 |
758 if (m_gain == gain) return; | 758 if (m_gain == gain) return; |
759 | 759 |
760 invalidatePixmapCaches(); | 760 invalidateImageCaches(); |
761 | 761 |
762 m_gain = gain; | 762 m_gain = gain; |
763 | 763 |
764 emit layerParametersChanged(); | 764 emit layerParametersChanged(); |
765 } | 765 } |
773 void | 773 void |
774 SpectrogramLayer::setThreshold(float threshold) | 774 SpectrogramLayer::setThreshold(float threshold) |
775 { | 775 { |
776 if (m_threshold == threshold) return; | 776 if (m_threshold == threshold) return; |
777 | 777 |
778 invalidatePixmapCaches(); | 778 invalidateImageCaches(); |
779 | 779 |
780 m_threshold = threshold; | 780 m_threshold = threshold; |
781 | 781 |
782 emit layerParametersChanged(); | 782 emit layerParametersChanged(); |
783 } | 783 } |
793 { | 793 { |
794 if (m_minFrequency == mf) return; | 794 if (m_minFrequency == mf) return; |
795 | 795 |
796 // std::cerr << "SpectrogramLayer::setMinFrequency: " << mf << std::endl; | 796 // std::cerr << "SpectrogramLayer::setMinFrequency: " << mf << std::endl; |
797 | 797 |
798 invalidatePixmapCaches(); | 798 invalidateImageCaches(); |
799 invalidateMagnitudes(); | 799 invalidateMagnitudes(); |
800 | 800 |
801 m_minFrequency = mf; | 801 m_minFrequency = mf; |
802 | 802 |
803 emit layerParametersChanged(); | 803 emit layerParametersChanged(); |
814 { | 814 { |
815 if (m_maxFrequency == mf) return; | 815 if (m_maxFrequency == mf) return; |
816 | 816 |
817 // std::cerr << "SpectrogramLayer::setMaxFrequency: " << mf << std::endl; | 817 // std::cerr << "SpectrogramLayer::setMaxFrequency: " << mf << std::endl; |
818 | 818 |
819 invalidatePixmapCaches(); | 819 invalidateImageCaches(); |
820 invalidateMagnitudes(); | 820 invalidateMagnitudes(); |
821 | 821 |
822 m_maxFrequency = mf; | 822 m_maxFrequency = mf; |
823 | 823 |
824 emit layerParametersChanged(); | 824 emit layerParametersChanged(); |
831 } | 831 } |
832 | 832 |
833 void | 833 void |
834 SpectrogramLayer::setColourRotation(int r) | 834 SpectrogramLayer::setColourRotation(int r) |
835 { | 835 { |
836 invalidatePixmapCaches(); | 836 invalidateImageCaches(); |
837 | 837 |
838 if (r < 0) r = 0; | 838 if (r < 0) r = 0; |
839 if (r > 256) r = 256; | 839 if (r > 256) r = 256; |
840 int distance = r - m_colourRotation; | 840 int distance = r - m_colourRotation; |
841 | 841 |
850 void | 850 void |
851 SpectrogramLayer::setColourScale(ColourScale colourScale) | 851 SpectrogramLayer::setColourScale(ColourScale colourScale) |
852 { | 852 { |
853 if (m_colourScale == colourScale) return; | 853 if (m_colourScale == colourScale) return; |
854 | 854 |
855 invalidatePixmapCaches(); | 855 invalidateImageCaches(); |
856 | 856 |
857 m_colourScale = colourScale; | 857 m_colourScale = colourScale; |
858 | 858 |
859 emit layerParametersChanged(); | 859 emit layerParametersChanged(); |
860 } | 860 } |
868 void | 868 void |
869 SpectrogramLayer::setColourMap(int map) | 869 SpectrogramLayer::setColourMap(int map) |
870 { | 870 { |
871 if (m_colourMap == map) return; | 871 if (m_colourMap == map) return; |
872 | 872 |
873 invalidatePixmapCaches(); | 873 invalidateImageCaches(); |
874 | 874 |
875 m_colourMap = map; | 875 m_colourMap = map; |
876 initialisePalette(); | 876 initialisePalette(); |
877 | 877 |
878 emit layerParametersChanged(); | 878 emit layerParametersChanged(); |
887 void | 887 void |
888 SpectrogramLayer::setFrequencyScale(FrequencyScale frequencyScale) | 888 SpectrogramLayer::setFrequencyScale(FrequencyScale frequencyScale) |
889 { | 889 { |
890 if (m_frequencyScale == frequencyScale) return; | 890 if (m_frequencyScale == frequencyScale) return; |
891 | 891 |
892 invalidatePixmapCaches(); | 892 invalidateImageCaches(); |
893 m_frequencyScale = frequencyScale; | 893 m_frequencyScale = frequencyScale; |
894 | 894 |
895 emit layerParametersChanged(); | 895 emit layerParametersChanged(); |
896 } | 896 } |
897 | 897 |
904 void | 904 void |
905 SpectrogramLayer::setBinDisplay(BinDisplay binDisplay) | 905 SpectrogramLayer::setBinDisplay(BinDisplay binDisplay) |
906 { | 906 { |
907 if (m_binDisplay == binDisplay) return; | 907 if (m_binDisplay == binDisplay) return; |
908 | 908 |
909 invalidatePixmapCaches(); | 909 invalidateImageCaches(); |
910 m_binDisplay = binDisplay; | 910 m_binDisplay = binDisplay; |
911 | 911 |
912 emit layerParametersChanged(); | 912 emit layerParametersChanged(); |
913 } | 913 } |
914 | 914 |
921 void | 921 void |
922 SpectrogramLayer::setNormalizeColumns(bool n) | 922 SpectrogramLayer::setNormalizeColumns(bool n) |
923 { | 923 { |
924 if (m_normalizeColumns == n) return; | 924 if (m_normalizeColumns == n) return; |
925 | 925 |
926 invalidatePixmapCaches(); | 926 invalidateImageCaches(); |
927 invalidateMagnitudes(); | 927 invalidateMagnitudes(); |
928 m_normalizeColumns = n; | 928 m_normalizeColumns = n; |
929 | 929 |
930 emit layerParametersChanged(); | 930 emit layerParametersChanged(); |
931 } | 931 } |
942 std::cerr << "SpectrogramLayer::setNormalizeVisibleArea(" << n | 942 std::cerr << "SpectrogramLayer::setNormalizeVisibleArea(" << n |
943 << ") (from " << m_normalizeVisibleArea << ")" << std::endl; | 943 << ") (from " << m_normalizeVisibleArea << ")" << std::endl; |
944 | 944 |
945 if (m_normalizeVisibleArea == n) return; | 945 if (m_normalizeVisibleArea == n) return; |
946 | 946 |
947 invalidatePixmapCaches(); | 947 invalidateImageCaches(); |
948 invalidateMagnitudes(); | 948 invalidateMagnitudes(); |
949 m_normalizeVisibleArea = n; | 949 m_normalizeVisibleArea = n; |
950 | 950 |
951 emit layerParametersChanged(); | 951 emit layerParametersChanged(); |
952 } | 952 } |
971 return; | 971 return; |
972 } | 972 } |
973 | 973 |
974 Layer::setLayerDormant(v, true); | 974 Layer::setLayerDormant(v, true); |
975 | 975 |
976 invalidatePixmapCaches(); | 976 invalidateImageCaches(); |
977 m_pixmapCaches.erase(v); | 977 m_imageCaches.erase(v); |
978 | 978 |
979 if (m_fftModels.find(v) != m_fftModels.end()) { | 979 if (m_fftModels.find(v) != m_fftModels.end()) { |
980 | 980 |
981 if (m_sliceableModel == m_fftModels[v].first) { | 981 if (m_sliceableModel == m_fftModels[v].first) { |
982 bool replaced = false; | 982 bool replaced = false; |
1006 { | 1006 { |
1007 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1007 #ifdef DEBUG_SPECTROGRAM_REPAINT |
1008 std::cerr << "SpectrogramLayer::cacheInvalid()" << std::endl; | 1008 std::cerr << "SpectrogramLayer::cacheInvalid()" << std::endl; |
1009 #endif | 1009 #endif |
1010 | 1010 |
1011 invalidatePixmapCaches(); | 1011 invalidateImageCaches(); |
1012 invalidateMagnitudes(); | 1012 invalidateMagnitudes(); |
1013 } | 1013 } |
1014 | 1014 |
1015 void | 1015 void |
1016 SpectrogramLayer::cacheInvalid(size_t from, size_t to) | 1016 SpectrogramLayer::cacheInvalid(size_t from, size_t to) |
1017 { | 1017 { |
1018 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1018 #ifdef DEBUG_SPECTROGRAM_REPAINT |
1019 std::cerr << "SpectrogramLayer::cacheInvalid(" << from << ", " << to << ")" << std::endl; | 1019 std::cerr << "SpectrogramLayer::cacheInvalid(" << from << ", " << to << ")" << std::endl; |
1020 #endif | 1020 #endif |
1021 | 1021 |
1022 invalidatePixmapCaches(from, to); | 1022 invalidateImageCaches(from, to); |
1023 invalidateMagnitudes(); | 1023 invalidateMagnitudes(); |
1024 } | 1024 } |
1025 | 1025 |
1026 void | 1026 void |
1027 SpectrogramLayer::fillTimerTimedOut() | 1027 SpectrogramLayer::fillTimerTimedOut() |
1051 if (fill >= lastFill) { | 1051 if (fill >= lastFill) { |
1052 if (fill >= m_model->getEndFrame() && lastFill > 0) { | 1052 if (fill >= m_model->getEndFrame() && lastFill > 0) { |
1053 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1053 #ifdef DEBUG_SPECTROGRAM_REPAINT |
1054 std::cerr << "complete!" << std::endl; | 1054 std::cerr << "complete!" << std::endl; |
1055 #endif | 1055 #endif |
1056 invalidatePixmapCaches(); | 1056 invalidateImageCaches(); |
1057 i->second.second = -1; | 1057 i->second.second = -1; |
1058 emit modelChanged(); | 1058 emit modelChanged(); |
1059 | 1059 |
1060 } else if (fill > lastFill) { | 1060 } else if (fill > lastFill) { |
1061 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1061 #ifdef DEBUG_SPECTROGRAM_REPAINT |
1062 std::cerr << "SpectrogramLayer: emitting modelChanged(" | 1062 std::cerr << "SpectrogramLayer: emitting modelChanged(" |
1063 << lastFill << "," << fill << ")" << std::endl; | 1063 << lastFill << "," << fill << ")" << std::endl; |
1064 #endif | 1064 #endif |
1065 invalidatePixmapCaches(lastFill, fill); | 1065 invalidateImageCaches(lastFill, fill); |
1066 i->second.second = fill; | 1066 i->second.second = fill; |
1067 emit modelChanged(lastFill, fill); | 1067 emit modelChanged(lastFill, fill); |
1068 } | 1068 } |
1069 } else { | 1069 } else { |
1070 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1070 #ifdef DEBUG_SPECTROGRAM_REPAINT |
1071 std::cerr << "SpectrogramLayer: going backwards, emitting modelChanged(" | 1071 std::cerr << "SpectrogramLayer: going backwards, emitting modelChanged(" |
1072 << m_model->getStartFrame() << "," << m_model->getEndFrame() << ")" << std::endl; | 1072 << m_model->getStartFrame() << "," << m_model->getEndFrame() << ")" << std::endl; |
1073 #endif | 1073 #endif |
1074 invalidatePixmapCaches(); | 1074 invalidateImageCaches(); |
1075 i->second.second = fill; | 1075 i->second.second = fill; |
1076 emit modelChanged(m_model->getStartFrame(), m_model->getEndFrame()); | 1076 emit modelChanged(m_model->getStartFrame(), m_model->getEndFrame()); |
1077 } | 1077 } |
1078 | 1078 |
1079 if (i->second.second >= 0) { | 1079 if (i->second.second >= 0) { |
1117 m_crosshairColour = mapper.getContrastingColour(); | 1117 m_crosshairColour = mapper.getContrastingColour(); |
1118 | 1118 |
1119 m_colourRotation = 0; | 1119 m_colourRotation = 0; |
1120 rotatePalette(m_colourRotation - formerRotation); | 1120 rotatePalette(m_colourRotation - formerRotation); |
1121 m_colourRotation = formerRotation; | 1121 m_colourRotation = formerRotation; |
1122 | |
1123 m_drawBuffer = QImage(); | |
1122 } | 1124 } |
1123 | 1125 |
1124 void | 1126 void |
1125 SpectrogramLayer::rotatePalette(int distance) | 1127 SpectrogramLayer::rotatePalette(int distance) |
1126 { | 1128 { |
1136 } | 1138 } |
1137 | 1139 |
1138 for (int pixel = 0; pixel < 256; ++pixel) { | 1140 for (int pixel = 0; pixel < 256; ++pixel) { |
1139 m_palette.setColour(pixel, newPixels[pixel]); | 1141 m_palette.setColour(pixel, newPixels[pixel]); |
1140 } | 1142 } |
1143 | |
1144 m_drawBuffer = QImage(); | |
1141 } | 1145 } |
1142 | 1146 |
1143 unsigned char | 1147 unsigned char |
1144 SpectrogramLayer::getDisplayValue(View *v, float input) const | 1148 SpectrogramLayer::getDisplayValue(View *v, float input) const |
1145 { | 1149 { |
1776 if (!fft) { | 1780 if (!fft) { |
1777 std::cerr << "ERROR: SpectrogramLayer::paint(): No FFT model, returning" << std::endl; | 1781 std::cerr << "ERROR: SpectrogramLayer::paint(): No FFT model, returning" << std::endl; |
1778 return; | 1782 return; |
1779 } | 1783 } |
1780 | 1784 |
1781 PixmapCache &cache = m_pixmapCaches[v]; | 1785 ImageCache &cache = m_imageCaches[v]; |
1782 | 1786 |
1783 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1787 #ifdef DEBUG_SPECTROGRAM_REPAINT |
1784 std::cerr << "SpectrogramLayer::paint(): pixmap cache valid area " << cache. | 1788 std::cerr << "SpectrogramLayer::paint(): image cache valid area " << cache. |
1785 | 1789 |
1786 validArea.x() << ", " << cache.validArea.y() << ", " << cache.validArea.width() << "x" << cache.validArea.height() << std::endl; | 1790 validArea.x() << ", " << cache.validArea.y() << ", " << cache.validArea.width() << "x" << cache.validArea.height() << std::endl; |
1787 #endif | 1791 #endif |
1788 | 1792 |
1789 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1793 #ifdef DEBUG_SPECTROGRAM_REPAINT |
1794 int zoomLevel = v->getZoomLevel(); | 1798 int zoomLevel = v->getZoomLevel(); |
1795 | 1799 |
1796 int x0 = 0; | 1800 int x0 = 0; |
1797 int x1 = v->width(); | 1801 int x1 = v->width(); |
1798 | 1802 |
1799 bool recreateWholePixmapCache = true; | 1803 bool recreateWholeImageCache = true; |
1800 | 1804 |
1801 x0 = rect.left(); | 1805 x0 = rect.left(); |
1802 x1 = rect.right() + 1; | 1806 x1 = rect.right() + 1; |
1803 | 1807 |
1804 if (cache.validArea.width() > 0) { | 1808 if (cache.validArea.width() > 0) { |
1805 | 1809 |
1806 if (int(cache.zoomLevel) == zoomLevel && | 1810 if (int(cache.zoomLevel) == zoomLevel && |
1807 cache.pixmap.width() == v->width() && | 1811 cache.image.width() == v->width() && |
1808 cache.pixmap.height() == v->height()) { | 1812 cache.image.height() == v->height()) { |
1809 | 1813 |
1810 if (v->getXForFrame(cache.startFrame) == | 1814 if (v->getXForFrame(cache.startFrame) == |
1811 v->getXForFrame(startFrame) && | 1815 v->getXForFrame(startFrame) && |
1812 cache.validArea.x() <= x0 && | 1816 cache.validArea.x() <= x0 && |
1813 cache.validArea.x() + cache.validArea.width() >= x1) { | 1817 cache.validArea.x() + cache.validArea.width() >= x1) { |
1814 | 1818 |
1815 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1819 #ifdef DEBUG_SPECTROGRAM_REPAINT |
1816 std::cerr << "SpectrogramLayer: pixmap cache good" << std::endl; | 1820 std::cerr << "SpectrogramLayer: image cache good" << std::endl; |
1817 #endif | 1821 #endif |
1818 | 1822 |
1819 paint.drawPixmap(rect, cache.pixmap, rect); | 1823 paint.drawImage(rect, cache.image, rect); |
1820 illuminateLocalFeatures(v, paint); | 1824 illuminateLocalFeatures(v, paint); |
1821 return; | 1825 return; |
1822 | 1826 |
1823 } else { | 1827 } else { |
1824 | 1828 |
1825 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1829 #ifdef DEBUG_SPECTROGRAM_REPAINT |
1826 std::cerr << "SpectrogramLayer: pixmap cache partially OK" << std::endl; | 1830 std::cerr << "SpectrogramLayer: image cache partially OK" << std::endl; |
1827 #endif | 1831 #endif |
1828 | 1832 |
1829 recreateWholePixmapCache = false; | 1833 recreateWholeImageCache = false; |
1830 | 1834 |
1831 int dx = v->getXForFrame(cache.startFrame) - | 1835 int dx = v->getXForFrame(cache.startFrame) - |
1832 v->getXForFrame(startFrame); | 1836 v->getXForFrame(startFrame); |
1833 | 1837 |
1834 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1838 #ifdef DEBUG_SPECTROGRAM_REPAINT |
1835 std::cerr << "SpectrogramLayer: dx = " << dx << " (pixmap cache " << cache.pixmap.width() << "x" << cache.pixmap.height() << ")" << std::endl; | 1839 std::cerr << "SpectrogramLayer: dx = " << dx << " (image cache " << cache.image.width() << "x" << cache.image.height() << ")" << std::endl; |
1836 #endif | 1840 #endif |
1837 | 1841 |
1838 if (dx != 0 && | 1842 if (dx != 0 && |
1839 dx > -cache.pixmap.width() && | 1843 dx > -cache.image.width() && |
1840 dx < cache.pixmap.width()) { | 1844 dx < cache.image.width()) { |
1841 | 1845 |
1842 QPixmap tmp = cache.pixmap; | 1846 QImage tmp = cache.image; |
1843 QPainter cachePainter(&cache.pixmap); | 1847 QPainter cachePainter(&cache.image); |
1844 if (dx < 0) { | 1848 if (dx < 0) { |
1845 cachePainter.drawPixmap | 1849 cachePainter.drawImage |
1846 (QRect(0, 0, | 1850 (QRect(0, 0, |
1847 cache.pixmap.width() + dx, | 1851 cache.image.width() + dx, |
1848 cache.pixmap.height()), | 1852 cache.image.height()), |
1849 tmp, | 1853 tmp, |
1850 QRect(-dx, 0, | 1854 QRect(-dx, 0, |
1851 cache.pixmap.width() + dx, | 1855 cache.image.width() + dx, |
1852 cache.pixmap.height())); | 1856 cache.image.height())); |
1853 } else { | 1857 } else { |
1854 cachePainter.drawPixmap | 1858 cachePainter.drawImage |
1855 (QRect(dx, 0, | 1859 (QRect(dx, 0, |
1856 cache.pixmap.width() - dx, | 1860 cache.image.width() - dx, |
1857 cache.pixmap.height()), | 1861 cache.image.height()), |
1858 tmp, | 1862 tmp, |
1859 QRect(0, 0, | 1863 QRect(0, 0, |
1860 cache.pixmap.width() - dx, | 1864 cache.image.width() - dx, |
1861 cache.pixmap.height())); | 1865 cache.image.height())); |
1862 } | 1866 } |
1863 | 1867 |
1864 int px = cache.validArea.x(); | 1868 int px = cache.validArea.x(); |
1865 int pw = cache.validArea.width(); | 1869 int pw = cache.validArea.width(); |
1866 | 1870 |
1867 if (dx < 0) { | 1871 if (dx < 0) { |
1868 x0 = cache.pixmap.width() + dx; | 1872 x0 = cache.image.width() + dx; |
1869 x1 = cache.pixmap.width(); | 1873 x1 = cache.image.width(); |
1870 px += dx; | 1874 px += dx; |
1871 if (px < 0) { | 1875 if (px < 0) { |
1872 pw += px; | 1876 pw += px; |
1873 px = 0; | 1877 px = 0; |
1874 if (pw < 0) pw = 0; | 1878 if (pw < 0) pw = 0; |
1875 } | 1879 } |
1876 } else { | 1880 } else { |
1877 x0 = 0; | 1881 x0 = 0; |
1878 x1 = dx; | 1882 x1 = dx; |
1879 px += dx; | 1883 px += dx; |
1880 if (px + pw > cache.pixmap.width()) { | 1884 if (px + pw > cache.image.width()) { |
1881 pw = int(cache.pixmap.width()) - px; | 1885 pw = int(cache.image.width()) - px; |
1882 if (pw < 0) pw = 0; | 1886 if (pw < 0) pw = 0; |
1883 } | 1887 } |
1884 } | 1888 } |
1885 | 1889 |
1886 cache.validArea = | 1890 cache.validArea = |
1892 << px << "," << cache.validArea.y() | 1896 << px << "," << cache.validArea.y() |
1893 << " " << pw << "x" << cache.validArea.height() | 1897 << " " << pw << "x" << cache.validArea.height() |
1894 << std::endl; | 1898 << std::endl; |
1895 #endif | 1899 #endif |
1896 | 1900 |
1897 paint.drawPixmap(rect & cache.validArea, | 1901 paint.drawImage(rect & cache.validArea, |
1898 cache.pixmap, | 1902 cache.image, |
1899 rect & cache.validArea); | 1903 rect & cache.validArea); |
1900 | 1904 |
1901 } else if (dx != 0) { | 1905 } else if (dx != 0) { |
1902 | 1906 |
1903 // we scrolled too far to be of use | 1907 // we scrolled too far to be of use |
1905 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1909 #ifdef DEBUG_SPECTROGRAM_REPAINT |
1906 std::cerr << "dx == " << dx << ": scrolled too far for cache to be useful" << std::endl; | 1910 std::cerr << "dx == " << dx << ": scrolled too far for cache to be useful" << std::endl; |
1907 #endif | 1911 #endif |
1908 | 1912 |
1909 cache.validArea = QRect(); | 1913 cache.validArea = QRect(); |
1910 recreateWholePixmapCache = true; | 1914 recreateWholeImageCache = true; |
1911 } | 1915 } |
1912 } | 1916 } |
1913 } else { | 1917 } else { |
1914 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1918 #ifdef DEBUG_SPECTROGRAM_REPAINT |
1915 std::cerr << "SpectrogramLayer: pixmap cache useless" << std::endl; | 1919 std::cerr << "SpectrogramLayer: image cache useless" << std::endl; |
1916 if (int(cache.zoomLevel) != zoomLevel) { | 1920 if (int(cache.zoomLevel) != zoomLevel) { |
1917 std::cerr << "(cache zoomLevel " << cache.zoomLevel | 1921 std::cerr << "(cache zoomLevel " << cache.zoomLevel |
1918 << " != " << zoomLevel << ")" << std::endl; | 1922 << " != " << zoomLevel << ")" << std::endl; |
1919 } | 1923 } |
1920 if (cache.pixmap.width() != v->width()) { | 1924 if (cache.image.width() != v->width()) { |
1921 std::cerr << "(cache width " << cache.pixmap.width() | 1925 std::cerr << "(cache width " << cache.image.width() |
1922 << " != " << v->width(); | 1926 << " != " << v->width(); |
1923 } | 1927 } |
1924 if (cache.pixmap.height() != v->height()) { | 1928 if (cache.image.height() != v->height()) { |
1925 std::cerr << "(cache height " << cache.pixmap.height() | 1929 std::cerr << "(cache height " << cache.image.height() |
1926 << " != " << v->height(); | 1930 << " != " << v->height(); |
1927 } | 1931 } |
1928 #endif | 1932 #endif |
1929 cache.validArea = QRect(); | 1933 cache.validArea = QRect(); |
1930 // recreateWholePixmapCache = true; | 1934 // recreateWholeImageCache = true; |
1931 } | 1935 } |
1932 } | 1936 } |
1933 | 1937 |
1934 if (updateViewMagnitudes(v)) { | 1938 if (updateViewMagnitudes(v)) { |
1935 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1939 #ifdef DEBUG_SPECTROGRAM_REPAINT |
1936 std::cerr << "SpectrogramLayer: magnitude range changed to [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "]" << std::endl; | 1940 std::cerr << "SpectrogramLayer: magnitude range changed to [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "]" << std::endl; |
1937 #endif | 1941 #endif |
1938 if (m_normalizeVisibleArea) { | 1942 if (m_normalizeVisibleArea) { |
1939 cache.validArea = QRect(); | 1943 cache.validArea = QRect(); |
1940 recreateWholePixmapCache = true; | 1944 recreateWholeImageCache = true; |
1941 } | 1945 } |
1942 } else { | 1946 } else { |
1943 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1947 #ifdef DEBUG_SPECTROGRAM_REPAINT |
1944 std::cerr << "No change in magnitude range [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "]" << std::endl; | 1948 std::cerr << "No change in magnitude range [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "]" << std::endl; |
1945 #endif | 1949 #endif |
1946 } | 1950 } |
1947 | 1951 |
1948 if (recreateWholePixmapCache) { | 1952 if (recreateWholeImageCache) { |
1949 x0 = 0; | 1953 x0 = 0; |
1950 x1 = v->width(); | 1954 x1 = v->width(); |
1951 } | 1955 } |
1952 | 1956 |
1953 struct timeval tv; | 1957 struct timeval tv; |
2065 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2069 #ifdef DEBUG_SPECTROGRAM_REPAINT |
2066 std::cerr << "x0 " << x0 << ", x1 " << x1 << ", w " << w << ", h " << h << std::endl; | 2070 std::cerr << "x0 " << x0 << ", x1 " << x1 << ", w " << w << ", h " << h << std::endl; |
2067 #endif | 2071 #endif |
2068 | 2072 |
2069 if (m_drawBuffer.width() < w || m_drawBuffer.height() < h) { | 2073 if (m_drawBuffer.width() < w || m_drawBuffer.height() < h) { |
2070 m_drawBuffer = QImage(w, h, QImage::Format_RGB32); | 2074 m_drawBuffer = QImage(w, h, QImage::Format_Indexed8); |
2071 } | 2075 m_drawBuffer.setNumColors(256); |
2072 | 2076 for (int pixel = 0; pixel < 256; ++pixel) { |
2073 m_drawBuffer.fill(m_palette.getColour(0).rgb()); | 2077 m_drawBuffer.setColor(pixel, m_palette.getColour(pixel).rgb()); |
2078 } | |
2079 } | |
2080 | |
2081 // m_drawBuffer.fill(m_palette.getColour(0).rgb()); | |
2082 m_drawBuffer.fill(0); | |
2074 | 2083 |
2075 int sr = m_model->getSampleRate(); | 2084 int sr = m_model->getSampleRate(); |
2076 | 2085 |
2077 // Set minFreq and maxFreq to the frequency extents of the possibly | 2086 // Set minFreq and maxFreq to the frequency extents of the possibly |
2078 // zero-padded visible bin range, and displayMinFreq and displayMaxFreq | 2087 // zero-padded visible bin range, and displayMinFreq and displayMaxFreq |
2115 } | 2124 } |
2116 | 2125 |
2117 // std::cerr << "(giving actual minFreq " << minFreq << " and display minFreq " << displayMinFreq << ")" << std::endl; | 2126 // std::cerr << "(giving actual minFreq " << minFreq << " and display minFreq " << displayMinFreq << ")" << std::endl; |
2118 | 2127 |
2119 float yforbin[maxbin - minbin + 1]; | 2128 float yforbin[maxbin - minbin + 1]; |
2120 float yval[h]; | |
2121 | 2129 |
2122 size_t increment = getWindowIncrement(); | 2130 size_t increment = getWindowIncrement(); |
2123 | 2131 |
2124 bool logarithmic = (m_frequencyScale == LogFrequencyScale); | 2132 bool logarithmic = (m_frequencyScale == LogFrequencyScale); |
2125 | 2133 |
2153 | 2161 |
2154 for (int x = 0; x < w; ++x) { | 2162 for (int x = 0; x < w; ++x) { |
2155 | 2163 |
2156 Profiler innerprof("SpectrogramLayer::paint: 1 pixel column"); | 2164 Profiler innerprof("SpectrogramLayer::paint: 1 pixel column"); |
2157 | 2165 |
2158 runOutOfData = !getColumnValues(v, fft, x0, x, | 2166 runOutOfData = !paintColumnValues(v, fft, x0, x, |
2159 minbin, maxbin, | 2167 minbin, maxbin, |
2160 displayMinFreq, displayMaxFreq, | 2168 displayMinFreq, displayMaxFreq, |
2161 h, yforbin, yval); | 2169 h, yforbin); |
2162 | 2170 |
2163 if (runOutOfData) { | 2171 if (runOutOfData) { |
2164 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2172 #ifdef DEBUG_SPECTROGRAM_REPAINT |
2165 std::cerr << "Run out of data -- dropping out of loop" << std::endl; | 2173 std::cerr << "Run out of data -- dropping out of loop" << std::endl; |
2166 #endif | 2174 #endif |
2167 break; | 2175 break; |
2168 } | 2176 } |
2169 | |
2170 Profiler drawbufferprof("SpectrogramLayer::paint: set buffer pixels"); | |
2171 | |
2172 for (int y = 0; y < h; ++y) { | |
2173 | |
2174 unsigned char pixel = 0; | |
2175 | |
2176 pixel = getDisplayValue(v, yval[y]); | |
2177 | |
2178 assert(x <= m_drawBuffer.width()); | |
2179 QColor c = m_palette.getColour(pixel); | |
2180 m_drawBuffer.setPixel(x, y, | |
2181 qRgb(c.red(), c.green(), c.blue())); | |
2182 #ifdef DEBUG_SPECTROGRAM_REPAINT | |
2183 ++pixels; | |
2184 #endif | |
2185 } | |
2186 } | 2177 } |
2187 | 2178 |
2188 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2179 #ifdef DEBUG_SPECTROGRAM_REPAINT |
2189 std::cerr << pixels << " pixels drawn" << std::endl; | 2180 std::cerr << pixels << " pixels drawn" << std::endl; |
2190 #endif | 2181 #endif |
2202 | 2193 |
2203 outerprof.end(); | 2194 outerprof.end(); |
2204 | 2195 |
2205 Profiler profiler2("SpectrogramLayer::paint: draw image"); | 2196 Profiler profiler2("SpectrogramLayer::paint: draw image"); |
2206 | 2197 |
2207 if (recreateWholePixmapCache) { | 2198 if (recreateWholeImageCache) { |
2208 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2199 #ifdef DEBUG_SPECTROGRAM_REPAINT |
2209 std::cerr << "Recreating pixmap cache: width = " << v->width() | 2200 std::cerr << "Recreating image cache: width = " << v->width() |
2210 << ", height = " << h << std::endl; | 2201 << ", height = " << h << std::endl; |
2211 #endif | 2202 #endif |
2212 cache.pixmap = QPixmap(v->width(), h); | 2203 cache.image = QImage(v->width(), h, QImage::Format_RGB32); |
2213 } | 2204 } |
2214 | 2205 |
2215 if (w > 0) { | 2206 if (w > 0) { |
2216 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2207 #ifdef DEBUG_SPECTROGRAM_REPAINT |
2217 std::cerr << "Painting " << w << "x" << h | 2208 std::cerr << "Painting " << w << "x" << h |
2218 << " from draw buffer at " << 0 << "," << 0 | 2209 << " from draw buffer at " << 0 << "," << 0 |
2219 << " to cache at " << x0 << "," << 0 << std::endl; | 2210 << " to cache at " << x0 << "," << 0 << std::endl; |
2220 #endif | 2211 #endif |
2221 | 2212 |
2222 QPainter cachePainter(&cache.pixmap); | 2213 QPainter cachePainter(&cache.image); |
2223 cachePainter.drawImage(x0, 0, m_drawBuffer, 0, 0, w, h); | 2214 cachePainter.drawImage(x0, 0, m_drawBuffer, 0, 0, w, h); |
2224 cachePainter.end(); | 2215 cachePainter.end(); |
2225 } | 2216 } |
2226 | 2217 |
2227 QRect pr = rect & cache.validArea; | 2218 QRect pr = rect & cache.validArea; |
2230 std::cerr << "Painting " << pr.width() << "x" << pr.height() | 2221 std::cerr << "Painting " << pr.width() << "x" << pr.height() |
2231 << " from cache at " << pr.x() << "," << pr.y() | 2222 << " from cache at " << pr.x() << "," << pr.y() |
2232 << " to window" << std::endl; | 2223 << " to window" << std::endl; |
2233 #endif | 2224 #endif |
2234 | 2225 |
2235 paint.drawPixmap(pr.x(), pr.y(), cache.pixmap, | 2226 paint.drawImage(pr.x(), pr.y(), cache.image, |
2236 pr.x(), pr.y(), pr.width(), pr.height()); | 2227 pr.x(), pr.y(), pr.width(), pr.height()); |
2237 | 2228 |
2238 cache.startFrame = startFrame; | 2229 cache.startFrame = startFrame; |
2239 cache.zoomLevel = zoomLevel; | 2230 cache.zoomLevel = zoomLevel; |
2240 | 2231 |
2249 #endif | 2240 #endif |
2250 v->update(0, 0, cache.validArea.x(), h); | 2241 v->update(0, 0, cache.validArea.x(), h); |
2251 } | 2242 } |
2252 | 2243 |
2253 if (cache.validArea.x() + cache.validArea.width() < | 2244 if (cache.validArea.x() + cache.validArea.width() < |
2254 cache.pixmap.width()) { | 2245 cache.image.width()) { |
2255 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2246 #ifdef DEBUG_SPECTROGRAM_REPAINT |
2256 std::cerr << "SpectrogramLayer::paint() updating right (" | 2247 std::cerr << "SpectrogramLayer::paint() updating right (" |
2257 << cache.validArea.x() + cache.validArea.width() | 2248 << cache.validArea.x() + cache.validArea.width() |
2258 << ", " | 2249 << ", " |
2259 << cache.pixmap.width() - (cache.validArea.x() + | 2250 << cache.image.width() - (cache.validArea.x() + |
2260 cache.validArea.width()) | 2251 cache.validArea.width()) |
2261 << ")" << std::endl; | 2252 << ")" << std::endl; |
2262 #endif | 2253 #endif |
2263 v->update(cache.validArea.x() + cache.validArea.width(), | 2254 v->update(cache.validArea.x() + cache.validArea.width(), |
2264 0, | 2255 0, |
2265 cache.pixmap.width() - (cache.validArea.x() + | 2256 cache.image.width() - (cache.validArea.x() + |
2266 cache.validArea.width()), | 2257 cache.validArea.width()), |
2267 h); | 2258 h); |
2268 } | 2259 } |
2269 } else { | 2260 } else { |
2270 // overallMagChanged | 2261 // overallMagChanged |
2289 //!!! if (fftSuspended) fft->resume(); | 2280 //!!! if (fftSuspended) fft->resume(); |
2290 } | 2281 } |
2291 | 2282 |
2292 | 2283 |
2293 bool | 2284 bool |
2294 SpectrogramLayer::getColumnValues(View *v, | 2285 SpectrogramLayer::paintColumnValues(View *v, |
2295 FFTModel *fft, | 2286 FFTModel *fft, |
2296 int x0, | 2287 int x0, |
2297 int x, | 2288 int x, |
2298 int minbin, | 2289 int minbin, |
2299 int maxbin, | 2290 int maxbin, |
2300 float displayMinFreq, | 2291 float displayMinFreq, |
2301 float displayMaxFreq, | 2292 float displayMaxFreq, |
2302 const int h, | 2293 const int h, |
2303 const float *yforbin, | 2294 const float *yforbin) const |
2304 float *yval) const | |
2305 { | 2295 { |
2306 float ymag[h]; | 2296 float ymag[h]; |
2307 float ydiv[h]; | 2297 float ydiv[h]; |
2308 float values[maxbin - minbin + 1]; | 2298 float values[maxbin - minbin + 1]; |
2309 | 2299 |
2330 if (!getXBinRange(v, x0 + x, s0, s1)) { | 2320 if (!getXBinRange(v, x0 + x, s0, s1)) { |
2331 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2321 #ifdef DEBUG_SPECTROGRAM_REPAINT |
2332 std::cerr << "Out of range at " << x0 + x << std::endl; | 2322 std::cerr << "Out of range at " << x0 + x << std::endl; |
2333 #endif | 2323 #endif |
2334 assert(x <= m_drawBuffer.width()); | 2324 assert(x <= m_drawBuffer.width()); |
2335 return false; | 2325 return true; |
2336 } | 2326 } |
2337 | 2327 |
2338 int s0i = int(s0 + 0.001); | 2328 int s0i = int(s0 + 0.001); |
2339 int s1i = int(s1); | 2329 int s1i = int(s1); |
2340 | 2330 |
2341 if (s1i >= int(fft->getWidth())) { | 2331 if (s1i >= int(fft->getWidth())) { |
2342 if (s0i >= int(fft->getWidth())) { | 2332 if (s0i >= int(fft->getWidth())) { |
2343 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2333 #ifdef DEBUG_SPECTROGRAM_REPAINT |
2344 std::cerr << "Column " << s0i << " out of range" << std::endl; | 2334 std::cerr << "Column " << s0i << " out of range" << std::endl; |
2345 #endif | 2335 #endif |
2346 return false; | 2336 return true; |
2347 } else { | 2337 } else { |
2348 s1i = s0i; | 2338 s1i = s0i; |
2349 } | 2339 } |
2350 } | 2340 } |
2351 | 2341 |
2511 } | 2501 } |
2512 } | 2502 } |
2513 | 2503 |
2514 for (int y = 0; y < h; ++y) { | 2504 for (int y = 0; y < h; ++y) { |
2515 | 2505 |
2506 float value = 0.f; | |
2507 | |
2516 if (ydiv[y] > 0.0) { | 2508 if (ydiv[y] > 0.0) { |
2517 yval[y] = ymag[y] / ydiv[y]; | 2509 value = ymag[y] / ydiv[y]; |
2518 } else { | 2510 } |
2519 yval[y] = 0; | 2511 |
2520 } | 2512 unsigned char pixel = getDisplayValue(v, value); |
2513 m_drawBuffer.setPixel(x, y, pixel); | |
2521 } | 2514 } |
2522 | 2515 |
2523 return true; | 2516 return true; |
2524 } | 2517 } |
2525 | 2518 |
2632 size_t minf = lrintf(min); | 2625 size_t minf = lrintf(min); |
2633 size_t maxf = lrintf(max); | 2626 size_t maxf = lrintf(max); |
2634 | 2627 |
2635 if (m_minFrequency == minf && m_maxFrequency == maxf) return true; | 2628 if (m_minFrequency == minf && m_maxFrequency == maxf) return true; |
2636 | 2629 |
2637 invalidatePixmapCaches(); | 2630 invalidateImageCaches(); |
2638 invalidateMagnitudes(); | 2631 invalidateMagnitudes(); |
2639 | 2632 |
2640 m_minFrequency = minf; | 2633 m_minFrequency = minf; |
2641 m_maxFrequency = maxf; | 2634 m_maxFrequency = maxf; |
2642 | 2635 |
2683 } | 2676 } |
2684 | 2677 |
2685 void | 2678 void |
2686 SpectrogramLayer::measureDoubleClick(View *v, QMouseEvent *e) | 2679 SpectrogramLayer::measureDoubleClick(View *v, QMouseEvent *e) |
2687 { | 2680 { |
2688 PixmapCache &cache = m_pixmapCaches[v]; | 2681 ImageCache &cache = m_imageCaches[v]; |
2689 | 2682 |
2690 std::cerr << "cache width: " << cache.pixmap.width() << ", height: " | 2683 std::cerr << "cache width: " << cache.image.width() << ", height: " |
2691 << cache.pixmap.height() << std::endl; | 2684 << cache.image.height() << std::endl; |
2692 | 2685 |
2693 QImage image = cache.pixmap.toImage(); | 2686 QImage image = cache.image; |
2694 | 2687 |
2695 ImageRegionFinder finder; | 2688 ImageRegionFinder finder; |
2696 QRect rect = finder.findRegionExtents(&image, e->pos()); | 2689 QRect rect = finder.findRegionExtents(&image, e->pos()); |
2697 if (rect.isValid()) { | 2690 if (rect.isValid()) { |
2698 MeasureRect mr; | 2691 MeasureRect mr; |