Mercurial > hg > svgui
comparison layer/SpectrogramLayer.cpp @ 1024:3bce4c45b681 spectrogram-minor-refactor
Rearrange cache update calculations so as to use the actual painted width returned by paint functions (though they only ever return the same width as requested, at this point)
author | Chris Cannam |
---|---|
date | Mon, 25 Jan 2016 15:52:26 +0000 |
parents | 74755fa6ea9e |
children | c02de0e34233 |
comparison
equal
deleted
inserted
replaced
1023:74755fa6ea9e | 1024:3bce4c45b681 |
---|---|
1952 } | 1952 } |
1953 } else { | 1953 } else { |
1954 x1 = x0; // it's all valid, paint nothing | 1954 x1 = x0; // it's all valid, paint nothing |
1955 } | 1955 } |
1956 } | 1956 } |
1957 | |
1958 cache.validArea = QRect | |
1959 (std::min(vx0, x0), cache.validArea.y(), | |
1960 std::max(vx1 - std::min(vx0, x0), | |
1961 x1 - std::min(vx0, x0)), | |
1962 cache.validArea.height()); | |
1963 | |
1964 #ifdef DEBUG_SPECTROGRAM_REPAINT | |
1965 cerr << "Valid area becomes " << cache.validArea.x() | |
1966 << ", " << cache.validArea.y() << ", " | |
1967 << cache.validArea.width() << "x" | |
1968 << cache.validArea.height() << endl; | |
1969 #endif | |
1970 | 1957 |
1971 } else { | 1958 } else { |
1972 if (x1 > x0 + paintBlockWidth) { | 1959 if (x1 > x0 + paintBlockWidth) { |
1973 int sfx = x1; | 1960 int sfx = x1; |
1974 if (startFrame < 0) sfx = v->getXForFrame(0); | 1961 if (startFrame < 0) sfx = v->getXForFrame(0); |
1979 int mid = (x1 + x0) / 2; | 1966 int mid = (x1 + x0) / 2; |
1980 x0 = mid - paintBlockWidth/2; | 1967 x0 = mid - paintBlockWidth/2; |
1981 x1 = x0 + paintBlockWidth; | 1968 x1 = x0 + paintBlockWidth; |
1982 } | 1969 } |
1983 } | 1970 } |
1984 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1971 } |
1985 cerr << "Valid area becomes " << x0 << ", 0, " << (x1-x0) | 1972 |
1986 << "x" << h << endl; | 1973 int repaintWidth = x1 - x0; |
1987 #endif | |
1988 cache.validArea = QRect(x0, 0, x1 - x0, h); | |
1989 } | |
1990 | |
1991 /* | |
1992 if (xPixelRatio != 1.f) { | |
1993 x0 = int((int(x0 / xPixelRatio) - 4) * xPixelRatio + 0.0001); | |
1994 x1 = int((int(x1 / xPixelRatio) + 4) * xPixelRatio + 0.0001); | |
1995 } | |
1996 */ | |
1997 int w = x1 - x0; | |
1998 | 1974 |
1999 #ifdef DEBUG_SPECTROGRAM_REPAINT | 1975 #ifdef DEBUG_SPECTROGRAM_REPAINT |
2000 cerr << "x0 " << x0 << ", x1 " << x1 << ", w " << w << ", h " << h << endl; | 1976 cerr << "x0 " << x0 << ", x1 " << x1 << ", w " << w << ", h " << h << endl; |
2001 #endif | 1977 #endif |
2002 | 1978 |
2062 | 2038 |
2063 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2039 #ifdef DEBUG_SPECTROGRAM_REPAINT |
2064 cerr << ((double(v->getFrameForX(1) - v->getFrameForX(0))) / increment) << " bin(s) per pixel" << endl; | 2040 cerr << ((double(v->getFrameForX(1) - v->getFrameForX(0))) / increment) << " bin(s) per pixel" << endl; |
2065 #endif | 2041 #endif |
2066 | 2042 |
2067 if (w == 0) { | 2043 if (repaintWidth == 0) { |
2068 SVDEBUG << "*** NOTE: w == 0" << endl; | 2044 SVDEBUG << "*** NOTE: repaintWidth == 0" << endl; |
2069 } | 2045 } |
2070 | 2046 |
2071 Profiler outerprof("SpectrogramLayer::paint: all cols"); | 2047 Profiler outerprof("SpectrogramLayer::paint: all cols"); |
2072 | 2048 |
2073 // The draw buffer contains a fragment at either our pixel | 2049 // The draw buffer contains a fragment at either our pixel |
2095 | 2071 |
2096 for (int x = x0; ; --x) { | 2072 for (int x = x0; ; --x) { |
2097 sv_frame_t f = v->getFrameForX(x); | 2073 sv_frame_t f = v->getFrameForX(x); |
2098 if ((f / increment) * increment == f) { | 2074 if ((f / increment) * increment == f) { |
2099 if (leftCropFrame == -1) leftCropFrame = f; | 2075 if (leftCropFrame == -1) leftCropFrame = f; |
2100 else if (x < x0 - 2) { leftBoundaryFrame = f; break; } | 2076 else if (x < x0 - 2) { |
2077 leftBoundaryFrame = f; | |
2078 break; | |
2079 } | |
2101 } | 2080 } |
2102 } | 2081 } |
2103 for (int x = x0 + w; ; ++x) { | 2082 for (int x = x0 + repaintWidth; ; ++x) { |
2104 sv_frame_t f = v->getFrameForX(x); | 2083 sv_frame_t f = v->getFrameForX(x); |
2105 if ((f / increment) * increment == f) { | 2084 if ((f / increment) * increment == f) { |
2106 if (rightCropFrame == -1) rightCropFrame = f; | 2085 if (rightCropFrame == -1) rightCropFrame = f; |
2107 else if (x > x0 + w + 2) { rightBoundaryFrame = f; break; } | 2086 else if (x > x0 + repaintWidth + 2) { |
2087 rightBoundaryFrame = f; | |
2088 break; | |
2089 } | |
2108 } | 2090 } |
2109 } | 2091 } |
2110 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2092 #ifdef DEBUG_SPECTROGRAM_REPAINT |
2111 cerr << "Left: crop: " << leftCropFrame << " (bin " << leftCropFrame/increment << "); boundary: " << leftBoundaryFrame << " (bin " << leftBoundaryFrame/increment << ")" << endl; | 2093 cerr << "Left: crop: " << leftCropFrame << " (bin " << leftCropFrame/increment << "); boundary: " << leftBoundaryFrame << " (bin " << leftBoundaryFrame/increment << ")" << endl; |
2112 cerr << "Right: crop: " << rightCropFrame << " (bin " << rightCropFrame/increment << "); boundary: " << rightBoundaryFrame << " (bin " << rightBoundaryFrame/increment << ")" << endl; | 2094 cerr << "Right: crop: " << rightCropFrame << " (bin " << rightCropFrame/increment << "); boundary: " << rightBoundaryFrame << " (bin " << rightBoundaryFrame/increment << ")" << endl; |
2114 | 2096 |
2115 bufwid = int((rightBoundaryFrame - leftBoundaryFrame) / increment); | 2097 bufwid = int((rightBoundaryFrame - leftBoundaryFrame) / increment); |
2116 | 2098 |
2117 } else { | 2099 } else { |
2118 | 2100 |
2119 bufwid = w; | 2101 bufwid = repaintWidth; |
2120 } | 2102 } |
2121 | 2103 |
2122 vector<int> binforx(bufwid); | 2104 vector<int> binforx(bufwid); |
2123 vector<double> binfory(h); | 2105 vector<double> binfory(h); |
2124 | 2106 |
2151 m_drawBuffer.setColor((unsigned char)pixel, | 2133 m_drawBuffer.setColor((unsigned char)pixel, |
2152 m_palette.getColour((unsigned char)pixel).rgb()); | 2134 m_palette.getColour((unsigned char)pixel).rgb()); |
2153 } | 2135 } |
2154 | 2136 |
2155 m_drawBuffer.fill(0); | 2137 m_drawBuffer.fill(0); |
2138 int attainedBufwid = bufwid; | |
2156 | 2139 |
2157 if (m_binDisplay != PeakFrequencies) { | 2140 if (m_binDisplay != PeakFrequencies) { |
2158 | 2141 |
2159 for (int y = 0; y < h; ++y) { | 2142 for (int y = 0; y < h; ++y) { |
2160 double q0 = 0, q1 = 0; | 2143 double q0 = 0, q1 = 0; |
2163 } else { | 2146 } else { |
2164 binfory[y] = q0; | 2147 binfory[y] = q0; |
2165 } | 2148 } |
2166 } | 2149 } |
2167 | 2150 |
2168 paintDrawBuffer(v, bufwid, h, binforx, binfory, usePeaksCache, | 2151 attainedBufwid = |
2169 overallMag, overallMagChanged); | 2152 paintDrawBuffer(v, bufwid, h, binforx, binfory, usePeaksCache, |
2153 overallMag, overallMagChanged); | |
2170 | 2154 |
2171 } else { | 2155 } else { |
2172 | 2156 |
2173 paintDrawBufferPeakFrequencies(v, bufwid, h, binforx, | 2157 attainedBufwid = |
2174 minbin, maxbin, | 2158 paintDrawBufferPeakFrequencies(v, bufwid, h, binforx, |
2175 displayMinFreq, displayMaxFreq, | 2159 minbin, maxbin, |
2176 logarithmic, | 2160 displayMinFreq, displayMaxFreq, |
2177 overallMag, overallMagChanged); | 2161 logarithmic, |
2178 } | 2162 overallMag, overallMagChanged); |
2179 | 2163 } |
2164 | |
2165 int failedToRepaint = bufwid - attainedBufwid; | |
2166 if (failedToRepaint < 0) { | |
2167 cerr << "WARNING: failedToRepaint < 0 (= " << failedToRepaint << ")" | |
2168 << endl; | |
2169 failedToRepaint = 0; | |
2170 } | |
2171 | |
2180 if (overallMagChanged) { | 2172 if (overallMagChanged) { |
2181 m_viewMags[v] = overallMag; | 2173 m_viewMags[v] = overallMag; |
2182 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2174 #ifdef DEBUG_SPECTROGRAM_REPAINT |
2183 cerr << "Overall mag is now [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "] - will be updating" << endl; | 2175 cerr << "Overall mag is now [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "] - will be updating" << endl; |
2184 #endif | 2176 #endif |
2194 << ", height = " << h << endl; | 2186 << ", height = " << h << endl; |
2195 #endif | 2187 #endif |
2196 cache.image = QImage(v->getPaintWidth(), h, QImage::Format_ARGB32_Premultiplied); | 2188 cache.image = QImage(v->getPaintWidth(), h, QImage::Format_ARGB32_Premultiplied); |
2197 } | 2189 } |
2198 | 2190 |
2199 if (w > 0) { | 2191 if (repaintWidth > 0) { |
2200 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2192 |
2201 cerr << "Painting " << w << "x" << h | 2193 #ifdef DEBUG_SPECTROGRAM_REPAINT |
2194 cerr << "Painting " << repaintWidth << "x" << h | |
2202 << " from draw buffer at " << 0 << "," << 0 | 2195 << " from draw buffer at " << 0 << "," << 0 |
2203 << " to " << w << "x" << h << " on cache at " | 2196 << " to " << repaintWidth << "x" << h << " on cache at " |
2204 << x0 << "," << 0 << endl; | 2197 << x0 << "," << 0 << endl; |
2205 #endif | 2198 #endif |
2206 | 2199 |
2207 QPainter cachePainter(&cache.image); | 2200 QPainter cachePainter(&cache.image); |
2208 | 2201 |
2232 (QRect(scaledLeftCrop, 0, | 2225 (QRect(scaledLeftCrop, 0, |
2233 scaledRightCrop - scaledLeftCrop, h), | 2226 scaledRightCrop - scaledLeftCrop, h), |
2234 scaled, | 2227 scaled, |
2235 QRect(scaledLeftCrop - scaledLeft, 0, | 2228 QRect(scaledLeftCrop - scaledLeft, 0, |
2236 scaledRightCrop - scaledLeftCrop, h)); | 2229 scaledRightCrop - scaledLeftCrop, h)); |
2230 | |
2237 } else { | 2231 } else { |
2238 cachePainter.drawImage(QRect(x0, 0, w, h), | 2232 |
2233 cachePainter.drawImage(QRect(x0, 0, repaintWidth, h), | |
2239 m_drawBuffer, | 2234 m_drawBuffer, |
2240 QRect(0, 0, w, h)); | 2235 QRect(0, 0, repaintWidth, h)); |
2241 } | 2236 } |
2242 | 2237 |
2243 cachePainter.end(); | 2238 cachePainter.end(); |
2239 } | |
2240 | |
2241 // update cache valid area based on painted area | |
2242 if (cache.validArea.width() > 0) { | |
2243 | |
2244 int left = std::min(cache.validArea.x(), x0); | |
2245 | |
2246 int wid = std::max(cache.validArea.x() + cache.validArea.width() - left, | |
2247 x1 - left); | |
2248 | |
2249 wid = wid - failedToRepaint; | |
2250 if (wid < 0) wid = 0; | |
2251 | |
2252 cache.validArea = QRect | |
2253 (left, cache.validArea.y(), wid, cache.validArea.height()); | |
2254 | |
2255 #ifdef DEBUG_SPECTROGRAM_REPAINT | |
2256 cerr << "Valid area becomes " << cache.validArea.x() | |
2257 << ", " << cache.validArea.y() << ", " | |
2258 << cache.validArea.width() << "x" | |
2259 << cache.validArea.height() << endl; | |
2260 #endif | |
2261 | |
2262 } else { | |
2263 | |
2264 cache.validArea = QRect(x0, 0, x1 - x0, h); | |
2265 | |
2266 #ifdef DEBUG_SPECTROGRAM_REPAINT | |
2267 cerr << "Valid area becomes " << x0 << ", 0, " << (x1-x0) | |
2268 << "x" << h << endl; | |
2269 #endif | |
2244 } | 2270 } |
2245 | 2271 |
2246 QRect pr = rect & cache.validArea; | 2272 QRect pr = rect & cache.validArea; |
2247 | 2273 |
2248 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2274 #ifdef DEBUG_SPECTROGRAM_REPAINT |
2277 << ", " | 2303 << ", " |
2278 << cache.image.width() - (cache.validArea.x() + | 2304 << cache.image.width() - (cache.validArea.x() + |
2279 cache.validArea.width()) | 2305 cache.validArea.width()) |
2280 << ")" << endl; | 2306 << ")" << endl; |
2281 #endif | 2307 #endif |
2282 v->getView()->update(cache.validArea.x() + cache.validArea.width(), | 2308 v->getView()->update |
2283 0, | 2309 (cache.validArea.x() + cache.validArea.width(), |
2284 cache.image.width() - (cache.validArea.x() + | 2310 0, |
2285 cache.validArea.width()), | 2311 cache.image.width() - (cache.validArea.x() + |
2286 h); | 2312 cache.validArea.width()), |
2313 h); | |
2287 } | 2314 } |
2288 } else { | 2315 } else { |
2289 // overallMagChanged | 2316 // overallMagChanged |
2290 cerr << "\noverallMagChanged - updating all\n" << endl; | 2317 cerr << "\noverallMagChanged - updating all\n" << endl; |
2291 cache.validArea = QRect(); | 2318 cache.validArea = QRect(); |
2305 m_lastPaintTime = std::chrono::duration<double>(diff).count(); | 2332 m_lastPaintTime = std::chrono::duration<double>(diff).count(); |
2306 m_lastPaintBlockWidth = paintBlockWidth; | 2333 m_lastPaintBlockWidth = paintBlockWidth; |
2307 } | 2334 } |
2308 } | 2335 } |
2309 | 2336 |
2310 void | 2337 int |
2311 SpectrogramLayer::paintDrawBufferPeakFrequencies(LayerGeometryProvider *v, | 2338 SpectrogramLayer::paintDrawBufferPeakFrequencies(LayerGeometryProvider *v, |
2312 int w, | 2339 int w, |
2313 int h, | 2340 int h, |
2314 const vector<int> &binforx, | 2341 const vector<int> &binforx, |
2315 int minbin, | 2342 int minbin, |
2327 #endif | 2354 #endif |
2328 if (minbin < 0) minbin = 0; | 2355 if (minbin < 0) minbin = 0; |
2329 if (maxbin < 0) maxbin = minbin+1; | 2356 if (maxbin < 0) maxbin = minbin+1; |
2330 | 2357 |
2331 FFTModel *fft = getFFTModel(v); | 2358 FFTModel *fft = getFFTModel(v); |
2332 if (!fft) return; | 2359 if (!fft) return 0; |
2333 | 2360 |
2334 FFTModel::PeakSet peakfreqs; | 2361 FFTModel::PeakSet peakfreqs; |
2335 | 2362 |
2336 int psx = -1; | 2363 int psx = -1; |
2337 | 2364 |
2420 if (overallMag.sample(mag)) overallMagChanged = true; | 2447 if (overallMag.sample(mag)) overallMagChanged = true; |
2421 } | 2448 } |
2422 } | 2449 } |
2423 } | 2450 } |
2424 } | 2451 } |
2425 } | 2452 |
2426 | 2453 return w; |
2427 void | 2454 } |
2455 | |
2456 int | |
2428 SpectrogramLayer::paintDrawBuffer(LayerGeometryProvider *v, | 2457 SpectrogramLayer::paintDrawBuffer(LayerGeometryProvider *v, |
2429 int w, | 2458 int w, |
2430 int h, | 2459 int h, |
2431 const vector<int> &binforx, | 2460 const vector<int> &binforx, |
2432 const vector<double> &binfory, | 2461 const vector<double> &binfory, |
2458 maxbin = sourceModel->getHeight(); | 2487 maxbin = sourceModel->getHeight(); |
2459 } else { | 2488 } else { |
2460 sourceModel = fft = getFFTModel(v); | 2489 sourceModel = fft = getFFTModel(v); |
2461 } | 2490 } |
2462 | 2491 |
2463 if (!sourceModel) return; | 2492 if (!sourceModel) return 0; |
2464 | 2493 |
2465 bool interpolate = false; | 2494 bool interpolate = false; |
2466 Preferences::SpectrogramSmoothing smoothing = | 2495 Preferences::SpectrogramSmoothing smoothing = |
2467 Preferences::getInstance()->getSpectrogramSmoothing(); | 2496 Preferences::getInstance()->getSpectrogramSmoothing(); |
2468 if (smoothing == Preferences::SpectrogramInterpolated || | 2497 if (smoothing == Preferences::SpectrogramInterpolated || |
2654 unsigned char peakpix = getDisplayValue(v, peak); | 2683 unsigned char peakpix = getDisplayValue(v, peak); |
2655 | 2684 |
2656 m_drawBuffer.setPixel(x, h-y-1, peakpix); | 2685 m_drawBuffer.setPixel(x, h-y-1, peakpix); |
2657 } | 2686 } |
2658 } | 2687 } |
2688 | |
2689 return w; | |
2659 } | 2690 } |
2660 | 2691 |
2661 void | 2692 void |
2662 SpectrogramLayer::illuminateLocalFeatures(LayerGeometryProvider *v, QPainter &paint) const | 2693 SpectrogramLayer::illuminateLocalFeatures(LayerGeometryProvider *v, QPainter &paint) const |
2663 { | 2694 { |