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; |
