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 |
