Mercurial > hg > svgui
changeset 1083:7122aae95a88 spectrogram-minor-refactor
Start introducing render code
author | Chris Cannam |
---|---|
date | Fri, 01 Jul 2016 11:21:09 +0100 |
parents | 5b4fe7bb9430 |
children | db976e9f385a |
files | layer/Colour3DPlotRenderer.cpp layer/Colour3DPlotRenderer.h layer/VerticalBinLayer.h |
diffstat | 3 files changed, 152 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/layer/Colour3DPlotRenderer.cpp Fri Jul 01 09:55:48 2016 +0100 +++ b/layer/Colour3DPlotRenderer.cpp Fri Jul 01 11:21:09 2016 +0100 @@ -273,18 +273,157 @@ m_sources.verticalBinLayer->getBinForY(m_sources.geometryProvider, y); } - /* - int attainedWidth = renderDrawBuffer(v, - repaintWidth, + int attainedWidth = renderDrawBuffer(repaintWidth, h, binforx, binfory, usePeaksCache, rightToLeft, timeConstrained); - */ + + //!!! now scale-copy to cache } - + + +int +Colour3DPlotRenderer::renderDrawBuffer(int w, int h, + const vector<int> &binforx, + const vector<double> &binfory, + bool usePeaksCache, + bool rightToLeft, + bool timeConstrained) +{ + // Callers must have checked that the appropriate subset of + // Sources data members are set for the supplied flags (e.g. that + // peaks model exists if usePeaksCache) + + RenderTimer timer(timeConstrained ? + RenderTimer::FastRender : + RenderTimer::NoTimeout); + + int minbin = int(binfory[0] + 0.0001); + int maxbin = int(binfory[h-1]); + if (minbin < 0) minbin = 0; + if (maxbin < 0) maxbin = minbin+1; + + int divisor = 1; + DenseThreeDimensionalModel *sourceModel = m_sources.source; + if (usePeaksCache) { + divisor = m_sources.peaks->getColumnsPerPeak(); + sourceModel = m_sources.peaks; + } + + int psx = -1; + + int start = 0; + int finish = w; + int step = 1; + + if (rightToLeft) { + start = w-1; + finish = -1; + step = -1; + } + + int columnCount = 0; + + vector<float> preparedColumn; + + for (int x = start; x != finish; x += step) { + + // x is the on-canvas pixel coord; sx (later) will be the + // source column index + + ++columnCount; + + if (binforx[x] < 0) continue; + + int sx0 = binforx[x] / divisor; + int sx1 = sx0; + if (x+1 < w) sx1 = binforx[x+1] / divisor; + if (sx0 < 0) sx0 = sx1 - 1; + if (sx0 < 0) continue; + if (sx1 <= sx0) sx1 = sx0 + 1; + + vector<float> pixelPeakColumn; + + for (int sx = sx0; sx < sx1; ++sx) { + +#ifdef DEBUG_SPECTROGRAM_REPAINT +// cerr << "sx = " << sx << endl; +#endif + + if (sx < 0 || sx >= sourceModel->getWidth()) { + continue; + } + + if (sx != psx) { + + // order: + // get column -> scale -> record extents -> + // normalise -> peak pick -> apply display gain -> + // distribute/interpolate + + ColumnOp::Column fullColumn = sourceModel->getColumn(sx); + ColumnOp::Column column = + vector<float>(fullColumn.data() + minbin, + fullColumn.data() + maxbin + 1); + +//!!! fft scale if (m_colourScale != PhaseColourScale) { +// column = ColumnOp::fftScale(column, m_fftSize); +// } + +//!!! extents recordColumnExtents(column, +// sx, +// overallMag, +// overallMagChanged); + +// if (m_colourScale != PhaseColourScale) { + column = ColumnOp::normalize(column, m_params.normalization); +// } + + if (m_params.binDisplay == PeakBins) { + column = ColumnOp::peakPick(column); + } + + preparedColumn = + ColumnOp::distribute(column, //!!! gain? ColumnOp::applyGain(column, m_gain), + h, + binfory, + minbin, + m_params.interpolate); + + psx = sx; + } + + if (sx == sx0) { + pixelPeakColumn = preparedColumn; + } else { + for (int i = 0; in_range_for(pixelPeakColumn, i); ++i) { + pixelPeakColumn[i] = std::max(pixelPeakColumn[i], + preparedColumn[i]); + } + } + } + + if (!pixelPeakColumn.empty()) { + for (int y = 0; y < h; ++y) { + m_drawBuffer.setPixel + (x, + h-y-1, + m_params.colourScale.getPixel(pixelPeakColumn[y])); + } + } + + double fractionComplete = double(columnCount) / double(w); + if (timer.outOfTime(fractionComplete)) { + return columnCount; + } + } + + return columnCount; +} + void Colour3DPlotRenderer::clearDrawBuffer(int w, int h) {
--- a/layer/Colour3DPlotRenderer.h Fri Jul 01 09:55:48 2016 +0100 +++ b/layer/Colour3DPlotRenderer.h Fri Jul 01 11:21:09 2016 +0100 @@ -157,6 +157,12 @@ RenderResult render(QPainter &paint, QRect rect, bool timeConstrained); void renderToCache(int x0, int repaintWidth, bool rightToLeft, bool timeConstrained); + int renderDrawBuffer(int w, int h, + const std::vector<int> &binforx, + const std::vector<double> &binfory, + bool usePeaksCache, + bool rightToLeft, + bool timeConstrained); void clearDrawBuffer(int w, int h); };
--- a/layer/VerticalBinLayer.h Fri Jul 01 09:55:48 2016 +0100 +++ b/layer/VerticalBinLayer.h Fri Jul 01 11:21:09 2016 +0100 @@ -19,6 +19,8 @@ /** * Interface for layers in which the Y axis corresponds to bin number * rather than scale value. Colour3DPlotLayer is the obvious example. + *!!! should just be a mapper interface, not a layer one? + *!!! or even an application of RangeMapper */ class VerticalBinLayer {