Mercurial > hg > svgui
comparison layer/SpectrogramLayer.cpp @ 480:567b94e627b8
* start introducing another rendering method
author | Chris Cannam |
---|---|
date | Tue, 03 Feb 2009 15:21:28 +0000 |
parents | 0033dbfb92e3 |
children | 74a7729e3653 |
comparison
equal
deleted
inserted
replaced
479:0033dbfb92e3 | 480:567b94e627b8 |
---|---|
37 #include <QMouseEvent> | 37 #include <QMouseEvent> |
38 #include <QTextStream> | 38 #include <QTextStream> |
39 | 39 |
40 #include <iostream> | 40 #include <iostream> |
41 | 41 |
42 using std::cerr; | |
43 using std::endl; | |
42 #include <cassert> | 44 #include <cassert> |
43 #include <cmath> | 45 #include <cmath> |
44 | 46 |
45 #define DEBUG_SPECTROGRAM_REPAINT 1 | 47 #define DEBUG_SPECTROGRAM_REPAINT 1 |
46 | 48 |
2071 << "x" << h << std::endl; | 2073 << "x" << h << std::endl; |
2072 #endif | 2074 #endif |
2073 cache.validArea = QRect(x0, 0, x1 - x0, h); | 2075 cache.validArea = QRect(x0, 0, x1 - x0, h); |
2074 } | 2076 } |
2075 | 2077 |
2078 if (xPixelRatio != 1.f) { | |
2079 x0 = int((int(x0 / xPixelRatio) - 4) * xPixelRatio + 0.0001); | |
2080 x1 = int((int(x1 / xPixelRatio) + 4) * xPixelRatio + 0.0001); | |
2081 } | |
2082 | |
2076 int w = x1 - x0; | 2083 int w = x1 - x0; |
2077 | 2084 |
2078 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2085 #ifdef DEBUG_SPECTROGRAM_REPAINT |
2079 std::cerr << "x0 " << x0 << ", x1 " << x1 << ", w " << w << ", h " << h << std::endl; | 2086 std::cerr << "x0 " << x0 << ", x1 " << x1 << ", w " << w << ", h " << h << std::endl; |
2080 #endif | 2087 #endif |
2167 size_t pixels = 0; | 2174 size_t pixels = 0; |
2168 #endif | 2175 #endif |
2169 | 2176 |
2170 Profiler outerprof("SpectrogramLayer::paint: all cols"); | 2177 Profiler outerprof("SpectrogramLayer::paint: all cols"); |
2171 | 2178 |
2179 int bufwid = w / xPixelRatio; | |
2180 int binforx[bufwid + 1]; | |
2181 int binfory[h + 1]; | |
2182 | |
2183 for (int x = 0; x <= bufwid; ++x) { | |
2184 int vx = int(x0 + x * xPixelRatio + 0.0001); | |
2185 float s0 = 0, s1 = 0; | |
2186 if (!getXBinRange(v, vx, s0, s1)) { | |
2187 binforx[x] = -1; | |
2188 } else { | |
2189 binforx[x] = int(s0 + 0.0001); | |
2190 } | |
2191 } | |
2192 | |
2193 for (int y = 0; y < h; ++y) { | |
2194 float q0 = 0, q1 = 0; | |
2195 if (!getYBinRange(v, h-y, q0, q1)) { | |
2196 binfory[y] = -1; | |
2197 } else { | |
2198 binfory[y] = int(q0 + 0.0001); | |
2199 } | |
2200 } | |
2201 binfory[h] = binfory[h-1]; | |
2202 | |
2203 paintColumnValues2(v, fft, bufwid, h, binforx, binfory); | |
2204 | |
2205 /* | |
2172 for (int x = 0; x < w / xPixelRatio; ++x) { | 2206 for (int x = 0; x < w / xPixelRatio; ++x) { |
2173 | 2207 |
2174 Profiler innerprof("SpectrogramLayer::paint: 1 pixel column"); | 2208 Profiler innerprof("SpectrogramLayer::paint: 1 pixel column"); |
2175 | 2209 |
2176 runOutOfData = !paintColumnValues(v, fft, x0, x, | 2210 runOutOfData = !paintColumnValues(v, fft, x0, x, |
2184 std::cerr << "Run out of data -- dropping out of loop" << std::endl; | 2218 std::cerr << "Run out of data -- dropping out of loop" << std::endl; |
2185 #endif | 2219 #endif |
2186 break; | 2220 break; |
2187 } | 2221 } |
2188 } | 2222 } |
2189 | 2223 */ |
2190 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2224 #ifdef DEBUG_SPECTROGRAM_REPAINT |
2191 std::cerr << pixels << " pixels drawn" << std::endl; | 2225 // std::cerr << pixels << " pixels drawn" << std::endl; |
2192 #endif | 2226 #endif |
2193 | 2227 |
2194 if (overallMagChanged) { | 2228 if (overallMagChanged) { |
2195 m_viewMags[v] = overallMag; | 2229 m_viewMags[v] = overallMag; |
2196 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2230 #ifdef DEBUG_SPECTROGRAM_REPAINT |
2214 cache.image = QImage(v->width(), h, QImage::Format_RGB32); | 2248 cache.image = QImage(v->width(), h, QImage::Format_RGB32); |
2215 } | 2249 } |
2216 | 2250 |
2217 if (w > 0) { | 2251 if (w > 0) { |
2218 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2252 #ifdef DEBUG_SPECTROGRAM_REPAINT |
2219 std::cerr << "Painting " << w << "x" << h | 2253 std::cerr << "Painting " << w/xPixelRatio << "x" << h |
2220 << " from draw buffer at " << 0 << "," << 0 | 2254 << " from draw buffer at " << 0 << "," << 0 |
2221 << " to cache at " << x0 << "," << 0 << std::endl; | 2255 << " to " << w << "x" << h << " on cache at " |
2256 << x0 << "," << 0 << std::endl; | |
2222 #endif | 2257 #endif |
2223 | 2258 |
2224 QPainter cachePainter(&cache.image); | 2259 QPainter cachePainter(&cache.image); |
2225 cachePainter.setRenderHint(QPainter::SmoothPixmapTransform, true); | 2260 cachePainter.setRenderHint(QPainter::SmoothPixmapTransform, true); |
2226 cachePainter.drawImage(QRect(x0, 0, w, h), | 2261 cachePainter.drawImage(QRect(x0, 0, w, h), |
2295 } | 2330 } |
2296 | 2331 |
2297 //!!! if (fftSuspended) fft->resume(); | 2332 //!!! if (fftSuspended) fft->resume(); |
2298 } | 2333 } |
2299 | 2334 |
2335 bool | |
2336 SpectrogramLayer::paintColumnValues2(View *v, | |
2337 FFTModel *fft, | |
2338 int w, | |
2339 int h, | |
2340 int *binforx, // w+1 values | |
2341 int *binfory // h+1 values | |
2342 ) const | |
2343 { | |
2344 // paint onto m_drawBuffer | |
2345 | |
2346 int minbin = binfory[0]; | |
2347 int maxbin = binfory[h-1]; | |
2348 | |
2349 cerr << "minbin " << minbin << ", maxbin " << maxbin << endl; | |
2350 if (minbin < 0) minbin = 0; | |
2351 if (maxbin < 0) maxbin = minbin+1; | |
2352 | |
2353 int psx = -1; | |
2354 float values[maxbin - minbin + 1]; | |
2355 | |
2356 for (int x = 0; x < w; ++x) { | |
2357 | |
2358 for (int y = 0; y < h; ++y) { | |
2359 | |
2360 unsigned char peakpix = 0; | |
2361 | |
2362 int sx0 = binforx[x]; | |
2363 int sx1 = binforx[x+1]; | |
2364 if (sx0 < 0) sx0 = sx1 - 1; | |
2365 if (sx0 < 0) continue; | |
2366 if (sx1 <= sx0) sx1 = sx0 + 1; | |
2367 | |
2368 for (int sx = sx0; sx < sx1; ++sx) { | |
2369 | |
2370 if (sx < 0 || sx >= int(fft->getWidth())) continue; | |
2371 | |
2372 if (!m_synchronous) { | |
2373 if (!fft->isColumnAvailable(sx)) { | |
2374 #ifdef DEBUG_SPECTROGRAM_REPAINT | |
2375 std::cerr << "Met unavailable column at col " << sx << std::endl; | |
2376 #endif | |
2377 return false; | |
2378 } | |
2379 } | |
2380 | |
2381 if (sx != psx) { | |
2382 fft->getMagnitudesAt(sx, values, minbin, maxbin - minbin + 1); | |
2383 psx = sx; | |
2384 } | |
2385 | |
2386 int sy0 = binfory[y]; | |
2387 int sy1 = binfory[y+1]; | |
2388 if (sy0 < 0) sy0 = sy1 - 1; | |
2389 if (sy0 < 0) continue; | |
2390 if (sy1 <= sy0) sy1 = sy0 + 1; | |
2391 | |
2392 // cerr << "sy0 " << sy0 << " sy1 " << sy1 << endl; | |
2393 | |
2394 //!!! review | |
2395 for (int sy = sy0; sy < sy1; ++sy) { | |
2396 | |
2397 float value = values[sy - minbin]; | |
2398 | |
2399 if (m_colourScale != PhaseColourScale) { | |
2400 if (!m_normalizeColumns) { | |
2401 value /= (m_fftSize/2.f); | |
2402 } | |
2403 //!!! mag.sample(value); | |
2404 value *= m_gain; | |
2405 } | |
2406 | |
2407 unsigned char pix = getDisplayValue(v, value); | |
2408 if (pix > peakpix) peakpix = pix; | |
2409 // cerr <<x<<","<<y<<" -> "<<sx<<","<<sy<<" -> "<<values[sy]<<" -> "<<(int)pix<< endl; | |
2410 } | |
2411 } | |
2412 | |
2413 m_drawBuffer.setPixel(x, h-y-1, peakpix); | |
2414 } | |
2415 } | |
2416 | |
2417 return true; | |
2418 } | |
2300 | 2419 |
2301 bool | 2420 bool |
2302 SpectrogramLayer::paintColumnValues(View *v, | 2421 SpectrogramLayer::paintColumnValues(View *v, |
2303 FFTModel *fft, | 2422 FFTModel *fft, |
2304 int x0, | 2423 int x0, |
2335 | 2454 |
2336 float s0 = 0, s1 = 0; | 2455 float s0 = 0, s1 = 0; |
2337 | 2456 |
2338 if (!getXBinRange(v, x0 + x * xPixelRatio, s0, s1)) { | 2457 if (!getXBinRange(v, x0 + x * xPixelRatio, s0, s1)) { |
2339 #ifdef DEBUG_SPECTROGRAM_REPAINT | 2458 #ifdef DEBUG_SPECTROGRAM_REPAINT |
2340 std::cerr << "Out of range at " << x0 + x << std::endl; | 2459 // std::cerr << "Out of range at " << x0 + x << std::endl; |
2341 #endif | 2460 #endif |
2342 assert(x <= m_drawBuffer.width()); | 2461 assert(x <= m_drawBuffer.width()); |
2343 return true; | 2462 return true; |
2344 } | 2463 } |
2345 | 2464 |