Mercurial > hg > svgui
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, |