Mercurial > hg > svgui
comparison layer/SpectrogramLayer.cpp @ 1039:bfce7940c017 spectrogram-minor-refactor
Don't use partial paints when zoomed in far enough to have boundary alignment concerns. (But boundary calculations are still wrong, leading to a logic error exception.)
author | Chris Cannam |
---|---|
date | Tue, 02 Feb 2016 16:00:31 +0000 |
parents | 6d4fa45a271d |
children | 25b035362c44 |
comparison
equal
deleted
inserted
replaced
1038:6d4fa45a271d | 1039:bfce7940c017 |
---|---|
1853 // If (getFrameForX(x) / increment) * increment == | 1853 // If (getFrameForX(x) / increment) * increment == |
1854 // getFrameForX(x), then x is a time-bin boundary. We want two | 1854 // getFrameForX(x), then x is a time-bin boundary. We want two |
1855 // such boundaries at either side of the draw buffer -- one which | 1855 // such boundaries at either side of the draw buffer -- one which |
1856 // we draw up to, and one which we subsequently crop at. | 1856 // we draw up to, and one which we subsequently crop at. |
1857 | 1857 |
1858 bool bufferBinResolution = false; | 1858 bool bufferIsBinResolution = false; |
1859 if (increment > zoomLevel) bufferBinResolution = true; | 1859 if (increment > zoomLevel) bufferIsBinResolution = true; |
1860 | 1860 |
1861 sv_frame_t leftBoundaryFrame = -1, leftCropFrame = -1; | 1861 sv_frame_t leftBoundaryFrame = -1, leftCropFrame = -1; |
1862 sv_frame_t rightBoundaryFrame = -1, rightCropFrame = -1; | 1862 sv_frame_t rightBoundaryFrame = -1, rightCropFrame = -1; |
1863 | 1863 |
1864 int bufwid; | 1864 int bufwid; |
1865 | 1865 |
1866 if (bufferBinResolution) { | 1866 if (bufferIsBinResolution) { |
1867 | 1867 |
1868 for (int x = x0; ; --x) { | 1868 for (int x = x0; ; --x) { |
1869 sv_frame_t f = v->getFrameForX(x); | 1869 sv_frame_t f = v->getFrameForX(x); |
1870 if ((f / increment) * increment == f) { | 1870 if ((f / increment) * increment == f) { |
1871 if (leftCropFrame == -1) leftCropFrame = f; | 1871 if (leftCropFrame == -1) leftCropFrame = f; |
1900 vector<int> binforx(bufwid); | 1900 vector<int> binforx(bufwid); |
1901 vector<double> binfory(h); | 1901 vector<double> binfory(h); |
1902 | 1902 |
1903 bool usePeaksCache = false; | 1903 bool usePeaksCache = false; |
1904 | 1904 |
1905 if (bufferBinResolution) { | 1905 if (bufferIsBinResolution) { |
1906 for (int x = 0; x < bufwid; ++x) { | 1906 for (int x = 0; x < bufwid; ++x) { |
1907 binforx[x] = int(leftBoundaryFrame / increment) + x; | 1907 binforx[x] = int(leftBoundaryFrame / increment) + x; |
1908 } | 1908 } |
1909 m_drawBuffer = QImage(bufwid, h, QImage::Format_Indexed8); | 1909 m_drawBuffer = QImage(bufwid, h, QImage::Format_Indexed8); |
1910 } else { | 1910 } else { |
1928 m_palette.getColour((unsigned char)pixel).rgb()); | 1928 m_palette.getColour((unsigned char)pixel).rgb()); |
1929 } | 1929 } |
1930 | 1930 |
1931 m_drawBuffer.fill(0); | 1931 m_drawBuffer.fill(0); |
1932 int attainedBufwid = bufwid; | 1932 int attainedBufwid = bufwid; |
1933 | 1933 |
1934 double softTimeLimit; | |
1935 | |
1936 if (m_synchronous) { | |
1937 | |
1938 // must paint the whole thing for synchronous mode, so give | |
1939 // "no timeout" | |
1940 softTimeLimit = 0.0; | |
1941 | |
1942 } else if (bufferIsBinResolution) { | |
1943 | |
1944 // calculating boundaries later will be too fiddly for partial | |
1945 // paints, and painting should be fast anyway when this is the | |
1946 // case because it means we're well zoomed in | |
1947 softTimeLimit = 0.0; | |
1948 | |
1949 } else { | |
1950 | |
1951 // neither limitation applies, so use a short soft limit | |
1952 | |
1953 if (m_binDisplay == PeakFrequencies) { | |
1954 softTimeLimit = 0.15; | |
1955 } else { | |
1956 softTimeLimit = 0.1; | |
1957 } | |
1958 } | |
1959 | |
1934 if (m_binDisplay != PeakFrequencies) { | 1960 if (m_binDisplay != PeakFrequencies) { |
1935 | 1961 |
1936 for (int y = 0; y < h; ++y) { | 1962 for (int y = 0; y < h; ++y) { |
1937 double q0 = 0, q1 = 0; | 1963 double q0 = 0, q1 = 0; |
1938 if (!getSmoothedYBinRange(v, h-y-1, q0, q1)) { | 1964 if (!getSmoothedYBinRange(v, h-y-1, q0, q1)) { |
1944 | 1970 |
1945 attainedBufwid = | 1971 attainedBufwid = |
1946 paintDrawBuffer(v, bufwid, h, binforx, binfory, | 1972 paintDrawBuffer(v, bufwid, h, binforx, binfory, |
1947 usePeaksCache, | 1973 usePeaksCache, |
1948 overallMag, overallMagChanged, | 1974 overallMag, overallMagChanged, |
1949 rightToLeft); | 1975 rightToLeft, |
1976 softTimeLimit); | |
1950 | 1977 |
1951 } else { | 1978 } else { |
1952 | 1979 |
1953 attainedBufwid = | 1980 attainedBufwid = |
1954 paintDrawBufferPeakFrequencies(v, bufwid, h, binforx, | 1981 paintDrawBufferPeakFrequencies(v, bufwid, h, binforx, |
1955 minbin, maxbin, | 1982 minbin, maxbin, |
1956 displayMinFreq, displayMaxFreq, | 1983 displayMinFreq, displayMaxFreq, |
1957 logarithmic, | 1984 logarithmic, |
1958 overallMag, overallMagChanged, | 1985 overallMag, overallMagChanged, |
1959 rightToLeft); | 1986 rightToLeft, |
1987 softTimeLimit); | |
1960 } | 1988 } |
1961 | 1989 |
1962 int failedToRepaint = bufwid - attainedBufwid; | 1990 int failedToRepaint = bufwid - attainedBufwid; |
1963 | 1991 |
1964 int paintedLeft = x0; | 1992 int paintedLeft = x0; |
2005 << " from draw buffer at " << paintedLeft - x0 << "," << 0 | 2033 << " from draw buffer at " << paintedLeft - x0 << "," << 0 |
2006 << " to " << paintedWidth << "x" << h << " on cache at " | 2034 << " to " << paintedWidth << "x" << h << " on cache at " |
2007 << x0 << "," << 0 << endl; | 2035 << x0 << "," << 0 << endl; |
2008 #endif | 2036 #endif |
2009 | 2037 |
2010 if (bufferBinResolution) { | 2038 if (bufferIsBinResolution) { |
2011 | 2039 |
2012 int scaledLeft = v->getXForFrame(leftBoundaryFrame); | 2040 int scaledLeft = v->getXForFrame(leftBoundaryFrame); |
2013 int scaledRight = v->getXForFrame(rightBoundaryFrame); | 2041 int scaledRight = v->getXForFrame(rightBoundaryFrame); |
2014 | 2042 |
2015 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2043 #ifdef DEBUG_SPECTROGRAM_REPAINT |
2136 double displayMinFreq, | 2164 double displayMinFreq, |
2137 double displayMaxFreq, | 2165 double displayMaxFreq, |
2138 bool logarithmic, | 2166 bool logarithmic, |
2139 MagnitudeRange &overallMag, | 2167 MagnitudeRange &overallMag, |
2140 bool &overallMagChanged, | 2168 bool &overallMagChanged, |
2141 bool rightToLeft) const | 2169 bool rightToLeft, |
2170 double softTimeLimit) const | |
2142 { | 2171 { |
2143 Profiler profiler("SpectrogramLayer::paintDrawBufferPeakFrequencies"); | 2172 Profiler profiler("SpectrogramLayer::paintDrawBufferPeakFrequencies"); |
2144 | 2173 |
2145 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2174 #ifdef DEBUG_SPECTROGRAM_REPAINT |
2146 cerr << "SpectrogramLayer::paintDrawBufferPeakFrequencies: minbin " << minbin << ", maxbin " << maxbin << "; w " << w << ", h " << h << endl; | 2175 cerr << "SpectrogramLayer::paintDrawBufferPeakFrequencies: minbin " << minbin << ", maxbin " << maxbin << "; w " << w << ", h " << h << endl; |
2160 #else | 2189 #else |
2161 float *values = (float *)alloca((maxbin - minbin + 1) * sizeof(float)); | 2190 float *values = (float *)alloca((maxbin - minbin + 1) * sizeof(float)); |
2162 #endif | 2191 #endif |
2163 | 2192 |
2164 int minColumns = 4; | 2193 int minColumns = 4; |
2165 double softTimeLimit = 0.15; // seconds; only for non-synchronous drawing | 2194 bool haveTimeLimits = (softTimeLimit > 0.0); |
2166 double hardTimeLimit = softTimeLimit * 2.0; | 2195 double hardTimeLimit = softTimeLimit * 2.0; |
2167 bool overridingSoftLimit = false; | 2196 bool overridingSoftLimit = false; |
2168 auto startTime = chrono::steady_clock::now(); | 2197 auto startTime = chrono::steady_clock::now(); |
2169 | 2198 |
2170 int start = 0; | 2199 int start = 0; |
2260 if (overallMag.sample(mag)) overallMagChanged = true; | 2289 if (overallMag.sample(mag)) overallMagChanged = true; |
2261 } | 2290 } |
2262 } | 2291 } |
2263 } | 2292 } |
2264 | 2293 |
2265 if (!m_synchronous) { | 2294 if (haveTimeLimits) { |
2266 if (columnCount >= minColumns) { | 2295 if (columnCount >= minColumns) { |
2267 auto t = chrono::steady_clock::now(); | 2296 auto t = chrono::steady_clock::now(); |
2268 double diff = chrono::duration<double>(t - startTime).count(); | 2297 double diff = chrono::duration<double>(t - startTime).count(); |
2269 if (diff > hardTimeLimit) { | 2298 if (diff > hardTimeLimit) { |
2270 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2299 #ifdef DEBUG_SPECTROGRAM_REPAINT |
2301 const vector<int> &binforx, | 2330 const vector<int> &binforx, |
2302 const vector<double> &binfory, | 2331 const vector<double> &binfory, |
2303 bool usePeaksCache, | 2332 bool usePeaksCache, |
2304 MagnitudeRange &overallMag, | 2333 MagnitudeRange &overallMag, |
2305 bool &overallMagChanged, | 2334 bool &overallMagChanged, |
2306 bool rightToLeft) const | 2335 bool rightToLeft, |
2336 double softTimeLimit) const | |
2307 { | 2337 { |
2308 Profiler profiler("SpectrogramLayer::paintDrawBuffer"); | 2338 Profiler profiler("SpectrogramLayer::paintDrawBuffer"); |
2309 | 2339 |
2310 int minbin = int(binfory[0] + 0.0001); | 2340 int minbin = int(binfory[0] + 0.0001); |
2311 int maxbin = int(binfory[h-1]); | 2341 int maxbin = int(binfory[h-1]); |
2356 | 2386 |
2357 const float *values = autoarray; | 2387 const float *values = autoarray; |
2358 DenseThreeDimensionalModel::Column c; | 2388 DenseThreeDimensionalModel::Column c; |
2359 | 2389 |
2360 int minColumns = 4; | 2390 int minColumns = 4; |
2361 double softTimeLimit = 0.1; // seconds; only for non-synchronous drawing | 2391 bool haveTimeLimits = (softTimeLimit > 0.0); |
2362 double hardTimeLimit = softTimeLimit * 2.0; | 2392 double hardTimeLimit = softTimeLimit * 2.0; |
2363 bool overridingSoftLimit = false; | 2393 bool overridingSoftLimit = false; |
2364 auto startTime = chrono::steady_clock::now(); | 2394 auto startTime = chrono::steady_clock::now(); |
2365 | 2395 |
2366 int start = 0; | 2396 int start = 0; |
2545 unsigned char peakpix = getDisplayValue(v, peak); | 2575 unsigned char peakpix = getDisplayValue(v, peak); |
2546 | 2576 |
2547 m_drawBuffer.setPixel(x, h-y-1, peakpix); | 2577 m_drawBuffer.setPixel(x, h-y-1, peakpix); |
2548 } | 2578 } |
2549 | 2579 |
2550 if (!m_synchronous) { | 2580 if (haveTimeLimits) { |
2551 if (columnCount >= minColumns) { | 2581 if (columnCount >= minColumns) { |
2552 auto t = chrono::steady_clock::now(); | 2582 auto t = chrono::steady_clock::now(); |
2553 double diff = chrono::duration<double>(t - startTime).count(); | 2583 double diff = chrono::duration<double>(t - startTime).count(); |
2554 if (diff > hardTimeLimit) { | 2584 if (diff > hardTimeLimit) { |
2555 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2585 #ifdef DEBUG_SPECTROGRAM_REPAINT |