Mercurial > hg > svgui
changeset 816:7b6c5fce5f84 tonioni
Merge from default branch
author | Chris Cannam |
---|---|
date | Wed, 02 Jul 2014 17:31:37 +0100 |
parents | b68af2be4545 (current diff) 09026c875301 (diff) |
children | 24f18a7dd26d |
files | |
diffstat | 5 files changed, 167 insertions(+), 70 deletions(-) [+] |
line wrap: on
line diff
--- a/layer/Colour3DPlotLayer.cpp Wed Jun 18 13:42:25 2014 +0100 +++ b/layer/Colour3DPlotLayer.cpp Wed Jul 02 17:31:37 2014 +0100 @@ -509,7 +509,7 @@ if (dormant) { #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT - SVDEBUG << "Colour3DPlotLayer::setLayerDormant(" << dormant << ")" + cerr << "Colour3DPlotLayer::setLayerDormant(" << dormant << ")" << endl; #endif @@ -530,7 +530,12 @@ bool Colour3DPlotLayer::isLayerScrollable(const View *v) const { - if (m_normalizeVisibleArea) return false; + if (m_normalizeVisibleArea) { + return false; + } + if (shouldPaintDenseIn(v)) { + return true; + } QPoint discard; return !v->shouldIlluminateLocalFeatures(this, discard); } @@ -686,8 +691,8 @@ float(v->getViewManager()->getMainModelSampleRate()) / float(m_model->getSampleRate()); - int sx0 = int((v->getFrameForX(x) / srRatio - long(modelStart)) / - long(modelResolution)); + int sx0 = int((v->getFrameForX(x) / srRatio - modelStart) / + modelResolution); int f0 = sx0 * modelResolution; int f1 = f0 + modelResolution; @@ -708,6 +713,10 @@ int sy = getBinForY(v, y); + if (sy < 0 || sy >= m_model->getHeight()) { + return ""; + } + if (m_invertVertical) sy = m_model->getHeight() - sy - 1; float value = m_model->getValueAt(sx0, sy); @@ -903,6 +912,8 @@ DenseThreeDimensionalModel::Column Colour3DPlotLayer::getColumn(int col) const { + Profiler profiler("Colour3DPlotLayer::getColumn"); + DenseThreeDimensionalModel::Column values = m_model->getColumn(col); while (values.size() < m_model->getHeight()) values.push_back(0.f); if (!m_normalizeColumns && !m_normalizeHybrid) return values; @@ -941,33 +952,39 @@ void Colour3DPlotLayer::fillCache(int firstBin, int lastBin) const { - Profiler profiler("Colour3DPlotLayer::fillCache"); + Profiler profiler("Colour3DPlotLayer::fillCache", true); int modelStart = m_model->getStartFrame(); int modelEnd = m_model->getEndFrame(); int modelResolution = m_model->getResolution(); -#ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT - SVDEBUG << "Colour3DPlotLayer::fillCache: " << firstBin << " -> " << lastBin << endl; -#endif - int modelStartBin = modelStart / modelResolution; int modelEndBin = modelEnd / modelResolution; +#ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT + cerr << "Colour3DPlotLayer::fillCache: range " << firstBin << " -> " << lastBin << " of model range " << modelStartBin << " -> " << modelEndBin << " (model resolution " << modelResolution << ")" << endl; +#endif + int cacheWidth = modelEndBin - modelStartBin + 1; if (lastBin > modelEndBin) cacheWidth = lastBin - modelStartBin + 1; int cacheHeight = m_model->getHeight(); - if (m_cache && (m_cache->height() != int(cacheHeight))) { + if (m_cache && m_cache->height() != cacheHeight) { // height has changed: delete everything rather than resizing +#ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT + cerr << "Colour3DPlotLayer::fillCache: Cache height has changed, recreating" << endl; +#endif delete m_cache; delete m_peaksCache; m_cache = 0; m_peaksCache = 0; } - if (m_cache && (m_cache->width() != int(cacheWidth))) { + if (m_cache && m_cache->width() != cacheWidth) { // width has changed and we have an existing cache: resize it +#ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT + cerr << "Colour3DPlotLayer::fillCache: Cache width has changed, resizing existing cache" << endl; +#endif QImage *newCache = new QImage(m_cache->copy(0, 0, cacheWidth, cacheHeight)); delete m_cache; @@ -982,15 +999,18 @@ } if (!m_cache) { +#ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT + cerr << "Colour3DPlotLayer::fillCache: Have no cache, making one" << endl; +#endif m_cache = new QImage (cacheWidth, cacheHeight, QImage::Format_Indexed8); -// No longer exists in Qt5: m_cache->setNumColors(256); + m_cache->setColorCount(256); m_cache->fill(0); if (!m_normalizeVisibleArea) { m_peaksCache = new QImage (cacheWidth / m_peakResolution + 1, cacheHeight, QImage::Format_Indexed8); -// No longer exists in Qt5: m_peaksCache->setNumColors(256); + m_peaksCache->setColorCount(256); m_peaksCache->fill(0); } else if (m_peaksCache) { delete m_peaksCache; @@ -1000,8 +1020,10 @@ m_cacheValidEnd = 0; } -// cerr << "cache size = " << m_cache->width() << "x" << m_cache->height() -// << " peaks cache size = " << m_peaksCache->width() << "x" << m_peaksCache->height() << endl; +#ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT + cerr << "cache size = " << m_cache->width() << "x" << m_cache->height() + << " peaks cache size = " << m_peaksCache->width() << "x" << m_peaksCache->height() << endl; +#endif if (m_cacheValidStart <= firstBin && m_cacheValidEnd >= lastBin) { #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT @@ -1034,14 +1056,15 @@ } else { - // the only valid area, ever, is the currently visible one + // when normalising the visible area, the only valid area, + // ever, is the currently visible one m_cacheValidStart = fillStart; m_cacheValidEnd = fillEnd; } #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT - cerr << "Cache size " << cacheWidth << "x" << cacheHeight << " will be valid from " << m_cacheValidStart << " to " << m_cacheValidEnd << endl; + cerr << "Cache size " << cacheWidth << "x" << cacheHeight << " will be valid from " << m_cacheValidStart << " to " << m_cacheValidEnd << " (fillStart = " << fillStart << ", fillEnd = " << fillEnd << ")" << endl; #endif DenseThreeDimensionalModel::Column values; @@ -1125,6 +1148,8 @@ } } + Profiler profiler2("Colour3DPlotLayer::fillCache: filling", true); + for (int c = fillStart; c <= fillEnd; ++c) { values = getColumn(c); @@ -1204,6 +1229,24 @@ delete[] peaks; } +bool +Colour3DPlotLayer::shouldPaintDenseIn(const View *v) const +{ + if (!m_model || !v || !(v->getViewManager())) { + return false; + } + float srRatio = + float(v->getViewManager()->getMainModelSampleRate()) / + float(m_model->getSampleRate()); + if (m_opaque || + m_smooth || + m_model->getHeight() >= v->height() || + ((m_model->getResolution() * srRatio) / v->getZoomLevel()) < 2) { + return true; + } + return false; +} + void Colour3DPlotLayer::paint(View *v, QPainter &paint, QRect rect) const { @@ -1214,7 +1257,7 @@ */ Profiler profiler("Colour3DPlotLayer::paint"); #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT - SVDEBUG << "Colour3DPlotLayer::paint(): m_model is " << m_model << ", zoom level is " << v->getZoomLevel() << endl; + cerr << "Colour3DPlotLayer::paint(): m_model is " << m_model << ", zoom level is " << v->getZoomLevel() << ", rect is (" << rect.x() << "," << rect.y() << ") " << rect.width() << "x" << rect.height() << endl; #endif int completion = 0; @@ -1250,10 +1293,10 @@ float(v->getViewManager()->getMainModelSampleRate()) / float(m_model->getSampleRate()); - int sx0 = int((v->getFrameForX(x0) / srRatio - long(modelStart)) - / long(modelResolution)); - int sx1 = int((v->getFrameForX(x1) / srRatio - long(modelStart)) - / long(modelResolution)); + int sx0 = int((v->getFrameForX(x0) / srRatio - modelStart) + / modelResolution); + int sx1 = int((v->getFrameForX(x1) / srRatio - modelStart) + / modelResolution); int sh = m_model->getHeight(); int symin = m_miny; @@ -1270,22 +1313,19 @@ sx1 < 0 ? 0 : sx1); #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT - SVDEBUG << "Colour3DPlotLayer::paint: height = "<< m_model->getHeight() << ", modelStart = " << modelStart << ", resolution = " << modelResolution << ", model rate = " << m_model->getSampleRate() << " (zoom level = " << v->getZoomLevel() << ", srRatio = " << srRatio << ")" << endl; + cerr << "Colour3DPlotLayer::paint: height = "<< m_model->getHeight() << ", modelStart = " << modelStart << ", resolution = " << modelResolution << ", model rate = " << m_model->getSampleRate() << " (zoom level = " << v->getZoomLevel() << ", srRatio = " << srRatio << ")" << endl; #endif - if (m_opaque || - m_smooth || - int(m_model->getHeight()) >= v->height() || - ((modelResolution * srRatio) / v->getZoomLevel()) < 2) { + if (shouldPaintDenseIn(v)) { #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT - SVDEBUG << "calling paintDense" << endl; + cerr << "calling paintDense" << endl; #endif paintDense(v, paint, rect); return; } #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT - SVDEBUG << "Colour3DPlotLayer::paint: w " << x1-x0 << ", h " << h << ", sx0 " << sx0 << ", sx1 " << sx1 << ", sw " << sx1-sx0 << ", sh " << sh << endl; + cerr << "Colour3DPlotLayer::paint: w " << x1-x0 << ", h " << h << ", sx0 " << sx0 << ", sx1 " << sx1 << ", sw " << sx1-sx0 << ", sh " << sh << endl; cerr << "Colour3DPlotLayer: sample rate is " << m_model->getSampleRate() << ", resolution " << m_model->getResolution() << endl; #endif @@ -1295,13 +1335,12 @@ for (int sx = sx0; sx <= sx1; ++sx) { - int fx = sx * int(modelResolution); + int fx = sx * modelResolution; - if (fx + int(modelResolution) <= int(modelStart) || - fx > int(modelEnd)) continue; + if (fx + modelResolution <= modelStart || fx > modelEnd) continue; - int rx0 = v->getXForFrame(int((fx + int(modelStart)) * srRatio)); - int rx1 = v->getXForFrame(int((fx + int(modelStart) + int(modelResolution) + 1) * srRatio)); + int rx0 = v->getXForFrame(int((fx + modelStart) * srRatio)); + int rx1 = v->getXForFrame(int((fx + modelStart + modelResolution + 1) * srRatio)); int rw = rx1 - rx0; if (rw < 1) rw = 1; @@ -1371,7 +1410,7 @@ void Colour3DPlotLayer::paintDense(View *v, QPainter &paint, QRect rect) const { - Profiler profiler("Colour3DPlotLayer::paintDense"); + Profiler profiler("Colour3DPlotLayer::paintDense", true); if (!m_cache) return; float modelStart = m_model->getStartFrame(); @@ -1406,30 +1445,37 @@ int zoomLevel = v->getZoomLevel(); QImage *source = m_cache; - - SVDEBUG << "modelResolution " << modelResolution << ", srRatio " - << srRatio << ", m_peakResolution " << m_peakResolution - << ", zoomLevel " << zoomLevel << ", result " - << ((modelResolution * srRatio * m_peakResolution) / zoomLevel) - << endl; + +#ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT + cerr << "modelResolution " << modelResolution << ", srRatio " + << srRatio << ", m_peakResolution " << m_peakResolution + << ", zoomLevel " << zoomLevel << ", result " + << ((modelResolution * srRatio * m_peakResolution) / zoomLevel) + << endl; +#endif if (m_peaksCache) { if (((modelResolution * srRatio * m_peakResolution) / zoomLevel) < 1) { - SVDEBUG << "using peaks cache" << endl; +#ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT + cerr << "using peaks cache" << endl; +#endif source = m_peaksCache; modelResolution *= m_peakResolution; } else { - SVDEBUG << "not using peaks cache" << endl; +#ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT + cerr << "not using peaks cache" << endl; +#endif } } else { - SVDEBUG << "have no peaks cache" << endl; +#ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT + cerr << "have no peaks cache" << endl; +#endif } - int psy1i = -1; int sw = source->width(); - long xf = -1; - long nxf = v->getFrameForX(x0); + int xf = -1; + int nxf = v->getFrameForX(x0); float epsilon = 0.000001; @@ -1453,6 +1499,10 @@ float logmin = symin+1, logmax = symax+1; LogRange::mapRange(logmin, logmax); +#ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT + cerr << "m_smooth = " << m_smooth << ", w = " << w << ", h = " << h << endl; +#endif + if (m_smooth) { for (int y = 0; y < h; ++y) { @@ -1525,22 +1575,28 @@ } } else { + float sy0 = getBinForY(v, 0); + + int psy0i = -1, psy1i = -1; + for (int y = 0; y < h; ++y) { - float sy0, sy1; - + float sy1 = sy0; sy0 = getBinForY(v, y + 1); - sy1 = getBinForY(v, y); int sy0i = int(sy0 + epsilon); int sy1i = int(sy1); uchar *targetLine = img.scanLine(y); - if (sy0i == sy1i && sy0i == psy1i) { // same source scan line as just computed + if (sy0i == psy0i && sy1i == psy1i) { + // same source scan line as just computed goto copy; } + psy0i = sy0i; + psy1i = sy1i; + for (int x = 0; x < w; ++x) { peaks[x] = 0; }
--- a/layer/Colour3DPlotLayer.h Wed Jun 18 13:42:25 2014 +0100 +++ b/layer/Colour3DPlotLayer.h Wed Jul 02 17:31:37 2014 +0100 @@ -214,6 +214,13 @@ DenseThreeDimensionalModel::Column getColumn(int col) const; + /** + * True if we have the opaque or smooth flag set, or if the cells + * are so small you can't see their borders. False for big, + * translucent cells. + */ + bool shouldPaintDenseIn(const View *) const; + int getColourScaleWidth(QPainter &) const; void fillCache(int firstBin, int lastBin) const; void paintDense(View *v, QPainter &paint, QRect rect) const;
--- a/view/View.cpp Wed Jun 18 13:42:25 2014 +0100 +++ b/view/View.cpp Wed Jul 02 17:31:37 2014 +0100 @@ -55,7 +55,7 @@ m_zoomLevel(1024), m_followPan(true), m_followZoom(true), - m_followPlay(PlaybackScrollPage), + m_followPlay(PlaybackScrollPageWithCentre), m_followPlayIsDetached(false), m_playPointerFrame(0), m_showProgress(showProgress), @@ -117,8 +117,12 @@ if (name == "Follow Playback") { if (min) *min = 0; if (max) *max = 2; - if (deflt) *deflt = int(PlaybackScrollPage); - return int(m_followPlay); + if (deflt) *deflt = int(PlaybackScrollPageWithCentre); + switch (m_followPlay) { + case PlaybackScrollContinuous: return 0; + case PlaybackScrollPageWithCentre: case PlaybackScrollPage: return 1; + case PlaybackIgnore: return 2; + } } if (min) *min = 0; if (max) *max = 0; @@ -152,7 +156,7 @@ switch (value) { default: case 0: setPlaybackFollow(PlaybackScrollContinuous); break; - case 1: setPlaybackFollow(PlaybackScrollPage); break; + case 1: setPlaybackFollow(PlaybackScrollPageWithCentre); break; case 2: setPlaybackFollow(PlaybackIgnore); break; } } @@ -704,17 +708,22 @@ connect(this, SIGNAL(zoomLevelChanged(int, bool)), m_manager, SLOT(viewZoomLevelChanged(int, bool))); -// setCentreFrame(m_manager->getViewInitialCentreFrame()); - - if (m_followPlay == PlaybackScrollPage) { -// SVDEBUG << "View::setViewManager: setting centre frame to global centre frame: " << m_manager->getGlobalCentreFrame() << endl; + switch (m_followPlay) { + + case PlaybackScrollPage: + case PlaybackScrollPageWithCentre: setCentreFrame(m_manager->getGlobalCentreFrame(), false); - } else if (m_followPlay == PlaybackScrollContinuous) { -// SVDEBUG << "View::setViewManager: setting centre frame to playback frame: " << m_manager->getPlaybackFrame() << endl; + break; + + case PlaybackScrollContinuous: setCentreFrame(m_manager->getPlaybackFrame(), false); - } else if (m_followPan) { -// SVDEBUG << "View::setViewManager: (follow pan) setting centre frame to global centre frame: " << m_manager->getGlobalCentreFrame() << endl; - setCentreFrame(m_manager->getGlobalCentreFrame(), false); + break; + + case PlaybackIgnore: + if (m_followPan) { + setCentreFrame(m_manager->getGlobalCentreFrame(), false); + } + break; } if (m_followZoom) setZoomLevel(m_manager->getGlobalZoom()); @@ -1016,6 +1025,7 @@ break; case PlaybackScrollPage: + case PlaybackScrollPageWithCentre: if (!pointerInVisibleArea && somethingGoingOn) { @@ -2459,7 +2469,9 @@ .arg(m_followPan) .arg(m_followZoom) .arg(m_followPlay == PlaybackScrollContinuous ? "scroll" : - m_followPlay == PlaybackScrollPage ? "page" : "ignore") + m_followPlay == PlaybackScrollPageWithCentre ? "page" : + m_followPlay == PlaybackScrollPage ? "daw" : + "ignore") .arg(extraAttributes); for (int i = 0; i < (int)m_layers.size(); ++i) {
--- a/view/ViewManager.cpp Wed Jun 18 13:42:25 2014 +0100 +++ b/view/ViewManager.cpp Wed Jul 02 17:31:37 2014 +0100 @@ -554,7 +554,7 @@ if (v) emit viewCentreFrameChanged(v, f); } - if (!dynamic_cast<Overview *>(v) || (mode == PlaybackScrollContinuous)) { + if (!dynamic_cast<Overview *>(v) || (mode != PlaybackIgnore)) { if (m_mainModelSampleRate != 0) { emit activity(tr("Scroll to %1") .arg(RealTime::frame2RealTime @@ -562,11 +562,10 @@ } } - if (mode != PlaybackScrollContinuous) { - return; + if (mode == PlaybackScrollPageWithCentre || + mode == PlaybackScrollContinuous) { + seek(f); } - - seek(f); } void
--- a/view/ViewManager.h Wed Jun 18 13:42:25 2014 +0100 +++ b/view/ViewManager.h Wed Jul 02 17:31:37 2014 +0100 @@ -31,8 +31,31 @@ class Model; enum PlaybackFollowMode { + + /** + * View scrolls continuously during playback, keeping the playback + * position at the centre. + */ PlaybackScrollContinuous, + + /** + * View follows playback page-by-page, but dragging the view + * relocates playback to the centre frame. This is the classic + * Sonic Visualiser behaviour. + */ + PlaybackScrollPageWithCentre, + + /** + * View follows playback page-by-page, and the play head is moved + * (by the user) separately from dragging the view. This is + * roughly the behaviour of a typical DAW or audio editor. + */ PlaybackScrollPage, + + /** + * View is detached from playback. It doesn't follow playback, and + * dragging the view does not affect the play head. + */ PlaybackIgnore };