Mercurial > hg > svgui
comparison layer/SpectrogramLayer.cpp @ 95:1b3996a86cfa
* Incremental refresh of spectrogram layer
author | Chris Cannam |
---|---|
date | Tue, 09 May 2006 16:18:59 +0000 |
parents | 05c41701dc6c |
children | 095916d7ed4d |
comparison
equal
deleted
inserted
replaced
94:c7ade7ea3cfe | 95:1b3996a86cfa |
---|---|
67 m_binDisplay(AllBins), | 67 m_binDisplay(AllBins), |
68 m_normalizeColumns(false), | 68 m_normalizeColumns(false), |
69 m_cache(0), | 69 m_cache(0), |
70 m_writeCache(0), | 70 m_writeCache(0), |
71 m_cacheInvalid(true), | 71 m_cacheInvalid(true), |
72 m_pixmapCache(0), | |
73 m_pixmapCacheInvalid(true), | |
74 m_fillThread(0), | 72 m_fillThread(0), |
75 m_updateTimer(0), | 73 m_updateTimer(0), |
76 m_candidateFillStartFrame(0), | 74 m_candidateFillStartFrame(0), |
77 m_lastFillExtent(0), | 75 m_lastFillExtent(0), |
78 m_exiting(false) | 76 m_exiting(false) |
517 setNormalizeColumns(value ? true : false); | 515 setNormalizeColumns(value ? true : false); |
518 } | 516 } |
519 } | 517 } |
520 | 518 |
521 void | 519 void |
520 SpectrogramLayer::invalidatePixmapCaches() | |
521 { | |
522 for (ViewPixmapCache::iterator i = m_pixmapCaches.begin(); | |
523 i != m_pixmapCaches.end(); ++i) { | |
524 i->second.validArea = QRect(); | |
525 } | |
526 } | |
527 | |
528 void | |
529 SpectrogramLayer::invalidatePixmapCaches(size_t startFrame, size_t endFrame) | |
530 { | |
531 for (ViewPixmapCache::iterator i = m_pixmapCaches.begin(); | |
532 i != m_pixmapCaches.end(); ++i) { | |
533 //!!! when are views removed from the map? on setLayerDormant? | |
534 const View *v = i->first; | |
535 | |
536 if (startFrame < v->getEndFrame() && endFrame >= v->getStartFrame()) { | |
537 i->second.validArea = QRect(); | |
538 } | |
539 } | |
540 } | |
541 | |
542 void | |
522 SpectrogramLayer::setChannel(int ch) | 543 SpectrogramLayer::setChannel(int ch) |
523 { | 544 { |
524 if (m_channel == ch) return; | 545 if (m_channel == ch) return; |
525 | 546 |
526 m_mutex.lock(); | 547 m_mutex.lock(); |
527 m_cacheInvalid = true; | 548 m_cacheInvalid = true; |
528 m_pixmapCacheInvalid = true; | 549 invalidatePixmapCaches(); |
529 | 550 |
530 m_channel = ch; | 551 m_channel = ch; |
531 | 552 |
532 m_mutex.unlock(); | 553 m_mutex.unlock(); |
533 | 554 |
547 { | 568 { |
548 if (m_windowSize == ws) return; | 569 if (m_windowSize == ws) return; |
549 | 570 |
550 m_mutex.lock(); | 571 m_mutex.lock(); |
551 m_cacheInvalid = true; | 572 m_cacheInvalid = true; |
552 m_pixmapCacheInvalid = true; | 573 invalidatePixmapCaches(); |
553 | 574 |
554 m_windowSize = ws; | 575 m_windowSize = ws; |
555 | 576 |
556 m_mutex.unlock(); | 577 m_mutex.unlock(); |
557 | 578 |
571 { | 592 { |
572 if (m_windowOverlap == wi) return; | 593 if (m_windowOverlap == wi) return; |
573 | 594 |
574 m_mutex.lock(); | 595 m_mutex.lock(); |
575 m_cacheInvalid = true; | 596 m_cacheInvalid = true; |
576 m_pixmapCacheInvalid = true; | 597 invalidatePixmapCaches(); |
577 | 598 |
578 m_windowOverlap = wi; | 599 m_windowOverlap = wi; |
579 | 600 |
580 m_mutex.unlock(); | 601 m_mutex.unlock(); |
581 | 602 |
595 { | 616 { |
596 if (m_windowType == w) return; | 617 if (m_windowType == w) return; |
597 | 618 |
598 m_mutex.lock(); | 619 m_mutex.lock(); |
599 m_cacheInvalid = true; | 620 m_cacheInvalid = true; |
600 m_pixmapCacheInvalid = true; | 621 invalidatePixmapCaches(); |
601 | 622 |
602 m_windowType = w; | 623 m_windowType = w; |
603 | 624 |
604 m_mutex.unlock(); | 625 m_mutex.unlock(); |
605 | 626 |
621 << m_gain << ")" << std::endl; | 642 << m_gain << ")" << std::endl; |
622 | 643 |
623 if (m_gain == gain) return; | 644 if (m_gain == gain) return; |
624 | 645 |
625 m_mutex.lock(); | 646 m_mutex.lock(); |
626 m_pixmapCacheInvalid = true; | 647 invalidatePixmapCaches(); |
627 | 648 |
628 m_gain = gain; | 649 m_gain = gain; |
629 | 650 |
630 m_mutex.unlock(); | 651 m_mutex.unlock(); |
631 | 652 |
644 SpectrogramLayer::setThreshold(float threshold) | 665 SpectrogramLayer::setThreshold(float threshold) |
645 { | 666 { |
646 if (m_threshold == threshold) return; | 667 if (m_threshold == threshold) return; |
647 | 668 |
648 m_mutex.lock(); | 669 m_mutex.lock(); |
649 m_pixmapCacheInvalid = true; | 670 invalidatePixmapCaches(); |
650 | 671 |
651 m_threshold = threshold; | 672 m_threshold = threshold; |
652 | 673 |
653 m_mutex.unlock(); | 674 m_mutex.unlock(); |
654 | 675 |
667 SpectrogramLayer::setMinFrequency(size_t mf) | 688 SpectrogramLayer::setMinFrequency(size_t mf) |
668 { | 689 { |
669 if (m_minFrequency == mf) return; | 690 if (m_minFrequency == mf) return; |
670 | 691 |
671 m_mutex.lock(); | 692 m_mutex.lock(); |
672 m_pixmapCacheInvalid = true; | 693 invalidatePixmapCaches(); |
673 | 694 |
674 m_minFrequency = mf; | 695 m_minFrequency = mf; |
675 | 696 |
676 m_mutex.unlock(); | 697 m_mutex.unlock(); |
677 | 698 |
688 SpectrogramLayer::setMaxFrequency(size_t mf) | 709 SpectrogramLayer::setMaxFrequency(size_t mf) |
689 { | 710 { |
690 if (m_maxFrequency == mf) return; | 711 if (m_maxFrequency == mf) return; |
691 | 712 |
692 m_mutex.lock(); | 713 m_mutex.lock(); |
693 m_pixmapCacheInvalid = true; | 714 invalidatePixmapCaches(); |
694 | 715 |
695 m_maxFrequency = mf; | 716 m_maxFrequency = mf; |
696 | 717 |
697 m_mutex.unlock(); | 718 m_mutex.unlock(); |
698 | 719 |
707 | 728 |
708 void | 729 void |
709 SpectrogramLayer::setColourRotation(int r) | 730 SpectrogramLayer::setColourRotation(int r) |
710 { | 731 { |
711 m_mutex.lock(); | 732 m_mutex.lock(); |
712 m_pixmapCacheInvalid = true; | 733 invalidatePixmapCaches(); |
713 | 734 |
714 if (r < 0) r = 0; | 735 if (r < 0) r = 0; |
715 if (r > 256) r = 256; | 736 if (r > 256) r = 256; |
716 int distance = r - m_colourRotation; | 737 int distance = r - m_colourRotation; |
717 | 738 |
729 SpectrogramLayer::setColourScale(ColourScale colourScale) | 750 SpectrogramLayer::setColourScale(ColourScale colourScale) |
730 { | 751 { |
731 if (m_colourScale == colourScale) return; | 752 if (m_colourScale == colourScale) return; |
732 | 753 |
733 m_mutex.lock(); | 754 m_mutex.lock(); |
734 m_pixmapCacheInvalid = true; | 755 invalidatePixmapCaches(); |
735 | 756 |
736 m_colourScale = colourScale; | 757 m_colourScale = colourScale; |
737 | 758 |
738 m_mutex.unlock(); | 759 m_mutex.unlock(); |
739 fillCache(); | 760 fillCache(); |
751 SpectrogramLayer::setColourScheme(ColourScheme scheme) | 772 SpectrogramLayer::setColourScheme(ColourScheme scheme) |
752 { | 773 { |
753 if (m_colourScheme == scheme) return; | 774 if (m_colourScheme == scheme) return; |
754 | 775 |
755 m_mutex.lock(); | 776 m_mutex.lock(); |
756 m_pixmapCacheInvalid = true; | 777 invalidatePixmapCaches(); |
757 | 778 |
758 m_colourScheme = scheme; | 779 m_colourScheme = scheme; |
759 setColourmap(); | 780 setColourmap(); |
760 | 781 |
761 m_mutex.unlock(); | 782 m_mutex.unlock(); |
774 { | 795 { |
775 if (m_frequencyScale == frequencyScale) return; | 796 if (m_frequencyScale == frequencyScale) return; |
776 | 797 |
777 m_mutex.lock(); | 798 m_mutex.lock(); |
778 | 799 |
779 m_pixmapCacheInvalid = true; | 800 invalidatePixmapCaches(); |
780 | 801 |
781 m_frequencyScale = frequencyScale; | 802 m_frequencyScale = frequencyScale; |
782 | 803 |
783 m_mutex.unlock(); | 804 m_mutex.unlock(); |
784 | 805 |
796 { | 817 { |
797 if (m_binDisplay == binDisplay) return; | 818 if (m_binDisplay == binDisplay) return; |
798 | 819 |
799 m_mutex.lock(); | 820 m_mutex.lock(); |
800 | 821 |
801 m_pixmapCacheInvalid = true; | 822 invalidatePixmapCaches(); |
802 | 823 |
803 m_binDisplay = binDisplay; | 824 m_binDisplay = binDisplay; |
804 | 825 |
805 m_mutex.unlock(); | 826 m_mutex.unlock(); |
806 | 827 |
819 SpectrogramLayer::setNormalizeColumns(bool n) | 840 SpectrogramLayer::setNormalizeColumns(bool n) |
820 { | 841 { |
821 if (m_normalizeColumns == n) return; | 842 if (m_normalizeColumns == n) return; |
822 m_mutex.lock(); | 843 m_mutex.lock(); |
823 | 844 |
824 m_pixmapCacheInvalid = true; | 845 invalidatePixmapCaches(); |
825 m_normalizeColumns = n; | 846 m_normalizeColumns = n; |
826 m_mutex.unlock(); | 847 m_mutex.unlock(); |
827 | 848 |
828 fillCache(); | 849 fillCache(); |
829 emit layerParametersChanged(); | 850 emit layerParametersChanged(); |
848 | 869 |
849 // delete m_cache; | 870 // delete m_cache; |
850 // m_cache = 0; | 871 // m_cache = 0; |
851 | 872 |
852 m_cacheInvalid = true; | 873 m_cacheInvalid = true; |
853 m_pixmapCacheInvalid = true; | 874 invalidatePixmapCaches(); |
854 delete m_pixmapCache; | 875 m_pixmapCaches.erase(v); |
855 m_pixmapCache = 0; | |
856 | 876 |
857 } else { | 877 } else { |
858 | 878 |
859 m_dormancy[v] = false; | 879 m_dormancy[v] = false; |
860 } | 880 } |
862 | 882 |
863 void | 883 void |
864 SpectrogramLayer::cacheInvalid() | 884 SpectrogramLayer::cacheInvalid() |
865 { | 885 { |
866 m_cacheInvalid = true; | 886 m_cacheInvalid = true; |
867 m_pixmapCacheInvalid = true; | 887 invalidatePixmapCaches(); |
868 fillCache(); | 888 fillCache(); |
869 } | 889 } |
870 | 890 |
871 void | 891 void |
872 SpectrogramLayer::cacheInvalid(size_t, size_t) | 892 SpectrogramLayer::cacheInvalid(size_t, size_t) |
910 if (fillExtent >= m_lastFillExtent) { | 930 if (fillExtent >= m_lastFillExtent) { |
911 if (fillExtent >= m_model->getEndFrame() && m_lastFillExtent > 0) { | 931 if (fillExtent >= m_model->getEndFrame() && m_lastFillExtent > 0) { |
912 #ifdef DEBUG_SPECTROGRAM_REPAINT | 932 #ifdef DEBUG_SPECTROGRAM_REPAINT |
913 std::cerr << "complete!" << std::endl; | 933 std::cerr << "complete!" << std::endl; |
914 #endif | 934 #endif |
915 m_pixmapCacheInvalid = true; | 935 invalidatePixmapCaches(); |
916 emit modelChanged(); | 936 emit modelChanged(); |
917 delete m_updateTimer; | 937 delete m_updateTimer; |
918 m_updateTimer = 0; | 938 m_updateTimer = 0; |
919 m_lastFillExtent = 0; | 939 m_lastFillExtent = 0; |
920 } else if (fillExtent > m_lastFillExtent) { | 940 } else if (fillExtent > m_lastFillExtent) { |
921 #ifdef DEBUG_SPECTROGRAM_REPAINT | 941 #ifdef DEBUG_SPECTROGRAM_REPAINT |
922 std::cerr << "SpectrogramLayer: emitting modelChanged(" | 942 std::cerr << "SpectrogramLayer: emitting modelChanged(" |
923 << m_lastFillExtent << "," << fillExtent << ")" << std::endl; | 943 << m_lastFillExtent << "," << fillExtent << ")" << std::endl; |
924 #endif | 944 #endif |
925 m_pixmapCacheInvalid = true; | 945 invalidatePixmapCaches(m_lastFillExtent, fillExtent); |
926 emit modelChanged(m_lastFillExtent, fillExtent); | 946 emit modelChanged(m_lastFillExtent, fillExtent); |
927 m_lastFillExtent = fillExtent; | 947 m_lastFillExtent = fillExtent; |
928 } | 948 } |
929 } else { | 949 } else { |
930 // if (v) { | 950 // if (v) { |
932 //!!! if (v->getStartFrame() > 0) sf = v->getStartFrame(); | 952 //!!! if (v->getStartFrame() > 0) sf = v->getStartFrame(); |
933 #ifdef DEBUG_SPECTROGRAM_REPAINT | 953 #ifdef DEBUG_SPECTROGRAM_REPAINT |
934 std::cerr << "SpectrogramLayer: going backwards, emitting modelChanged(" | 954 std::cerr << "SpectrogramLayer: going backwards, emitting modelChanged(" |
935 << sf << "," << m_model->getEndFrame() << ")" << std::endl; | 955 << sf << "," << m_model->getEndFrame() << ")" << std::endl; |
936 #endif | 956 #endif |
937 m_pixmapCacheInvalid = true; | 957 invalidatePixmapCaches(); |
938 emit modelChanged(sf, m_model->getEndFrame()); | 958 emit modelChanged(sf, m_model->getEndFrame()); |
939 // } | 959 // } |
940 m_lastFillExtent = fillExtent; | 960 m_lastFillExtent = fillExtent; |
941 } | 961 } |
942 } | 962 } |
1692 v->setLightBackground(false); | 1712 v->setLightBackground(false); |
1693 } | 1713 } |
1694 | 1714 |
1695 // Profiler profiler("SpectrogramLayer::paint", true); | 1715 // Profiler profiler("SpectrogramLayer::paint", true); |
1696 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1716 #ifdef DEBUG_SPECTROGRAM_REPAINT |
1697 std::cerr << "SpectrogramLayer::paint(): m_model is " << m_model << ", zoom level is " << v->getZoomLevel() << ", m_updateTimer " << m_updateTimer << ", pixmap cache invalid " << m_pixmapCacheInvalid << std::endl; | 1717 std::cerr << "SpectrogramLayer::paint(): m_model is " << m_model << ", zoom level is " << v->getZoomLevel() << ", m_updateTimer " << m_updateTimer << std::endl; |
1718 | |
1719 std::cerr << "rect is " << rect.x() << "," << rect.y() << " " << rect.width() << "x" << rect.height() << std::endl; | |
1698 #endif | 1720 #endif |
1699 | 1721 |
1700 long sf = v->getStartFrame(); | 1722 long sf = v->getStartFrame(); |
1701 if (sf < 0) m_candidateFillStartFrame = 0; | 1723 if (sf < 0) m_candidateFillStartFrame = 0; |
1702 else m_candidateFillStartFrame = sf; | 1724 else m_candidateFillStartFrame = sf; |
1703 | 1725 |
1704 if (!m_model || !m_model->isOK() || !m_model->isReady()) { | 1726 if (!m_model || !m_model->isOK() || !m_model->isReady()) { |
1714 // and accountable for when determining whether we need the cache | 1736 // and accountable for when determining whether we need the cache |
1715 // in the cache-fill thread above. | 1737 // in the cache-fill thread above. |
1716 m_dormancy[v] = false; | 1738 m_dormancy[v] = false; |
1717 | 1739 |
1718 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1740 #ifdef DEBUG_SPECTROGRAM_REPAINT |
1719 std::cerr << "SpectrogramLayer::paint(): About to lock" << std::endl; | 1741 // std::cerr << "SpectrogramLayer::paint(): About to lock" << std::endl; |
1720 #endif | 1742 #endif |
1721 | 1743 |
1722 m_mutex.lock(); | 1744 m_mutex.lock(); |
1723 | 1745 |
1724 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1746 #ifdef DEBUG_SPECTROGRAM_REPAINT |
1725 std::cerr << "SpectrogramLayer::paint(): locked" << std::endl; | 1747 // std::cerr << "SpectrogramLayer::paint(): locked" << std::endl; |
1726 #endif | 1748 #endif |
1727 | 1749 |
1728 if (m_cacheInvalid) { // lock the mutex before checking this | 1750 if (m_cacheInvalid) { // lock the mutex before checking this |
1729 m_mutex.unlock(); | 1751 m_mutex.unlock(); |
1730 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1752 #ifdef DEBUG_SPECTROGRAM_REPAINT |
1731 std::cerr << "SpectrogramLayer::paint(): Cache invalid, returning" << std::endl; | 1753 std::cerr << "SpectrogramLayer::paint(): Cache invalid, returning" << std::endl; |
1732 #endif | 1754 #endif |
1733 return; | 1755 return; |
1734 } | 1756 } |
1735 | 1757 |
1758 PixmapCache &cache = m_pixmapCaches[v]; | |
1759 | |
1760 #ifdef DEBUG_SPECTROGRAM_REPAINT | |
1761 std::cerr << "SpectrogramLayer::paint(): pixmap cache valid area " << cache.validArea.x() << ", " << cache.validArea.y() << ", " << cache.validArea.width() << "x" << cache.validArea.height() << std::endl; | |
1762 #endif | |
1763 | |
1736 bool stillCacheing = (m_updateTimer != 0); | 1764 bool stillCacheing = (m_updateTimer != 0); |
1737 | 1765 |
1738 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1766 #ifdef DEBUG_SPECTROGRAM_REPAINT |
1739 std::cerr << "SpectrogramLayer::paint(): Still cacheing = " << stillCacheing << std::endl; | 1767 std::cerr << "SpectrogramLayer::paint(): Still cacheing = " << stillCacheing << std::endl; |
1740 #endif | 1768 #endif |
1747 int y0 = 0; | 1775 int y0 = 0; |
1748 int y1 = v->height(); | 1776 int y1 = v->height(); |
1749 | 1777 |
1750 bool recreateWholePixmapCache = true; | 1778 bool recreateWholePixmapCache = true; |
1751 | 1779 |
1752 // if (stillCacheing) { | 1780 x0 = rect.left(); |
1753 x0 = rect.left(); | 1781 x1 = rect.right() + 1; |
1754 x1 = rect.right() + 1; | 1782 y0 = rect.top(); |
1755 y0 = rect.top(); | 1783 y1 = rect.bottom() + 1; |
1756 y1 = rect.bottom() + 1; | 1784 |
1757 // } | 1785 if (cache.validArea.width() > 0) { |
1758 | 1786 |
1759 if (!m_pixmapCacheInvalid) { | 1787 if (int(cache.zoomLevel) == zoomLevel && |
1760 | 1788 cache.pixmap.width() == v->width() && |
1761 //!!! This cache may have been obsoleted entirely by the | 1789 cache.pixmap.height() == v->height()) { |
1762 //scrolling cache in View. Perhaps experiment with | 1790 |
1763 //removing it and see if it makes things even quicker (or else | 1791 if (v->getXForFrame(cache.startFrame) == |
1764 //make it optional) | 1792 v->getXForFrame(startFrame) && |
1765 | 1793 cache.validArea.x() <= x0 && |
1766 if (int(m_pixmapCacheZoomLevel) == zoomLevel && | 1794 cache.validArea.x() + cache.validArea.width() >= x1) { |
1767 m_pixmapCache->width() == v->width() && | |
1768 m_pixmapCache->height() == v->height()) { | |
1769 | |
1770 if (v->getXForFrame(m_pixmapCacheStartFrame) == | |
1771 v->getXForFrame(startFrame)) { | |
1772 | 1795 |
1773 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1796 #ifdef DEBUG_SPECTROGRAM_REPAINT |
1774 std::cerr << "SpectrogramLayer: pixmap cache good" << std::endl; | 1797 std::cerr << "SpectrogramLayer: pixmap cache good" << std::endl; |
1775 #endif | 1798 #endif |
1776 | 1799 |
1777 m_mutex.unlock(); | 1800 m_mutex.unlock(); |
1778 paint.drawPixmap(rect, *m_pixmapCache, rect); | 1801 paint.drawPixmap(rect, cache.pixmap, rect); |
1779 return; | 1802 return; |
1780 | 1803 |
1781 } else { | 1804 } else { |
1782 | 1805 |
1783 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1806 #ifdef DEBUG_SPECTROGRAM_REPAINT |
1784 std::cerr << "SpectrogramLayer: pixmap cache partially OK" << std::endl; | 1807 std::cerr << "SpectrogramLayer: pixmap cache partially OK" << std::endl; |
1785 #endif | 1808 #endif |
1786 | 1809 |
1787 recreateWholePixmapCache = false; | 1810 recreateWholePixmapCache = false; |
1788 | 1811 |
1789 int dx = v->getXForFrame(m_pixmapCacheStartFrame) - | 1812 int dx = v->getXForFrame(cache.startFrame) - |
1790 v->getXForFrame(startFrame); | 1813 v->getXForFrame(startFrame); |
1791 | 1814 |
1792 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1815 #ifdef DEBUG_SPECTROGRAM_REPAINT |
1793 std::cerr << "SpectrogramLayer: dx = " << dx << " (pixmap cache " << m_pixmapCache->width() << "x" << m_pixmapCache->height() << ")" << std::endl; | 1816 std::cerr << "SpectrogramLayer: dx = " << dx << " (pixmap cache " << cache.pixmap.width() << "x" << cache.pixmap.height() << ")" << std::endl; |
1794 #endif | 1817 #endif |
1795 | 1818 |
1796 if (dx > -m_pixmapCache->width() && dx < m_pixmapCache->width()) { | 1819 if (dx != 0 && |
1820 dx > -cache.pixmap.width() && | |
1821 dx < cache.pixmap.width()) { | |
1797 | 1822 |
1798 #if defined(Q_WS_WIN32) || defined(Q_WS_MAC) | 1823 #if defined(Q_WS_WIN32) || defined(Q_WS_MAC) |
1799 // Copying a pixmap to itself doesn't work | 1824 // Copying a pixmap to itself doesn't work |
1800 // properly on Windows or Mac (it only works when | 1825 // properly on Windows or Mac (it only works when |
1801 // moving in one direction). | 1826 // moving in one direction). |
1802 | 1827 |
1803 //!!! Need a utility function for this | 1828 //!!! Need a utility function for this |
1804 | 1829 |
1805 static QPixmap *tmpPixmap = 0; | 1830 static QPixmap *tmpPixmap = 0; |
1806 if (!tmpPixmap || | 1831 if (!tmpPixmap || |
1807 tmpPixmap->width() != m_pixmapCache->width() || | 1832 tmpPixmap->width() != cache.pixmap.width() || |
1808 tmpPixmap->height() != m_pixmapCache->height()) { | 1833 tmpPixmap->height() != cache.pixmap.height()) { |
1809 delete tmpPixmap; | 1834 delete tmpPixmap; |
1810 tmpPixmap = new QPixmap(m_pixmapCache->width(), | 1835 tmpPixmap = new QPixmap(cache.pixmap.width(), |
1811 m_pixmapCache->height()); | 1836 cache.pixmap.height()); |
1812 } | 1837 } |
1813 QPainter cachePainter; | 1838 QPainter cachePainter; |
1814 cachePainter.begin(tmpPixmap); | 1839 cachePainter.begin(tmpPixmap); |
1815 cachePainter.drawPixmap(0, 0, *m_pixmapCache); | 1840 cachePainter.drawPixmap(0, 0, cache.pixmap); |
1816 cachePainter.end(); | 1841 cachePainter.end(); |
1817 cachePainter.begin(m_pixmapCache); | 1842 cachePainter.begin(&cache.pixmap); |
1818 cachePainter.drawPixmap(dx, 0, *tmpPixmap); | 1843 cachePainter.drawPixmap(dx, 0, *tmpPixmap); |
1819 cachePainter.end(); | 1844 cachePainter.end(); |
1820 #else | 1845 #else |
1821 QPainter cachePainter(m_pixmapCache); | 1846 QPainter cachePainter(&cache.pixmap); |
1822 cachePainter.drawPixmap(dx, 0, *m_pixmapCache); | 1847 cachePainter.drawPixmap(dx, 0, cache.pixmap); |
1823 cachePainter.end(); | 1848 cachePainter.end(); |
1824 #endif | 1849 #endif |
1825 | 1850 |
1826 paint.drawPixmap(rect, *m_pixmapCache, rect); | 1851 int px = cache.validArea.x(); |
1852 int pw = cache.validArea.width(); | |
1827 | 1853 |
1828 if (dx < 0) { | 1854 if (dx < 0) { |
1829 x0 = m_pixmapCache->width() + dx; | 1855 x0 = cache.pixmap.width() + dx; |
1830 x1 = m_pixmapCache->width(); | 1856 x1 = cache.pixmap.width(); |
1857 px += dx; | |
1858 if (px < 0) { | |
1859 pw += px; | |
1860 px = 0; | |
1861 if (pw < 0) pw = 0; | |
1862 } | |
1831 } else { | 1863 } else { |
1832 x0 = 0; | 1864 x0 = 0; |
1833 x1 = dx; | 1865 x1 = dx; |
1866 px += dx; | |
1867 if (px + pw > cache.pixmap.width()) { | |
1868 pw = int(cache.pixmap.width()) - px; | |
1869 if (pw < 0) pw = 0; | |
1870 } | |
1834 } | 1871 } |
1872 | |
1873 cache.validArea = | |
1874 QRect(px, cache.validArea.y(), | |
1875 pw, cache.validArea.height()); | |
1876 | |
1877 paint.drawPixmap(rect & cache.validArea, | |
1878 cache.pixmap, | |
1879 rect & cache.validArea); | |
1835 } | 1880 } |
1836 } | 1881 } |
1837 } else { | 1882 } else { |
1838 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1883 #ifdef DEBUG_SPECTROGRAM_REPAINT |
1839 std::cerr << "SpectrogramLayer: pixmap cache useless" << std::endl; | 1884 std::cerr << "SpectrogramLayer: pixmap cache useless" << std::endl; |
1840 #endif | 1885 #endif |
1841 } | 1886 cache.validArea = QRect(); |
1842 } | 1887 } |
1888 } | |
1889 | |
1843 /* | 1890 /* |
1844 if (stillCacheing) { | 1891 if (stillCacheing) { |
1845 x0 = rect.left(); | 1892 x0 = rect.left(); |
1846 x1 = rect.right() + 1; | 1893 x1 = rect.right() + 1; |
1847 y0 = rect.top(); | 1894 y0 = rect.top(); |
1848 y1 = rect.bottom() + 1; | 1895 y1 = rect.bottom() + 1; |
1849 } | 1896 } |
1850 */ | 1897 */ |
1898 | |
1899 if (recreateWholePixmapCache) { | |
1900 | |
1901 x0 = 0; | |
1902 x1 = v->width(); | |
1903 // cache.validArea = QRect(x0, 0, x1, v->height()); | |
1904 } | |
1905 | |
1906 if (1) {//!!! | |
1907 | |
1908 int paintBlockWidth = (500000 / zoomLevel); | |
1909 if (paintBlockWidth < 20) paintBlockWidth = 20; | |
1910 | |
1911 if (cache.validArea.width() > 0) { | |
1912 | |
1913 int vx0 = 0, vx1 = 0; | |
1914 vx0 = cache.validArea.x(); | |
1915 vx1 = cache.validArea.x() + cache.validArea.width(); | |
1916 | |
1917 #ifdef DEBUG_SPECTROGRAM_REPAINT | |
1918 std::cerr << "x0 " << x0 << ", x1 " << x1 << ", vx0 " << vx0 << ", vx1 " << vx1 << ", paintBlockWidth " << paintBlockWidth << std::endl; | |
1919 #endif | |
1920 if (x0 < vx0) { | |
1921 if (x0 + paintBlockWidth < vx0) { | |
1922 x0 = vx0 - paintBlockWidth; | |
1923 } else { | |
1924 x0 = 0; | |
1925 } | |
1926 } else if (x0 > vx1) { | |
1927 x0 = vx1; | |
1928 } | |
1929 | |
1930 if (x1 < vx0) { | |
1931 x1 = vx0; | |
1932 } else if (x1 > vx1) { | |
1933 if (vx1 + paintBlockWidth < x1) { | |
1934 x1 = vx1 + paintBlockWidth; | |
1935 } else { | |
1936 x1 = v->width(); | |
1937 } | |
1938 } | |
1939 | |
1940 cache.validArea = QRect | |
1941 (std::min(vx0, x0), cache.validArea.y(), | |
1942 std::max(vx1 - std::min(vx0, x0), | |
1943 x1 - std::min(vx0, x0)), | |
1944 cache.validArea.height()); | |
1945 | |
1946 } else { | |
1947 if (x1 > x0 + paintBlockWidth) { | |
1948 x1 = x0 + paintBlockWidth; | |
1949 } | |
1950 cache.validArea = QRect(x0, 0, x1 - x0, v->height()); | |
1951 } | |
1952 } | |
1953 | |
1851 int w = x1 - x0; | 1954 int w = x1 - x0; |
1852 int h = y1 - y0; | 1955 int h = y1 - y0; |
1853 | 1956 |
1854 // std::cerr << "x0 " << x0 << ", x1 " << x1 << ", w " << w << ", h " << h << std::endl; | 1957 #ifdef DEBUG_SPECTROGRAM_REPAINT |
1855 | 1958 std::cerr << "x0 " << x0 << ", x1 " << x1 << ", w " << w << ", h " << h << std::endl; |
1856 QImage scaled(w, h, QImage::Format_RGB32); | 1959 #endif |
1857 scaled.fill(m_colourMap.getColour(0).rgb()); | 1960 |
1961 if (m_drawBuffer.width() < w || m_drawBuffer.height() < h) { | |
1962 m_drawBuffer = QImage(w, h, QImage::Format_RGB32); | |
1963 } | |
1964 | |
1965 // if (m_binDisplay == PeakFrequencies) { | |
1966 m_drawBuffer.fill(m_colourMap.getColour(0).rgb()); | |
1967 // } | |
1858 | 1968 |
1859 int sr = m_model->getSampleRate(); | 1969 int sr = m_model->getSampleRate(); |
1860 | 1970 |
1861 size_t bins = m_windowSize / 2; | 1971 size_t bins = m_windowSize / 2; |
1862 if (m_maxFrequency > 0) { | 1972 if (m_maxFrequency > 0) { |
1887 for (size_t q = minbin; q <= bins; ++q) { | 1997 for (size_t q = minbin; q <= bins; ++q) { |
1888 float f0 = (float(q) * sr) / m_windowSize; | 1998 float f0 = (float(q) * sr) / m_windowSize; |
1889 yval[q] = v->getYForFrequency(f0, minFreq, maxFreq, logarithmic); | 1999 yval[q] = v->getYForFrequency(f0, minFreq, maxFreq, logarithmic); |
1890 } | 2000 } |
1891 | 2001 |
2002 m_mutex.lock(); | |
2003 | |
1892 for (int x = 0; x < w; ++x) { | 2004 for (int x = 0; x < w; ++x) { |
1893 | 2005 |
1894 m_mutex.lock(); | 2006 if (x % 10 == 0) { |
1895 if (m_cacheInvalid) { | 2007 m_mutex.unlock(); |
1896 m_mutex.unlock(); | 2008 m_mutex.lock(); |
1897 break; | 2009 if (m_cacheInvalid) { |
1898 } | 2010 break; |
2011 } | |
2012 } | |
1899 | 2013 |
1900 for (int y = 0; y < h; ++y) { | 2014 for (int y = 0; y < h; ++y) { |
1901 ymag[y] = 0.0; | 2015 ymag[y] = 0.0; |
1902 ydiv[y] = 0.0; | 2016 ydiv[y] = 0.0; |
1903 } | 2017 } |
1904 | 2018 |
1905 float s0 = 0, s1 = 0; | 2019 float s0 = 0, s1 = 0; |
1906 | 2020 |
1907 if (!getXBinRange(v, x0 + x, s0, s1)) { | 2021 if (!getXBinRange(v, x0 + x, s0, s1)) { |
1908 assert(x <= scaled.width()); | 2022 assert(x <= m_drawBuffer.width()); |
1909 m_mutex.unlock(); | |
1910 continue; | 2023 continue; |
1911 } | 2024 } |
1912 | 2025 |
1913 int s0i = int(s0 + 0.001); | 2026 int s0i = int(s0 + 0.001); |
1914 int s1i = int(s1); | 2027 int s1i = int(s1); |
1915 | 2028 |
1916 if (s1i >= m_cache->getWidth()) { | 2029 if (s1i >= m_cache->getWidth()) { |
1917 if (s0i >= m_cache->getWidth()) { | 2030 if (s0i >= m_cache->getWidth()) { |
1918 m_mutex.unlock(); | |
1919 continue; | 2031 continue; |
1920 } else { | 2032 } else { |
1921 s1i = s0i; | 2033 s1i = s0i; |
1922 } | 2034 } |
1923 } | 2035 } |
1991 unsigned char pixel = 0; | 2103 unsigned char pixel = 0; |
1992 | 2104 |
1993 float avg = ymag[y] / ydiv[y]; | 2105 float avg = ymag[y] / ydiv[y]; |
1994 pixel = getDisplayValue(avg); | 2106 pixel = getDisplayValue(avg); |
1995 | 2107 |
1996 assert(x <= scaled.width()); | 2108 assert(x <= m_drawBuffer.width()); |
1997 QColor c = m_colourMap.getColour(pixel); | 2109 QColor c = m_colourMap.getColour(pixel); |
1998 scaled.setPixel(x, y, | 2110 m_drawBuffer.setPixel(x, y, |
1999 qRgb(c.red(), c.green(), c.blue())); | 2111 qRgb(c.red(), c.green(), c.blue())); |
2000 } | 2112 } |
2001 } | 2113 } |
2002 | 2114 } |
2003 m_mutex.unlock(); | 2115 |
2004 } | 2116 m_mutex.unlock(); |
2005 | 2117 |
2006 paint.drawImage(x0, y0, scaled); | 2118 paint.drawImage(x0, y0, m_drawBuffer, 0, 0, w, h); |
2007 | 2119 |
2008 if (recreateWholePixmapCache) { | 2120 if (recreateWholePixmapCache) { |
2009 delete m_pixmapCache; | 2121 cache.pixmap = QPixmap(v->width(), v->height()); |
2010 m_pixmapCache = new QPixmap(w, h); | 2122 } |
2011 } | 2123 |
2012 | 2124 QPainter cachePainter(&cache.pixmap); |
2013 QPainter cachePainter(m_pixmapCache); | 2125 cachePainter.drawImage(x0, y0, m_drawBuffer, 0, 0, w, h); |
2014 cachePainter.drawImage(x0, y0, scaled); | |
2015 cachePainter.end(); | 2126 cachePainter.end(); |
2016 | 2127 |
2017 m_pixmapCacheInvalid = false; | 2128 // m_pixmapCacheInvalid = false; |
2018 m_pixmapCacheStartFrame = startFrame; | 2129 cache.startFrame = startFrame; |
2019 m_pixmapCacheZoomLevel = zoomLevel; | 2130 cache.zoomLevel = zoomLevel; |
2131 | |
2132 if (cache.validArea.x() > 0) { | |
2133 #ifdef DEBUG_SPECTROGRAM_REPAINT | |
2134 std::cerr << "SpectrogramLayer::paint() updating left" << std::endl; | |
2135 #endif | |
2136 v->update(0, 0, cache.validArea.x(), v->height()); | |
2137 } | |
2138 | |
2139 if (cache.validArea.x() + cache.validArea.width() < | |
2140 cache.pixmap.width()) { | |
2141 #ifdef DEBUG_SPECTROGRAM_REPAINT | |
2142 std::cerr << "SpectrogramLayer::paint() updating right (" | |
2143 << cache.validArea.x() + cache.validArea.width() | |
2144 << ", " | |
2145 << cache.pixmap.width() - (cache.validArea.x() + | |
2146 cache.validArea.width()) | |
2147 << ")" << std::endl; | |
2148 #endif | |
2149 v->update(cache.validArea.x() + cache.validArea.width(), | |
2150 0, | |
2151 cache.pixmap.width() - (cache.validArea.x() + | |
2152 cache.validArea.width()), | |
2153 v->height()); | |
2154 } | |
2020 | 2155 |
2021 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2156 #ifdef DEBUG_SPECTROGRAM_REPAINT |
2022 std::cerr << "SpectrogramLayer::paint() returning" << std::endl; | 2157 std::cerr << "SpectrogramLayer::paint() returning" << std::endl; |
2023 #endif | 2158 #endif |
2024 } | 2159 } |