Mercurial > hg > svgui
comparison layer/SpectrogramLayer.cpp @ 706:97ea68f62c1f imaf_enc
Merge from default branch
| author | Chris Cannam |
|---|---|
| date | Thu, 05 Dec 2013 09:47:02 +0000 |
| parents | 8072264dc61f |
| children | 67e6d518ac27 |
comparison
equal
deleted
inserted
replaced
| 678:26c5f7fd4807 | 706:97ea68f62c1f |
|---|---|
| 25 #include "base/LogRange.h" | 25 #include "base/LogRange.h" |
| 26 #include "widgets/CommandHistory.h" | 26 #include "widgets/CommandHistory.h" |
| 27 #include "ColourMapper.h" | 27 #include "ColourMapper.h" |
| 28 #include "ImageRegionFinder.h" | 28 #include "ImageRegionFinder.h" |
| 29 #include "data/model/Dense3DModelPeakCache.h" | 29 #include "data/model/Dense3DModelPeakCache.h" |
| 30 #include "PianoScale.h" | |
| 30 | 31 |
| 31 #include <QPainter> | 32 #include <QPainter> |
| 32 #include <QImage> | 33 #include <QImage> |
| 33 #include <QPixmap> | 34 #include <QPixmap> |
| 34 #include <QRect> | 35 #include <QRect> |
| 38 #include <QMouseEvent> | 39 #include <QMouseEvent> |
| 39 #include <QTextStream> | 40 #include <QTextStream> |
| 40 | 41 |
| 41 #include <iostream> | 42 #include <iostream> |
| 42 | 43 |
| 43 using std::cerr; | 44 |
| 44 using std::endl; | 45 |
| 45 #include <cassert> | 46 #include <cassert> |
| 46 #include <cmath> | 47 #include <cmath> |
| 47 | 48 |
| 48 #ifndef __GNUC__ | 49 #ifndef __GNUC__ |
| 49 #include <alloca.h> | 50 #include <alloca.h> |
| 125 } | 126 } |
| 126 | 127 |
| 127 void | 128 void |
| 128 SpectrogramLayer::setModel(const DenseTimeValueModel *model) | 129 SpectrogramLayer::setModel(const DenseTimeValueModel *model) |
| 129 { | 130 { |
| 130 // std::cerr << "SpectrogramLayer(" << this << "): setModel(" << model << ")" << std::endl; | 131 // cerr << "SpectrogramLayer(" << this << "): setModel(" << model << ")" << endl; |
| 131 | 132 |
| 132 if (model == m_model) return; | 133 if (model == m_model) return; |
| 133 | 134 |
| 134 m_model = model; | 135 m_model = model; |
| 135 invalidateFFTModels(); | 136 invalidateFFTModels(); |
| 582 SVDEBUG << "SpectrogramLayer::invalidateImageCaches(" | 583 SVDEBUG << "SpectrogramLayer::invalidateImageCaches(" |
| 583 << startFrame << ", " << endFrame << "): view range is " | 584 << startFrame << ", " << endFrame << "): view range is " |
| 584 << v->getStartFrame() << ", " << v->getEndFrame() | 585 << v->getStartFrame() << ", " << v->getEndFrame() |
| 585 << endl; | 586 << endl; |
| 586 | 587 |
| 587 std::cerr << "Valid area was: " << i->second.validArea.x() << ", " | 588 cerr << "Valid area was: " << i->second.validArea.x() << ", " |
| 588 << i->second.validArea.y() << " " | 589 << i->second.validArea.y() << " " |
| 589 << i->second.validArea.width() << "x" | 590 << i->second.validArea.width() << "x" |
| 590 << i->second.validArea.height() << std::endl; | 591 << i->second.validArea.height() << endl; |
| 591 #endif | 592 #endif |
| 592 | 593 |
| 593 if (long(startFrame) > v->getStartFrame()) { | 594 if (long(startFrame) > v->getStartFrame()) { |
| 594 if (startFrame >= v->getEndFrame()) { | 595 if (startFrame >= v->getEndFrame()) { |
| 595 #ifdef DEBUG_SPECTROGRAM_REPAINT | 596 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 596 std::cerr << "Modified start frame is off right of view" << std::endl; | 597 cerr << "Modified start frame is off right of view" << endl; |
| 597 #endif | 598 #endif |
| 598 return; | 599 return; |
| 599 } | 600 } |
| 600 int x = v->getXForFrame(startFrame); | 601 int x = v->getXForFrame(startFrame); |
| 601 #ifdef DEBUG_SPECTROGRAM_REPAINT | 602 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 608 i->second.validArea = QRect(); | 609 i->second.validArea = QRect(); |
| 609 } | 610 } |
| 610 } else { | 611 } else { |
| 611 if (long(endFrame) < v->getStartFrame()) { | 612 if (long(endFrame) < v->getStartFrame()) { |
| 612 #ifdef DEBUG_SPECTROGRAM_REPAINT | 613 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 613 std::cerr << "Modified end frame is off left of view" << std::endl; | 614 cerr << "Modified end frame is off left of view" << endl; |
| 614 #endif | 615 #endif |
| 615 return; | 616 return; |
| 616 } | 617 } |
| 617 int x = v->getXForFrame(endFrame); | 618 int x = v->getXForFrame(endFrame); |
| 618 #ifdef DEBUG_SPECTROGRAM_REPAINT | 619 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 626 i->second.validArea = QRect(); | 627 i->second.validArea = QRect(); |
| 627 } | 628 } |
| 628 } | 629 } |
| 629 | 630 |
| 630 #ifdef DEBUG_SPECTROGRAM_REPAINT | 631 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 631 std::cerr << "Valid area is now: " << i->second.validArea.x() << ", " | 632 cerr << "Valid area is now: " << i->second.validArea.x() << ", " |
| 632 << i->second.validArea.y() << " " | 633 << i->second.validArea.y() << " " |
| 633 << i->second.validArea.width() << "x" | 634 << i->second.validArea.width() << "x" |
| 634 << i->second.validArea.height() << std::endl; | 635 << i->second.validArea.height() << endl; |
| 635 #endif | 636 #endif |
| 636 } | 637 } |
| 637 } | 638 } |
| 638 | 639 |
| 639 void | 640 void |
| 1065 #endif | 1066 #endif |
| 1066 | 1067 |
| 1067 if (fill >= lastFill) { | 1068 if (fill >= lastFill) { |
| 1068 if (fill >= m_model->getEndFrame() && lastFill > 0) { | 1069 if (fill >= m_model->getEndFrame() && lastFill > 0) { |
| 1069 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1070 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 1070 std::cerr << "complete!" << std::endl; | 1071 cerr << "complete!" << endl; |
| 1071 #endif | 1072 #endif |
| 1072 invalidateImageCaches(); | 1073 invalidateImageCaches(); |
| 1073 i->second.second = -1; | 1074 i->second.second = -1; |
| 1074 emit modelChanged(); | 1075 emit modelChanged(); |
| 1075 | 1076 |
| 1076 } else if (fill > lastFill) { | 1077 } else if (fill > lastFill) { |
| 1077 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1078 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 1078 std::cerr << "SpectrogramLayer: emitting modelChanged(" | 1079 cerr << "SpectrogramLayer: emitting modelChanged(" |
| 1079 << lastFill << "," << fill << ")" << std::endl; | 1080 << lastFill << "," << fill << ")" << endl; |
| 1080 #endif | 1081 #endif |
| 1081 invalidateImageCaches(lastFill, fill); | 1082 invalidateImageCaches(lastFill, fill); |
| 1082 i->second.second = fill; | 1083 i->second.second = fill; |
| 1083 emit modelChanged(lastFill, fill); | 1084 emit modelChanged(lastFill, fill); |
| 1084 } | 1085 } |
| 1085 } else { | 1086 } else { |
| 1086 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1087 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 1087 std::cerr << "SpectrogramLayer: going backwards, emitting modelChanged(" | 1088 cerr << "SpectrogramLayer: going backwards, emitting modelChanged(" |
| 1088 << m_model->getStartFrame() << "," << m_model->getEndFrame() << ")" << std::endl; | 1089 << m_model->getStartFrame() << "," << m_model->getEndFrame() << ")" << endl; |
| 1089 #endif | 1090 #endif |
| 1090 invalidateImageCaches(); | 1091 invalidateImageCaches(); |
| 1091 i->second.second = fill; | 1092 i->second.second = fill; |
| 1092 emit modelChanged(m_model->getStartFrame(), m_model->getEndFrame()); | 1093 emit modelChanged(m_model->getStartFrame(), m_model->getEndFrame()); |
| 1093 } | 1094 } |
| 1098 } | 1099 } |
| 1099 } | 1100 } |
| 1100 | 1101 |
| 1101 if (allDone) { | 1102 if (allDone) { |
| 1102 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1103 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 1103 std::cerr << "SpectrogramLayer: all complete!" << std::endl; | 1104 cerr << "SpectrogramLayer: all complete!" << endl; |
| 1104 #endif | 1105 #endif |
| 1105 delete m_updateTimer; | 1106 delete m_updateTimer; |
| 1106 m_updateTimer = 0; | 1107 m_updateTimer = 0; |
| 1107 } | 1108 } |
| 1108 } | 1109 } |
| 1672 return 0; | 1673 return 0; |
| 1673 } | 1674 } |
| 1674 | 1675 |
| 1675 if (!m_sliceableModel) { | 1676 if (!m_sliceableModel) { |
| 1676 #ifdef DEBUG_SPECTROGRAM | 1677 #ifdef DEBUG_SPECTROGRAM |
| 1677 std::cerr << "SpectrogramLayer: emitting sliceableModelReplaced(0, " << model << ")" << std::endl; | 1678 cerr << "SpectrogramLayer: emitting sliceableModelReplaced(0, " << model << ")" << endl; |
| 1678 #endif | 1679 #endif |
| 1679 ((SpectrogramLayer *)this)->sliceableModelReplaced(0, model); | 1680 ((SpectrogramLayer *)this)->sliceableModelReplaced(0, model); |
| 1680 m_sliceableModel = model; | 1681 m_sliceableModel = model; |
| 1681 } | 1682 } |
| 1682 | 1683 |
| 1728 | 1729 |
| 1729 m_fftModels.clear(); | 1730 m_fftModels.clear(); |
| 1730 m_peakCaches.clear(); | 1731 m_peakCaches.clear(); |
| 1731 | 1732 |
| 1732 if (m_sliceableModel) { | 1733 if (m_sliceableModel) { |
| 1733 std::cerr << "SpectrogramLayer: emitting sliceableModelReplaced(" << m_sliceableModel << ", 0)" << std::endl; | 1734 cerr << "SpectrogramLayer: emitting sliceableModelReplaced(" << m_sliceableModel << ", 0)" << endl; |
| 1734 emit sliceableModelReplaced(m_sliceableModel, 0); | 1735 emit sliceableModelReplaced(m_sliceableModel, 0); |
| 1735 m_sliceableModel = 0; | 1736 m_sliceableModel = 0; |
| 1736 } | 1737 } |
| 1737 } | 1738 } |
| 1738 | 1739 |
| 1803 Profiler profiler("SpectrogramLayer::paint", false); | 1804 Profiler profiler("SpectrogramLayer::paint", false); |
| 1804 | 1805 |
| 1805 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1806 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 1806 SVDEBUG << "SpectrogramLayer::paint(): m_model is " << m_model << ", zoom level is " << v->getZoomLevel() << ", m_updateTimer " << m_updateTimer << endl; | 1807 SVDEBUG << "SpectrogramLayer::paint(): m_model is " << m_model << ", zoom level is " << v->getZoomLevel() << ", m_updateTimer " << m_updateTimer << endl; |
| 1807 | 1808 |
| 1808 std::cerr << "rect is " << rect.x() << "," << rect.y() << " " << rect.width() << "x" << rect.height() << std::endl; | 1809 cerr << "rect is " << rect.x() << "," << rect.y() << " " << rect.width() << "x" << rect.height() << endl; |
| 1809 #endif | 1810 #endif |
| 1810 | 1811 |
| 1811 long startFrame = v->getStartFrame(); | 1812 long startFrame = v->getStartFrame(); |
| 1812 if (startFrame < 0) m_candidateFillStartFrame = 0; | 1813 if (startFrame < 0) m_candidateFillStartFrame = 0; |
| 1813 else m_candidateFillStartFrame = startFrame; | 1814 else m_candidateFillStartFrame = startFrame; |
| 1829 | 1830 |
| 1830 size_t fftSize = getFFTSize(v); | 1831 size_t fftSize = getFFTSize(v); |
| 1831 /* | 1832 /* |
| 1832 FFTModel *fft = getFFTModel(v); | 1833 FFTModel *fft = getFFTModel(v); |
| 1833 if (!fft) { | 1834 if (!fft) { |
| 1834 std::cerr << "ERROR: SpectrogramLayer::paint(): No FFT model, returning" << std::endl; | 1835 cerr << "ERROR: SpectrogramLayer::paint(): No FFT model, returning" << endl; |
| 1835 return; | 1836 return; |
| 1836 } | 1837 } |
| 1837 */ | 1838 */ |
| 1838 ImageCache &cache = m_imageCaches[v]; | 1839 ImageCache &cache = m_imageCaches[v]; |
| 1839 | 1840 |
| 1857 | 1858 |
| 1858 x0 = rect.left(); | 1859 x0 = rect.left(); |
| 1859 x1 = rect.right() + 1; | 1860 x1 = rect.right() + 1; |
| 1860 /* | 1861 /* |
| 1861 float xPixelRatio = float(fft->getResolution()) / float(zoomLevel); | 1862 float xPixelRatio = float(fft->getResolution()) / float(zoomLevel); |
| 1862 std::cerr << "xPixelRatio = " << xPixelRatio << std::endl; | 1863 cerr << "xPixelRatio = " << xPixelRatio << endl; |
| 1863 if (xPixelRatio < 1.f) xPixelRatio = 1.f; | 1864 if (xPixelRatio < 1.f) xPixelRatio = 1.f; |
| 1864 */ | 1865 */ |
| 1865 if (cache.validArea.width() > 0) { | 1866 if (cache.validArea.width() > 0) { |
| 1866 | 1867 |
| 1867 int cw = cache.image.width(); | 1868 int cw = cache.image.width(); |
| 1875 v->getXForFrame(startFrame) && | 1876 v->getXForFrame(startFrame) && |
| 1876 cache.validArea.x() <= x0 && | 1877 cache.validArea.x() <= x0 && |
| 1877 cache.validArea.x() + cache.validArea.width() >= x1) { | 1878 cache.validArea.x() + cache.validArea.width() >= x1) { |
| 1878 | 1879 |
| 1879 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1880 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 1880 std::cerr << "SpectrogramLayer: image cache good" << std::endl; | 1881 cerr << "SpectrogramLayer: image cache good" << endl; |
| 1881 #endif | 1882 #endif |
| 1882 | 1883 |
| 1883 paint.drawImage(rect, cache.image, rect); | 1884 paint.drawImage(rect, cache.image, rect); |
| 1884 //!!! | 1885 //!!! |
| 1885 // paint.drawImage(v->rect(), cache.image, | 1886 // paint.drawImage(v->rect(), cache.image, |
| 1889 return; | 1890 return; |
| 1890 | 1891 |
| 1891 } else { | 1892 } else { |
| 1892 | 1893 |
| 1893 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1894 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 1894 std::cerr << "SpectrogramLayer: image cache partially OK" << std::endl; | 1895 cerr << "SpectrogramLayer: image cache partially OK" << endl; |
| 1895 #endif | 1896 #endif |
| 1896 | 1897 |
| 1897 recreateWholeImageCache = false; | 1898 recreateWholeImageCache = false; |
| 1898 | 1899 |
| 1899 int dx = v->getXForFrame(cache.startFrame) - | 1900 int dx = v->getXForFrame(cache.startFrame) - |
| 1900 v->getXForFrame(startFrame); | 1901 v->getXForFrame(startFrame); |
| 1901 | 1902 |
| 1902 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1903 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 1903 std::cerr << "SpectrogramLayer: dx = " << dx << " (image cache " << cw << "x" << ch << ")" << std::endl; | 1904 cerr << "SpectrogramLayer: dx = " << dx << " (image cache " << cw << "x" << ch << ")" << endl; |
| 1904 #endif | 1905 #endif |
| 1905 | 1906 |
| 1906 if (dx != 0 && | 1907 if (dx != 0 && |
| 1907 dx > -cw && | 1908 dx > -cw && |
| 1908 dx < cw) { | 1909 dx < cw) { |
| 1944 cache.validArea = | 1945 cache.validArea = |
| 1945 QRect(px, cache.validArea.y(), | 1946 QRect(px, cache.validArea.y(), |
| 1946 pw, cache.validArea.height()); | 1947 pw, cache.validArea.height()); |
| 1947 | 1948 |
| 1948 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1949 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 1949 std::cerr << "valid area now " | 1950 cerr << "valid area now " |
| 1950 << px << "," << cache.validArea.y() | 1951 << px << "," << cache.validArea.y() |
| 1951 << " " << pw << "x" << cache.validArea.height() | 1952 << " " << pw << "x" << cache.validArea.height() |
| 1952 << std::endl; | 1953 << endl; |
| 1953 #endif | 1954 #endif |
| 1954 /* | 1955 /* |
| 1955 paint.drawImage(rect & cache.validArea, | 1956 paint.drawImage(rect & cache.validArea, |
| 1956 cache.image, | 1957 cache.image, |
| 1957 rect & cache.validArea); | 1958 rect & cache.validArea); |
| 1959 } else if (dx != 0) { | 1960 } else if (dx != 0) { |
| 1960 | 1961 |
| 1961 // we scrolled too far to be of use | 1962 // we scrolled too far to be of use |
| 1962 | 1963 |
| 1963 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1964 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 1964 std::cerr << "dx == " << dx << ": scrolled too far for cache to be useful" << std::endl; | 1965 cerr << "dx == " << dx << ": scrolled too far for cache to be useful" << endl; |
| 1965 #endif | 1966 #endif |
| 1966 | 1967 |
| 1967 cache.validArea = QRect(); | 1968 cache.validArea = QRect(); |
| 1968 recreateWholeImageCache = true; | 1969 recreateWholeImageCache = true; |
| 1969 } | 1970 } |
| 1970 } | 1971 } |
| 1971 } else { | 1972 } else { |
| 1972 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1973 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 1973 std::cerr << "SpectrogramLayer: image cache useless" << std::endl; | 1974 cerr << "SpectrogramLayer: image cache useless" << endl; |
| 1974 if (int(cache.zoomLevel) != zoomLevel) { | 1975 if (int(cache.zoomLevel) != zoomLevel) { |
| 1975 std::cerr << "(cache zoomLevel " << cache.zoomLevel | 1976 cerr << "(cache zoomLevel " << cache.zoomLevel |
| 1976 << " != " << zoomLevel << ")" << std::endl; | 1977 << " != " << zoomLevel << ")" << endl; |
| 1977 } | 1978 } |
| 1978 if (cw != v->width()) { | 1979 if (cw != v->width()) { |
| 1979 std::cerr << "(cache width " << cw | 1980 cerr << "(cache width " << cw |
| 1980 << " != " << v->width(); | 1981 << " != " << v->width(); |
| 1981 } | 1982 } |
| 1982 if (ch != v->height()) { | 1983 if (ch != v->height()) { |
| 1983 std::cerr << "(cache height " << ch | 1984 cerr << "(cache height " << ch |
| 1984 << " != " << v->height(); | 1985 << " != " << v->height(); |
| 1985 } | 1986 } |
| 1986 #endif | 1987 #endif |
| 1987 cache.validArea = QRect(); | 1988 cache.validArea = QRect(); |
| 1988 // recreateWholeImageCache = true; | 1989 // recreateWholeImageCache = true; |
| 1989 } | 1990 } |
| 1990 } | 1991 } |
| 1991 | 1992 |
| 1992 if (updateViewMagnitudes(v)) { | 1993 if (updateViewMagnitudes(v)) { |
| 1993 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1994 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 1994 std::cerr << "SpectrogramLayer: magnitude range changed to [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "]" << std::endl; | 1995 cerr << "SpectrogramLayer: magnitude range changed to [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "]" << endl; |
| 1995 #endif | 1996 #endif |
| 1996 if (m_normalizeVisibleArea) { | 1997 if (m_normalizeVisibleArea) { |
| 1997 cache.validArea = QRect(); | 1998 cache.validArea = QRect(); |
| 1998 recreateWholeImageCache = true; | 1999 recreateWholeImageCache = true; |
| 1999 } | 2000 } |
| 2000 } else { | 2001 } else { |
| 2001 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2002 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 2002 std::cerr << "No change in magnitude range [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "]" << std::endl; | 2003 cerr << "No change in magnitude range [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "]" << endl; |
| 2003 #endif | 2004 #endif |
| 2004 } | 2005 } |
| 2005 | 2006 |
| 2006 if (recreateWholeImageCache) { | 2007 if (recreateWholeImageCache) { |
| 2007 x0 = 0; | 2008 x0 = 0; |
| 2038 | 2039 |
| 2039 if (paintBlockWidth < 20) paintBlockWidth = 20; | 2040 if (paintBlockWidth < 20) paintBlockWidth = 20; |
| 2040 } | 2041 } |
| 2041 | 2042 |
| 2042 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2043 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 2043 std::cerr << "[" << this << "]: last paint width: " << m_lastPaintBlockWidth << ", last paint time: " << m_lastPaintTime << ", new paint width: " << paintBlockWidth << std::endl; | 2044 cerr << "[" << this << "]: last paint width: " << m_lastPaintBlockWidth << ", last paint time: " << m_lastPaintTime << ", new paint width: " << paintBlockWidth << endl; |
| 2044 #endif | 2045 #endif |
| 2045 | 2046 |
| 2046 // We always paint the full height when refreshing the cache. | 2047 // We always paint the full height when refreshing the cache. |
| 2047 // Smaller heights can be used when painting direct from cache | 2048 // Smaller heights can be used when painting direct from cache |
| 2048 // (further up in this function), but we want to ensure the cache | 2049 // (further up in this function), but we want to ensure the cache |
| 2063 int vx0 = 0, vx1 = 0; | 2064 int vx0 = 0, vx1 = 0; |
| 2064 vx0 = cache.validArea.x(); | 2065 vx0 = cache.validArea.x(); |
| 2065 vx1 = cache.validArea.x() + cache.validArea.width(); | 2066 vx1 = cache.validArea.x() + cache.validArea.width(); |
| 2066 | 2067 |
| 2067 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2068 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 2068 std::cerr << "x0 " << x0 << ", x1 " << x1 << ", vx0 " << vx0 << ", vx1 " << vx1 << ", paintBlockWidth " << paintBlockWidth << std::endl; | 2069 cerr << "x0 " << x0 << ", x1 " << x1 << ", vx0 " << vx0 << ", vx1 " << vx1 << ", paintBlockWidth " << paintBlockWidth << endl; |
| 2069 #endif | 2070 #endif |
| 2070 if (x0 < vx0) { | 2071 if (x0 < vx0) { |
| 2071 if (x0 + paintBlockWidth < vx0) { | 2072 if (x0 + paintBlockWidth < vx0) { |
| 2072 x0 = vx0 - paintBlockWidth; | 2073 x0 = vx0 - paintBlockWidth; |
| 2073 } | 2074 } |
| 2094 std::max(vx1 - std::min(vx0, x0), | 2095 std::max(vx1 - std::min(vx0, x0), |
| 2095 x1 - std::min(vx0, x0)), | 2096 x1 - std::min(vx0, x0)), |
| 2096 cache.validArea.height()); | 2097 cache.validArea.height()); |
| 2097 | 2098 |
| 2098 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2099 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 2099 std::cerr << "Valid area becomes " << cache.validArea.x() | 2100 cerr << "Valid area becomes " << cache.validArea.x() |
| 2100 << ", " << cache.validArea.y() << ", " | 2101 << ", " << cache.validArea.y() << ", " |
| 2101 << cache.validArea.width() << "x" | 2102 << cache.validArea.width() << "x" |
| 2102 << cache.validArea.height() << std::endl; | 2103 << cache.validArea.height() << endl; |
| 2103 #endif | 2104 #endif |
| 2104 | 2105 |
| 2105 } else { | 2106 } else { |
| 2106 if (x1 > x0 + paintBlockWidth) { | 2107 if (x1 > x0 + paintBlockWidth) { |
| 2107 int sfx = x1; | 2108 int sfx = x1; |
| 2114 x0 = mid - paintBlockWidth/2; | 2115 x0 = mid - paintBlockWidth/2; |
| 2115 x1 = x0 + paintBlockWidth; | 2116 x1 = x0 + paintBlockWidth; |
| 2116 } | 2117 } |
| 2117 } | 2118 } |
| 2118 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2119 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 2119 std::cerr << "Valid area becomes " << x0 << ", 0, " << (x1-x0) | 2120 cerr << "Valid area becomes " << x0 << ", 0, " << (x1-x0) |
| 2120 << "x" << h << std::endl; | 2121 << "x" << h << endl; |
| 2121 #endif | 2122 #endif |
| 2122 cache.validArea = QRect(x0, 0, x1 - x0, h); | 2123 cache.validArea = QRect(x0, 0, x1 - x0, h); |
| 2123 } | 2124 } |
| 2124 | 2125 |
| 2125 /* | 2126 /* |
| 2129 } | 2130 } |
| 2130 */ | 2131 */ |
| 2131 int w = x1 - x0; | 2132 int w = x1 - x0; |
| 2132 | 2133 |
| 2133 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2134 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 2134 std::cerr << "x0 " << x0 << ", x1 " << x1 << ", w " << w << ", h " << h << std::endl; | 2135 cerr << "x0 " << x0 << ", x1 " << x1 << ", w " << w << ", h " << h << endl; |
| 2135 #endif | 2136 #endif |
| 2136 | 2137 |
| 2137 int sr = m_model->getSampleRate(); | 2138 int sr = m_model->getSampleRate(); |
| 2138 | 2139 |
| 2139 // Set minFreq and maxFreq to the frequency extents of the possibly | 2140 // Set minFreq and maxFreq to the frequency extents of the possibly |
| 2154 } | 2155 } |
| 2155 | 2156 |
| 2156 size_t minbin = 1; | 2157 size_t minbin = 1; |
| 2157 if (m_minFrequency > 0) { | 2158 if (m_minFrequency > 0) { |
| 2158 minbin = int((double(m_minFrequency) * m_fftSize) / sr + 0.001); | 2159 minbin = int((double(m_minFrequency) * m_fftSize) / sr + 0.001); |
| 2159 // std::cerr << "m_minFrequency = " << m_minFrequency << " -> minbin = " << minbin << std::endl; | 2160 // cerr << "m_minFrequency = " << m_minFrequency << " -> minbin = " << minbin << endl; |
| 2160 if (minbin < 1) minbin = 1; | 2161 if (minbin < 1) minbin = 1; |
| 2161 if (minbin >= maxbin) minbin = maxbin - 1; | 2162 if (minbin >= maxbin) minbin = maxbin - 1; |
| 2162 } | 2163 } |
| 2163 | 2164 |
| 2164 int zpl = getZeroPadLevel(v) + 1; | 2165 int zpl = getZeroPadLevel(v) + 1; |
| 2174 if (fftSize != m_fftSize) { | 2175 if (fftSize != m_fftSize) { |
| 2175 displayMinFreq = getEffectiveMinFrequency(); | 2176 displayMinFreq = getEffectiveMinFrequency(); |
| 2176 displayMaxFreq = getEffectiveMaxFrequency(); | 2177 displayMaxFreq = getEffectiveMaxFrequency(); |
| 2177 } | 2178 } |
| 2178 | 2179 |
| 2179 // std::cerr << "(giving actual minFreq " << minFreq << " and display minFreq " << displayMinFreq << ")" << std::endl; | 2180 // cerr << "(giving actual minFreq " << minFreq << " and display minFreq " << displayMinFreq << ")" << endl; |
| 2180 | 2181 |
| 2181 int increment = getWindowIncrement(); | 2182 int increment = getWindowIncrement(); |
| 2182 | 2183 |
| 2183 bool logarithmic = (m_frequencyScale == LogFrequencyScale); | 2184 bool logarithmic = (m_frequencyScale == LogFrequencyScale); |
| 2184 /* | 2185 /* |
| 2195 bool overallMagChanged = false; | 2196 bool overallMagChanged = false; |
| 2196 | 2197 |
| 2197 bool fftSuspended = false; | 2198 bool fftSuspended = false; |
| 2198 | 2199 |
| 2199 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2200 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 2200 std::cerr << ((float(v->getFrameForX(1) - v->getFrameForX(0))) / increment) << " bin(s) per pixel" << std::endl; | 2201 cerr << ((float(v->getFrameForX(1) - v->getFrameForX(0))) / increment) << " bin(s) per pixel" << endl; |
| 2201 #endif | 2202 #endif |
| 2202 | 2203 |
| 2203 bool runOutOfData = false; | 2204 bool runOutOfData = false; |
| 2204 | 2205 |
| 2205 if (w == 0) { | 2206 if (w == 0) { |
| 2335 xPixelRatio, | 2336 xPixelRatio, |
| 2336 h, yforbin); | 2337 h, yforbin); |
| 2337 | 2338 |
| 2338 if (runOutOfData) { | 2339 if (runOutOfData) { |
| 2339 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2340 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 2340 std::cerr << "Run out of data -- dropping out of loop" << std::endl; | 2341 cerr << "Run out of data -- dropping out of loop" << endl; |
| 2341 #endif | 2342 #endif |
| 2342 break; | 2343 break; |
| 2343 } | 2344 } |
| 2344 } | 2345 } |
| 2345 */ | 2346 */ |
| 2346 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2347 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 2347 // std::cerr << pixels << " pixels drawn" << std::endl; | 2348 // cerr << pixels << " pixels drawn" << endl; |
| 2348 #endif | 2349 #endif |
| 2349 | 2350 |
| 2350 if (overallMagChanged) { | 2351 if (overallMagChanged) { |
| 2351 m_viewMags[v] = overallMag; | 2352 m_viewMags[v] = overallMag; |
| 2352 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2353 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 2353 std::cerr << "Overall mag is now [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "] - will be updating" << std::endl; | 2354 cerr << "Overall mag is now [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "] - will be updating" << endl; |
| 2354 #endif | 2355 #endif |
| 2355 } else { | 2356 } else { |
| 2356 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2357 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 2357 std::cerr << "Overall mag unchanged at [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "]" << std::endl; | 2358 cerr << "Overall mag unchanged at [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "]" << endl; |
| 2358 #endif | 2359 #endif |
| 2359 } | 2360 } |
| 2360 | 2361 |
| 2361 outerprof.end(); | 2362 outerprof.end(); |
| 2362 | 2363 |
| 2462 cache.validArea.width()), | 2463 cache.validArea.width()), |
| 2463 h); | 2464 h); |
| 2464 } | 2465 } |
| 2465 } else { | 2466 } else { |
| 2466 // overallMagChanged | 2467 // overallMagChanged |
| 2467 std::cerr << "\noverallMagChanged - updating all\n" << std::endl; | 2468 cerr << "\noverallMagChanged - updating all\n" << endl; |
| 2468 cache.validArea = QRect(); | 2469 cache.validArea = QRect(); |
| 2469 v->update(); | 2470 v->update(); |
| 2470 } | 2471 } |
| 2471 } | 2472 } |
| 2472 | 2473 |
| 2538 if (sx < 0 || sx >= int(fft->getWidth())) continue; | 2539 if (sx < 0 || sx >= int(fft->getWidth())) continue; |
| 2539 | 2540 |
| 2540 if (!m_synchronous) { | 2541 if (!m_synchronous) { |
| 2541 if (!fft->isColumnAvailable(sx)) { | 2542 if (!fft->isColumnAvailable(sx)) { |
| 2542 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2543 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 2543 std::cerr << "Met unavailable column at col " << sx << std::endl; | 2544 cerr << "Met unavailable column at col " << sx << endl; |
| 2544 #endif | 2545 #endif |
| 2545 return false; | 2546 return false; |
| 2546 } | 2547 } |
| 2547 } | 2548 } |
| 2548 | 2549 |
| 2590 } | 2591 } |
| 2591 | 2592 |
| 2592 if (mag.isSet()) { | 2593 if (mag.isSet()) { |
| 2593 if (sx >= int(m_columnMags.size())) { | 2594 if (sx >= int(m_columnMags.size())) { |
| 2594 #ifdef DEBUG_SPECTROGRAM | 2595 #ifdef DEBUG_SPECTROGRAM |
| 2595 std::cerr << "INTERNAL ERROR: " << sx << " >= " | 2596 cerr << "INTERNAL ERROR: " << sx << " >= " |
| 2596 << m_columnMags.size() | 2597 << m_columnMags.size() |
| 2597 << " at SpectrogramLayer.cpp::paintDrawBuffer" | 2598 << " at SpectrogramLayer.cpp::paintDrawBuffer" |
| 2598 << std::endl; | 2599 << endl; |
| 2599 #endif | 2600 #endif |
| 2600 } else { | 2601 } else { |
| 2601 m_columnMags[sx].sample(mag); | 2602 m_columnMags[sx].sample(mag); |
| 2602 if (overallMag.sample(mag)) overallMagChanged = true; | 2603 if (overallMag.sample(mag)) overallMagChanged = true; |
| 2603 } | 2604 } |
| 2687 for (int y = 0; y < h; ++y) peaks[y] = 0.f; | 2688 for (int y = 0; y < h; ++y) peaks[y] = 0.f; |
| 2688 | 2689 |
| 2689 for (int sx = sx0; sx < sx1; ++sx) { | 2690 for (int sx = sx0; sx < sx1; ++sx) { |
| 2690 | 2691 |
| 2691 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2692 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 2692 // std::cerr << "sx = " << sx << std::endl; | 2693 // cerr << "sx = " << sx << endl; |
| 2693 #endif | 2694 #endif |
| 2694 | 2695 |
| 2695 if (sx < 0 || sx >= int(sourceModel->getWidth())) continue; | 2696 if (sx < 0 || sx >= int(sourceModel->getWidth())) continue; |
| 2696 | 2697 |
| 2697 if (!m_synchronous) { | 2698 if (!m_synchronous) { |
| 2698 if (!sourceModel->isColumnAvailable(sx)) { | 2699 if (!sourceModel->isColumnAvailable(sx)) { |
| 2699 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2700 #ifdef DEBUG_SPECTROGRAM_REPAINT |
| 2700 std::cerr << "Met unavailable column at col " << sx << std::endl; | 2701 cerr << "Met unavailable column at col " << sx << endl; |
| 2701 #endif | 2702 #endif |
| 2702 return false; | 2703 return false; |
| 2703 } | 2704 } |
| 2704 } | 2705 } |
| 2705 | 2706 |
| 2803 } | 2804 } |
| 2804 | 2805 |
| 2805 if (mag.isSet()) { | 2806 if (mag.isSet()) { |
| 2806 if (sx >= int(m_columnMags.size())) { | 2807 if (sx >= int(m_columnMags.size())) { |
| 2807 #ifdef DEBUG_SPECTROGRAM | 2808 #ifdef DEBUG_SPECTROGRAM |
| 2808 std::cerr << "INTERNAL ERROR: " << sx << " >= " | 2809 cerr << "INTERNAL ERROR: " << sx << " >= " |
| 2809 << m_columnMags.size() | 2810 << m_columnMags.size() |
| 2810 << " at SpectrogramLayer.cpp::paintDrawBuffer" | 2811 << " at SpectrogramLayer.cpp::paintDrawBuffer" |
| 2811 << std::endl; | 2812 << endl; |
| 2812 #endif | 2813 #endif |
| 2813 } else { | 2814 } else { |
| 2814 m_columnMags[sx].sample(mag); | 2815 m_columnMags[sx].sample(mag); |
| 2815 if (overallMag.sample(mag)) overallMagChanged = true; | 2816 if (overallMag.sample(mag)) overallMagChanged = true; |
| 2816 } | 2817 } |
| 2844 QPoint localPos; | 2845 QPoint localPos; |
| 2845 if (!v->shouldIlluminateLocalFeatures(this, localPos) || !m_model) { | 2846 if (!v->shouldIlluminateLocalFeatures(this, localPos) || !m_model) { |
| 2846 return; | 2847 return; |
| 2847 } | 2848 } |
| 2848 | 2849 |
| 2849 // std::cerr << "SpectrogramLayer: illuminateLocalFeatures(" | 2850 // cerr << "SpectrogramLayer: illuminateLocalFeatures(" |
| 2850 // << localPos.x() << "," << localPos.y() << ")" << std::endl; | 2851 // << localPos.x() << "," << localPos.y() << ")" << endl; |
| 2851 | 2852 |
| 2852 float s0, s1; | 2853 float s0, s1; |
| 2853 float f0, f1; | 2854 float f0, f1; |
| 2854 | 2855 |
| 2855 if (getXBinRange(v, localPos.x(), s0, s1) && | 2856 if (getXBinRange(v, localPos.x(), s0, s1) && |
| 2862 int x1 = v->getXForFrame((s1i + 1) * getWindowIncrement()); | 2863 int x1 = v->getXForFrame((s1i + 1) * getWindowIncrement()); |
| 2863 | 2864 |
| 2864 int y1 = int(getYForFrequency(v, f1)); | 2865 int y1 = int(getYForFrequency(v, f1)); |
| 2865 int y0 = int(getYForFrequency(v, f0)); | 2866 int y0 = int(getYForFrequency(v, f0)); |
| 2866 | 2867 |
| 2867 // std::cerr << "SpectrogramLayer: illuminate " | 2868 // cerr << "SpectrogramLayer: illuminate " |
| 2868 // << x0 << "," << y1 << " -> " << x1 << "," << y0 << std::endl; | 2869 // << x0 << "," << y1 << " -> " << x1 << "," << y0 << endl; |
| 2869 | 2870 |
| 2870 paint.setPen(v->getForeground()); | 2871 paint.setPen(v->getForeground()); |
| 2871 | 2872 |
| 2872 //!!! should we be using paintCrosshairs for this? | 2873 //!!! should we be using paintCrosshairs for this? |
| 2873 | 2874 |
| 3004 void | 3005 void |
| 3005 SpectrogramLayer::measureDoubleClick(View *v, QMouseEvent *e) | 3006 SpectrogramLayer::measureDoubleClick(View *v, QMouseEvent *e) |
| 3006 { | 3007 { |
| 3007 ImageCache &cache = m_imageCaches[v]; | 3008 ImageCache &cache = m_imageCaches[v]; |
| 3008 | 3009 |
| 3009 std::cerr << "cache width: " << cache.image.width() << ", height: " | 3010 cerr << "cache width: " << cache.image.width() << ", height: " |
| 3010 << cache.image.height() << std::endl; | 3011 << cache.image.height() << endl; |
| 3011 | 3012 |
| 3012 QImage image = cache.image; | 3013 QImage image = cache.image; |
| 3013 | 3014 |
| 3014 ImageRegionFinder finder; | 3015 ImageRegionFinder finder; |
| 3015 QRect rect = finder.findRegionExtents(&image, e->pos()); | 3016 QRect rect = finder.findRegionExtents(&image, e->pos()); |
| 3433 | 3434 |
| 3434 if (m_frequencyScale == LogFrequencyScale) { | 3435 if (m_frequencyScale == LogFrequencyScale) { |
| 3435 | 3436 |
| 3436 // piano keyboard | 3437 // piano keyboard |
| 3437 | 3438 |
| 3438 paint.drawLine(w - pkw - 1, 0, w - pkw - 1, h); | 3439 PianoScale().paintPianoVertical |
| 3439 | 3440 (v, paint, QRect(w - pkw - 1, 0, pkw, h), |
| 3440 float minf = getEffectiveMinFrequency(); | 3441 getEffectiveMinFrequency(), getEffectiveMaxFrequency()); |
| 3441 float maxf = getEffectiveMaxFrequency(); | |
| 3442 | |
| 3443 int py = h, ppy = h; | |
| 3444 paint.setBrush(paint.pen().color()); | |
| 3445 | |
| 3446 for (int i = 0; i < 128; ++i) { | |
| 3447 | |
| 3448 float f = Pitch::getFrequencyForPitch(i); | |
| 3449 int y = lrintf(v->getYForFrequency(f, minf, maxf, true)); | |
| 3450 | |
| 3451 if (y < -2) break; | |
| 3452 if (y > h + 2) { | |
| 3453 continue; | |
| 3454 } | |
| 3455 | |
| 3456 int n = (i % 12); | |
| 3457 | |
| 3458 if (n == 1) { | |
| 3459 // C# -- fill the C from here | |
| 3460 QColor col = Qt::gray; | |
| 3461 if (i == 61) { // filling middle C | |
| 3462 col = Qt::blue; | |
| 3463 col = col.light(150); | |
| 3464 } | |
| 3465 if (ppy - y > 2) { | |
| 3466 paint.fillRect(w - pkw, | |
| 3467 y, | |
| 3468 pkw, | |
| 3469 (py + ppy) / 2 - y, | |
| 3470 col); | |
| 3471 } | |
| 3472 } | |
| 3473 | |
| 3474 if (n == 1 || n == 3 || n == 6 || n == 8 || n == 10) { | |
| 3475 // black notes | |
| 3476 paint.drawLine(w - pkw, y, w, y); | |
| 3477 int rh = ((py - y) / 4) * 2; | |
| 3478 if (rh < 2) rh = 2; | |
| 3479 paint.drawRect(w - pkw, y - (py-y)/4, pkw/2, rh); | |
| 3480 } else if (n == 0 || n == 5) { | |
| 3481 // C, F | |
| 3482 if (py < h) { | |
| 3483 paint.drawLine(w - pkw, (y + py) / 2, w, (y + py) / 2); | |
| 3484 } | |
| 3485 } | |
| 3486 | |
| 3487 ppy = py; | |
| 3488 py = y; | |
| 3489 } | |
| 3490 } | 3442 } |
| 3491 | 3443 |
| 3492 m_haveDetailedScale = detailed; | 3444 m_haveDetailedScale = detailed; |
| 3493 } | 3445 } |
| 3494 | 3446 |
| 3582 if (!m_model) return; | 3534 if (!m_model) return; |
| 3583 | 3535 |
| 3584 float dmin = m_minFrequency, dmax = m_maxFrequency; | 3536 float dmin = m_minFrequency, dmax = m_maxFrequency; |
| 3585 // getDisplayExtents(dmin, dmax); | 3537 // getDisplayExtents(dmin, dmax); |
| 3586 | 3538 |
| 3587 // std::cerr << "current range " << dmin << " -> " << dmax << ", range " << dmax-dmin << ", mid " << (dmax + dmin)/2 << std::endl; | 3539 // cerr << "current range " << dmin << " -> " << dmax << ", range " << dmax-dmin << ", mid " << (dmax + dmin)/2 << endl; |
| 3588 | 3540 |
| 3589 int sr = m_model->getSampleRate(); | 3541 int sr = m_model->getSampleRate(); |
| 3590 SpectrogramRangeMapper mapper(sr, m_fftSize); | 3542 SpectrogramRangeMapper mapper(sr, m_fftSize); |
| 3591 float newdist = mapper.getValueForPosition(step); | 3543 float newdist = mapper.getValueForPosition(step); |
| 3592 | 3544 |
| 3616 // so newmax = (newdist + sqrtf(newdist^2 + 4dmin.dmax)) / 2 | 3568 // so newmax = (newdist + sqrtf(newdist^2 + 4dmin.dmax)) / 2 |
| 3617 | 3569 |
| 3618 newmax = (newdist + sqrtf(newdist*newdist + 4*dmin*dmax)) / 2; | 3570 newmax = (newdist + sqrtf(newdist*newdist + 4*dmin*dmax)) / 2; |
| 3619 newmin = newmax - newdist; | 3571 newmin = newmax - newdist; |
| 3620 | 3572 |
| 3621 // std::cerr << "newmin = " << newmin << ", newmax = " << newmax << std::endl; | 3573 // cerr << "newmin = " << newmin << ", newmax = " << newmax << endl; |
| 3622 | 3574 |
| 3623 } else { | 3575 } else { |
| 3624 float dmid = (dmax + dmin) / 2; | 3576 float dmid = (dmax + dmin) / 2; |
| 3625 newmin = dmid - newdist / 2; | 3577 newmin = dmid - newdist / 2; |
| 3626 newmax = dmid + newdist / 2; | 3578 newmax = dmid + newdist / 2; |
