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;