comparison layer/SpectrogramLayer.cpp @ 224:9465b5375235

* Fix #1672407 confused by plugin-named files in cwd (or home?) * Fix #1491848 crash when loading new file while transform plugin runs * Fix #1502287 Background remains black after spectrogram layer deleted * Fix #1604477 Replacing the main audio file silences secondary audio file * Fix failure to initialise property box layout to last preference on startup * Fix resample/wrong-rate display in Pane, ensure that right rate is chosen if all current models have an acceptable rate even if previous main model had a different one * Fix "global zoom" broken in previous commit * Some fixes to spectrogram cache area updating (makes spectrogram appear more quickly, previously it had a tendency to refresh with empty space) * Fixes to colour 3d plot normalization
author Chris Cannam
date Thu, 08 Mar 2007 16:53:08 +0000
parents cd81066ac7ad
children b4809e942e7d
comparison
equal deleted inserted replaced
223:403bfb88d8d6 224:9465b5375235
79 setMaxFrequency(1500); 79 setMaxFrequency(1500);
80 setMinFrequency(40); 80 setMinFrequency(40);
81 setColourScale(LinearColourScale); 81 setColourScale(LinearColourScale);
82 setColourMap(ColourMapper::Sunset); 82 setColourMap(ColourMapper::Sunset);
83 setFrequencyScale(LogFrequencyScale); 83 setFrequencyScale(LogFrequencyScale);
84 setGain(20); 84 // setGain(20);
85 } else if (config == MelodicPeaks) { 85 } else if (config == MelodicPeaks) {
86 setWindowSize(4096); 86 setWindowSize(4096);
87 setWindowHopLevel(5); 87 setWindowHopLevel(5);
88 m_initialMaxFrequency = 2000; 88 m_initialMaxFrequency = 2000;
89 setMaxFrequency(2000); 89 setMaxFrequency(2000);
1013 delete m_updateTimer; 1013 delete m_updateTimer;
1014 m_updateTimer = 0; 1014 m_updateTimer = 0;
1015 } 1015 }
1016 } 1016 }
1017 1017
1018 bool
1019 SpectrogramLayer::hasLightBackground() const
1020 {
1021 return (m_colourMap == (int)ColourMapper::BlackOnWhite);
1022 }
1023
1018 void 1024 void
1019 SpectrogramLayer::initialisePalette() 1025 SpectrogramLayer::initialisePalette()
1020 { 1026 {
1021 int formerRotation = m_colourRotation; 1027 int formerRotation = m_colourRotation;
1022 1028
1110 1116
1111 if (m_normalizeVisibleArea) { 1117 if (m_normalizeVisibleArea) {
1112 min = m_viewMags[v].getMin(); 1118 min = m_viewMags[v].getMin();
1113 max = m_viewMags[v].getMax(); 1119 max = m_viewMags[v].getMax();
1114 } else if (!m_normalizeColumns) { 1120 } else if (!m_normalizeColumns) {
1115 if (m_colourScale == LinearColourScale || 1121 if (m_colourScale == LinearColourScale //||
1116 m_colourScale == MeterColourScale) { 1122 // m_colourScale == MeterColourScale) {
1117 // max = 0.1f; 1123 ) {
1124 max = 0.1f;
1118 } 1125 }
1119 } 1126 }
1120 1127
1121 float thresh = -80.f; 1128 float thresh = -80.f;
1122 1129
1685 } 1692 }
1686 1693
1687 void 1694 void
1688 SpectrogramLayer::paint(View *v, QPainter &paint, QRect rect) const 1695 SpectrogramLayer::paint(View *v, QPainter &paint, QRect rect) const
1689 { 1696 {
1690 if (m_colourMap == (int)ColourMapper::BlackOnWhite) {
1691 v->setLightBackground(true);
1692 } else {
1693 v->setLightBackground(false);
1694 }
1695
1696 Profiler profiler("SpectrogramLayer::paint", true); 1697 Profiler profiler("SpectrogramLayer::paint", true);
1697 #ifdef DEBUG_SPECTROGRAM_REPAINT 1698 #ifdef DEBUG_SPECTROGRAM_REPAINT
1698 std::cerr << "SpectrogramLayer::paint(): m_model is " << m_model << ", zoom level is " << v->getZoomLevel() << ", m_updateTimer " << m_updateTimer << std::endl; 1699 std::cerr << "SpectrogramLayer::paint(): m_model is " << m_model << ", zoom level is " << v->getZoomLevel() << ", m_updateTimer " << m_updateTimer << std::endl;
1699 1700
1700 std::cerr << "rect is " << rect.x() << "," << rect.y() << " " << rect.width() << "x" << rect.height() << std::endl; 1701 std::cerr << "rect is " << rect.x() << "," << rect.y() << " " << rect.width() << "x" << rect.height() << std::endl;
1740 1741
1741 int zoomLevel = v->getZoomLevel(); 1742 int zoomLevel = v->getZoomLevel();
1742 1743
1743 int x0 = 0; 1744 int x0 = 0;
1744 int x1 = v->width(); 1745 int x1 = v->width();
1745 int y0 = 0;
1746 int y1 = v->height();
1747 1746
1748 bool recreateWholePixmapCache = true; 1747 bool recreateWholePixmapCache = true;
1749 1748
1750 x0 = rect.left(); 1749 x0 = rect.left();
1751 x1 = rect.right() + 1; 1750 x1 = rect.right() + 1;
1752 y0 = rect.top();
1753 y1 = rect.bottom() + 1;
1754 1751
1755 if (cache.validArea.width() > 0) { 1752 if (cache.validArea.width() > 0) {
1756 1753
1757 if (int(cache.zoomLevel) == zoomLevel && 1754 if (int(cache.zoomLevel) == zoomLevel &&
1758 cache.pixmap.width() == v->width() && 1755 cache.pixmap.width() == v->width() &&
1850 } 1847 }
1851 } 1848 }
1852 } else { 1849 } else {
1853 #ifdef DEBUG_SPECTROGRAM_REPAINT 1850 #ifdef DEBUG_SPECTROGRAM_REPAINT
1854 std::cerr << "SpectrogramLayer: pixmap cache useless" << std::endl; 1851 std::cerr << "SpectrogramLayer: pixmap cache useless" << std::endl;
1852 if (int(cache.zoomLevel) != zoomLevel) {
1853 std::cerr << "(cache zoomLevel " << cache.zoomLevel
1854 << " != " << zoomLevel << ")" << std::endl;
1855 }
1856 if (cache.pixmap.width() != v->width()) {
1857 std::cerr << "(cache width " << cache.pixmap.width()
1858 << " != " << v->width();
1859 }
1860 if (cache.pixmap.height() != v->height()) {
1861 std::cerr << "(cache height " << cache.pixmap.height()
1862 << " != " << v->height();
1863 }
1855 #endif 1864 #endif
1856 cache.validArea = QRect(); 1865 cache.validArea = QRect();
1857 } 1866 }
1858 } 1867 }
1859
1860 /*
1861 if (stillCacheing) {
1862 x0 = rect.left();
1863 x1 = rect.right() + 1;
1864 y0 = rect.top();
1865 y1 = rect.bottom() + 1;
1866 }
1867 */
1868 1868
1869 if (updateViewMagnitudes(v)) { 1869 if (updateViewMagnitudes(v)) {
1870 #ifdef DEBUG_SPECTROGRAM_REPAINT 1870 #ifdef DEBUG_SPECTROGRAM_REPAINT
1871 std::cerr << "SpectrogramLayer: magnitude range changed to [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "]" << std::endl; 1871 std::cerr << "SpectrogramLayer: magnitude range changed to [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "]" << std::endl;
1872 #endif 1872 #endif
1904 } 1904 }
1905 } 1905 }
1906 1906
1907 if (paintBlockWidth < 20) paintBlockWidth = 20; 1907 if (paintBlockWidth < 20) paintBlockWidth = 20;
1908 1908
1909 #ifdef DEBUG_SPECTROGRAM_REPAINT
1909 std::cerr << "[" << this << "]: last paint width: " << m_lastPaintBlockWidth << ", last paint time: " << m_lastPaintTime << ", new paint width: " << paintBlockWidth << std::endl; 1910 std::cerr << "[" << this << "]: last paint width: " << m_lastPaintBlockWidth << ", last paint time: " << m_lastPaintTime << ", new paint width: " << paintBlockWidth << std::endl;
1911 #endif
1912
1913 // We always paint the full height when refreshing the cache.
1914 // Smaller heights can be used when painting direct from cache
1915 // (further up in this function), but we want to ensure the cache
1916 // is coherent without having to worry about vertical matching of
1917 // required and valid areas as well as horizontal.
1918
1919 int h = v->height();
1910 1920
1911 if (cache.validArea.width() > 0) { 1921 if (cache.validArea.width() > 0) {
1912 1922
1913 int vx0 = 0, vx1 = 0; 1923 int vx0 = 0, vx1 = 0;
1914 vx0 = cache.validArea.x(); 1924 vx0 = cache.validArea.x();
1954 int mid = (x1 + x0) / 2; 1964 int mid = (x1 + x0) / 2;
1955 x0 = mid - paintBlockWidth/2; 1965 x0 = mid - paintBlockWidth/2;
1956 x1 = x0 + paintBlockWidth; 1966 x1 = x0 + paintBlockWidth;
1957 } 1967 }
1958 } 1968 }
1959 cache.validArea = QRect(x0, 0, x1 - x0, v->height()); 1969 cache.validArea = QRect(x0, 0, x1 - x0, h);
1960 } 1970 }
1961 1971
1962 int w = x1 - x0; 1972 int w = x1 - x0;
1963 int h = y1 - y0;
1964 1973
1965 #ifdef DEBUG_SPECTROGRAM_REPAINT 1974 #ifdef DEBUG_SPECTROGRAM_REPAINT
1966 std::cerr << "x0 " << x0 << ", x1 " << x1 << ", w " << w << ", h " << h << std::endl; 1975 std::cerr << "x0 " << x0 << ", x1 " << x1 << ", w " << w << ", h " << h << std::endl;
1967 #endif 1976 #endif
1968 1977
2031 m_binDisplay != PeakFrequencies) { 2040 m_binDisplay != PeakFrequencies) {
2032 interpolate = true; 2041 interpolate = true;
2033 } 2042 }
2034 } 2043 }
2035 2044
2036 2045 #ifdef DEBUG_SPECTROGRAM_REPAINT
2037 #ifdef DEBUG_SPECTROGRAM_REPAINT 2046 std::cerr << ((float(v->getFrameForX(1) - v->getFrameForX(0))) / increment) << " bin(s) per pixel" << std::endl;
2038 std::cerr << (float(v->getFrameForX(1) - v->getFrameForX(0)) / increment) << " bins per pixel" << std::endl; 2047 #endif
2039 #endif 2048
2049 bool runOutOfData = false;
2040 2050
2041 for (int x = 0; x < w; ++x) { 2051 for (int x = 0; x < w; ++x) {
2052
2053 if (runOutOfData) break;
2042 2054
2043 for (int y = 0; y < h; ++y) { 2055 for (int y = 0; y < h; ++y) {
2044 ymag[y] = 0.f; 2056 ymag[y] = 0.f;
2045 ydiv[y] = 0.f; 2057 ydiv[y] = 0.f;
2046 } 2058 }
2063 } 2075 }
2064 } 2076 }
2065 2077
2066 for (int s = s0i; s <= s1i; ++s) { 2078 for (int s = s0i; s <= s1i; ++s) {
2067 2079
2068 if (!fft->isColumnAvailable(s)) continue; 2080 if (!fft->isColumnAvailable(s)) {
2081 #ifdef DEBUG_SPECTROGRAM_REPAINT
2082 std::cerr << "Met unavailable column at col " << s << std::endl;
2083 #endif
2084 // continue;
2085 runOutOfData = true;
2086 break;
2087 }
2069 2088
2070 if (!fftSuspended) { 2089 if (!fftSuspended) {
2071 fft->suspendWrites(); 2090 fft->suspendWrites();
2072 fftSuspended = true; 2091 fftSuspended = true;
2073 } 2092 }
2234 #endif 2253 #endif
2235 } 2254 }
2236 2255
2237 Profiler profiler2("SpectrogramLayer::paint: draw image", true); 2256 Profiler profiler2("SpectrogramLayer::paint: draw image", true);
2238 2257
2239 paint.drawImage(x0, y0, m_drawBuffer, 0, 0, w, h); 2258 #ifdef DEBUG_SPECTROGRAM_REPAINT
2259 std::cerr << "Painting " << w << "x" << rect.height()
2260 << " from draw buffer at " << 0 << "," << rect.y()
2261 << " to window at " << x0 << "," << rect.y() << std::endl;
2262 #endif
2263
2264 paint.drawImage(x0, rect.y(), m_drawBuffer, 0, rect.y(), w, rect.height());
2240 2265
2241 if (recreateWholePixmapCache) { 2266 if (recreateWholePixmapCache) {
2242 cache.pixmap = QPixmap(v->width(), v->height()); 2267 cache.pixmap = QPixmap(v->width(), h);
2243 } 2268 }
2269
2270 #ifdef DEBUG_SPECTROGRAM_REPAINT
2271 std::cerr << "Painting " << w << "x" << h
2272 << " from draw buffer at " << 0 << "," << 0
2273 << " to cache at " << x0 << "," << 0 << std::endl;
2274 #endif
2244 2275
2245 QPainter cachePainter(&cache.pixmap); 2276 QPainter cachePainter(&cache.pixmap);
2246 cachePainter.drawImage(x0, y0, m_drawBuffer, 0, 0, w, h); 2277 cachePainter.drawImage(x0, 0, m_drawBuffer, 0, 0, w, h);
2247 cachePainter.end(); 2278 cachePainter.end();
2248 2279
2249 if (!m_normalizeVisibleArea || !overallMagChanged) { 2280 if (!m_normalizeVisibleArea || !overallMagChanged) {
2250 2281
2251 cache.startFrame = startFrame; 2282 cache.startFrame = startFrame;
2254 if (cache.validArea.x() > 0) { 2285 if (cache.validArea.x() > 0) {
2255 #ifdef DEBUG_SPECTROGRAM_REPAINT 2286 #ifdef DEBUG_SPECTROGRAM_REPAINT
2256 std::cerr << "SpectrogramLayer::paint() updating left (0, " 2287 std::cerr << "SpectrogramLayer::paint() updating left (0, "
2257 << cache.validArea.x() << ")" << std::endl; 2288 << cache.validArea.x() << ")" << std::endl;
2258 #endif 2289 #endif
2259 v->update(0, 0, cache.validArea.x(), v->height()); 2290 v->update(0, 0, cache.validArea.x(), h);
2260 } 2291 }
2261 2292
2262 if (cache.validArea.x() + cache.validArea.width() < 2293 if (cache.validArea.x() + cache.validArea.width() <
2263 cache.pixmap.width()) { 2294 cache.pixmap.width()) {
2264 #ifdef DEBUG_SPECTROGRAM_REPAINT 2295 #ifdef DEBUG_SPECTROGRAM_REPAINT
2271 #endif 2302 #endif
2272 v->update(cache.validArea.x() + cache.validArea.width(), 2303 v->update(cache.validArea.x() + cache.validArea.width(),
2273 0, 2304 0,
2274 cache.pixmap.width() - (cache.validArea.x() + 2305 cache.pixmap.width() - (cache.validArea.x() +
2275 cache.validArea.width()), 2306 cache.validArea.width()),
2276 v->height()); 2307 h);
2277 } 2308 }
2278 } else { 2309 } else {
2279 // overallMagChanged 2310 // overallMagChanged
2280 cache.validArea = QRect(); 2311 cache.validArea = QRect();
2281 v->update(); 2312 v->update();
2354 { 2385 {
2355 if (m_updateTimer == 0) return 100; 2386 if (m_updateTimer == 0) return 100;
2356 if (m_fftModels.find(v) == m_fftModels.end()) return 100; 2387 if (m_fftModels.find(v) == m_fftModels.end()) return 100;
2357 2388
2358 size_t completion = m_fftModels[v].first->getCompletion(); 2389 size_t completion = m_fftModels[v].first->getCompletion();
2390 #ifdef DEBUG_SPECTROGRAM_REPAINT
2359 std::cerr << "SpectrogramLayer::getCompletion: completion = " << completion << std::endl; 2391 std::cerr << "SpectrogramLayer::getCompletion: completion = " << completion << std::endl;
2392 #endif
2360 return completion; 2393 return completion;
2361 } 2394 }
2362 2395
2363 bool 2396 bool
2364 SpectrogramLayer::getValueExtents(float &min, float &max, 2397 SpectrogramLayer::getValueExtents(float &min, float &max,