Mercurial > hg > svgui
comparison layer/SpectrogramLayer.cpp @ 1023:74755fa6ea9e colourschemes
Avoid reusing a large paint width if the zoom level has changed (in case it has changed dramatically, as for example when the user hits the F key). Also some tidying and adjustment to timing stuff
author | Chris Cannam |
---|---|
date | Fri, 22 Jan 2016 18:12:41 +0000 |
parents | 2bd5eb6a6c6b |
children | 3bce4c45b681 |
comparison
equal
deleted
inserted
replaced
1022:2bd5eb6a6c6b | 1023:74755fa6ea9e |
---|---|
47 | 47 |
48 #ifndef __GNUC__ | 48 #ifndef __GNUC__ |
49 #include <alloca.h> | 49 #include <alloca.h> |
50 #endif | 50 #endif |
51 | 51 |
52 #define DEBUG_SPECTROGRAM_REPAINT 1 | 52 //#define DEBUG_SPECTROGRAM_REPAINT 1 |
53 | 53 |
54 using std::vector; | 54 using std::vector; |
55 | 55 |
56 SpectrogramLayer::SpectrogramLayer(Configuration config) : | 56 SpectrogramLayer::SpectrogramLayer(Configuration config) : |
57 m_model(0), | 57 m_model(0), |
1729 if (m_normalization == NormalizeVisibleArea) { | 1729 if (m_normalization == NormalizeVisibleArea) { |
1730 cache.validArea = QRect(); | 1730 cache.validArea = QRect(); |
1731 } | 1731 } |
1732 } | 1732 } |
1733 | 1733 |
1734 if (cache.zoomLevel != zoomLevel) { | |
1735 // no matter what we do with the cache, we'll need to | |
1736 // recalculate our paint width again because each block will | |
1737 // take a different time to render from previously | |
1738 m_lastPaintBlockWidth = 0; | |
1739 } | |
1740 | |
1734 if (cache.validArea.width() > 0) { | 1741 if (cache.validArea.width() > 0) { |
1735 | 1742 |
1736 int cw = cache.image.width(); | 1743 int cw = cache.image.width(); |
1737 int ch = cache.image.height(); | 1744 int ch = cache.image.height(); |
1738 | 1745 |
1866 if (recreateWholeImageCache) { | 1873 if (recreateWholeImageCache) { |
1867 x0 = 0; | 1874 x0 = 0; |
1868 x1 = v->getPaintWidth(); | 1875 x1 = v->getPaintWidth(); |
1869 } | 1876 } |
1870 | 1877 |
1871 struct timeval tv; | 1878 auto mainPaintStart = std::chrono::steady_clock::now(); |
1872 (void)gettimeofday(&tv, 0); | |
1873 RealTime mainPaintStart = RealTime::fromTimeval(tv); | |
1874 | 1879 |
1875 int paintBlockWidth = m_lastPaintBlockWidth; | 1880 int paintBlockWidth = m_lastPaintBlockWidth; |
1876 | 1881 |
1877 if (m_synchronous) { | 1882 if (m_synchronous) { |
1878 if (paintBlockWidth < x1 - x0) { | 1883 if (paintBlockWidth < x1 - x0) { |
1881 } | 1886 } |
1882 } else { | 1887 } else { |
1883 if (paintBlockWidth == 0) { | 1888 if (paintBlockWidth == 0) { |
1884 paintBlockWidth = (300000 / zoomLevel); | 1889 paintBlockWidth = (300000 / zoomLevel); |
1885 } else { | 1890 } else { |
1886 RealTime lastTime = m_lastPaintTime; | 1891 double lastTime = m_lastPaintTime; |
1887 while (lastTime > RealTime::fromMilliseconds(200) && | 1892 while (lastTime > 0.2 && |
1888 paintBlockWidth > 50) { | 1893 paintBlockWidth > 30) { |
1889 paintBlockWidth /= 2; | 1894 paintBlockWidth /= 2; |
1890 lastTime = lastTime / 2; | 1895 lastTime = lastTime / 2; |
1891 } | 1896 } |
1892 while (lastTime < RealTime::fromMilliseconds(90) && | 1897 while (lastTime < 0.09 && |
1898 paintBlockWidth < std::max(50, 1200000 / zoomLevel) && | |
1893 paintBlockWidth < 1500) { | 1899 paintBlockWidth < 1500) { |
1894 paintBlockWidth *= 2; | 1900 paintBlockWidth *= 2; |
1895 lastTime = lastTime * 2; | 1901 lastTime = lastTime * 2; |
1896 } | 1902 } |
1897 } | 1903 } |
1898 | 1904 |
1899 if (paintBlockWidth < 20) paintBlockWidth = 20; | 1905 if (paintBlockWidth < 20) paintBlockWidth = 20; |
1900 } | 1906 } |
1901 | 1907 |
1902 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1908 //#ifdef DEBUG_SPECTROGRAM_REPAINT |
1903 cerr << "[" << this << "]: last paint width: " << m_lastPaintBlockWidth << ", last paint time: " << m_lastPaintTime << ", new paint width: " << paintBlockWidth << endl; | 1909 cerr << "[" << this << "]: last paint width: " << m_lastPaintBlockWidth << ", last paint time: " << m_lastPaintTime << ", new paint width: " << paintBlockWidth << endl; |
1904 #endif | 1910 //#endif |
1905 | 1911 |
1906 // We always paint the full height when refreshing the cache. | 1912 // We always paint the full height when refreshing the cache. |
1907 // Smaller heights can be used when painting direct from cache | 1913 // Smaller heights can be used when painting direct from cache |
1908 // (further up in this function), but we want to ensure the cache | 1914 // (further up in this function), but we want to ensure the cache |
1909 // is coherent without having to worry about vertical matching of | 1915 // is coherent without having to worry about vertical matching of |
2154 double q0 = 0, q1 = 0; | 2160 double q0 = 0, q1 = 0; |
2155 if (!getSmoothedYBinRange(v, h-y-1, q0, q1)) { | 2161 if (!getSmoothedYBinRange(v, h-y-1, q0, q1)) { |
2156 binfory[y] = -1; | 2162 binfory[y] = -1; |
2157 } else { | 2163 } else { |
2158 binfory[y] = q0; | 2164 binfory[y] = q0; |
2159 // cerr << "binfory[" << y << "] = " << binfory[y] << endl; | |
2160 } | 2165 } |
2161 } | 2166 } |
2162 | 2167 |
2163 paintDrawBuffer(v, bufwid, h, binforx, binfory, usePeaksCache, | 2168 paintDrawBuffer(v, bufwid, h, binforx, binfory, usePeaksCache, |
2164 overallMag, overallMagChanged); | 2169 overallMag, overallMagChanged); |
2170 displayMinFreq, displayMaxFreq, | 2175 displayMinFreq, displayMaxFreq, |
2171 logarithmic, | 2176 logarithmic, |
2172 overallMag, overallMagChanged); | 2177 overallMag, overallMagChanged); |
2173 } | 2178 } |
2174 | 2179 |
2175 /* | |
2176 for (int x = 0; x < w / xPixelRatio; ++x) { | |
2177 | |
2178 Profiler innerprof("SpectrogramLayer::paint: 1 pixel column"); | |
2179 | |
2180 runOutOfData = !paintColumnValues(v, fft, x0, x, | |
2181 minbin, maxbin, | |
2182 displayMinFreq, displayMaxFreq, | |
2183 xPixelRatio, | |
2184 h, yforbin); | |
2185 | |
2186 if (runOutOfData) { | |
2187 #ifdef DEBUG_SPECTROGRAM_REPAINT | |
2188 cerr << "Run out of data -- dropping out of loop" << endl; | |
2189 #endif | |
2190 break; | |
2191 } | |
2192 } | |
2193 */ | |
2194 #ifdef DEBUG_SPECTROGRAM_REPAINT | |
2195 // cerr << pixels << " pixels drawn" << endl; | |
2196 #endif | |
2197 | |
2198 if (overallMagChanged) { | 2180 if (overallMagChanged) { |
2199 m_viewMags[v] = overallMag; | 2181 m_viewMags[v] = overallMag; |
2200 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2182 #ifdef DEBUG_SPECTROGRAM_REPAINT |
2201 cerr << "Overall mag is now [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "] - will be updating" << endl; | 2183 cerr << "Overall mag is now [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "] - will be updating" << endl; |
2202 #endif | |
2203 } else { | |
2204 #ifdef DEBUG_SPECTROGRAM_REPAINT | |
2205 cerr << "Overall mag unchanged at [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "]" << endl; | |
2206 #endif | 2184 #endif |
2207 } | 2185 } |
2208 | 2186 |
2209 outerprof.end(); | 2187 outerprof.end(); |
2210 | 2188 |
2273 << " to window" << endl; | 2251 << " to window" << endl; |
2274 #endif | 2252 #endif |
2275 | 2253 |
2276 paint.drawImage(pr.x(), pr.y(), cache.image, | 2254 paint.drawImage(pr.x(), pr.y(), cache.image, |
2277 pr.x(), pr.y(), pr.width(), pr.height()); | 2255 pr.x(), pr.y(), pr.width(), pr.height()); |
2278 //!!! | |
2279 // paint.drawImage(v->rect(), cache.image, | |
2280 // QRect(QPoint(0, 0), cache.image.size())); | |
2281 | 2256 |
2282 cache.startFrame = startFrame; | 2257 cache.startFrame = startFrame; |
2283 cache.zoomLevel = zoomLevel; | 2258 cache.zoomLevel = zoomLevel; |
2284 | 2259 |
2285 if (!m_synchronous) { | 2260 if (!m_synchronous) { |
2323 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2298 #ifdef DEBUG_SPECTROGRAM_REPAINT |
2324 cerr << "SpectrogramLayer::paint() returning" << endl; | 2299 cerr << "SpectrogramLayer::paint() returning" << endl; |
2325 #endif | 2300 #endif |
2326 | 2301 |
2327 if (!m_synchronous) { | 2302 if (!m_synchronous) { |
2303 auto mainPaintEnd = std::chrono::steady_clock::now(); | |
2304 auto diff = mainPaintEnd - mainPaintStart; | |
2305 m_lastPaintTime = std::chrono::duration<double>(diff).count(); | |
2328 m_lastPaintBlockWidth = paintBlockWidth; | 2306 m_lastPaintBlockWidth = paintBlockWidth; |
2329 (void)gettimeofday(&tv, 0); | |
2330 m_lastPaintTime = RealTime::fromTimeval(tv) - mainPaintStart; | |
2331 } | 2307 } |
2332 } | 2308 } |
2333 | 2309 |
2334 void | 2310 void |
2335 SpectrogramLayer::paintDrawBufferPeakFrequencies(LayerGeometryProvider *v, | 2311 SpectrogramLayer::paintDrawBufferPeakFrequencies(LayerGeometryProvider *v, |
2462 | 2438 |
2463 int minbin = int(binfory[0] + 0.0001); | 2439 int minbin = int(binfory[0] + 0.0001); |
2464 int maxbin = int(binfory[h-1]); | 2440 int maxbin = int(binfory[h-1]); |
2465 | 2441 |
2466 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2442 #ifdef DEBUG_SPECTROGRAM_REPAINT |
2467 cerr << "minbin " << minbin << ", maxbin " << maxbin << "; w " << w << ", h " << h << endl; | 2443 cerr << "paintDrawBuffer: minbin " << minbin << ", maxbin " << maxbin << "; w " << w << ", h " << h << endl; |
2468 #endif | 2444 #endif |
2469 if (minbin < 0) minbin = 0; | 2445 if (minbin < 0) minbin = 0; |
2470 if (maxbin < 0) maxbin = minbin+1; | 2446 if (maxbin < 0) maxbin = minbin+1; |
2471 | 2447 |
2472 DenseThreeDimensionalModel *sourceModel = 0; | 2448 DenseThreeDimensionalModel *sourceModel = 0; |