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 {