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;