Mercurial > hg > svgui
changeset 1143:c53ed1a6fcbd spectrogram-minor-refactor
Fixes to phase display and colour scale for it; tidy up some debug output
author | Chris Cannam |
---|---|
date | Fri, 05 Aug 2016 14:31:16 +0100 |
parents | 8f4634b82e36 |
children | 6eef0330ef12 |
files | layer/Colour3DPlotRenderer.cpp layer/ColourScale.cpp layer/ScrollableImageCache.cpp layer/ScrollableMagRangeCache.cpp layer/ScrollableMagRangeCache.h layer/SpectrogramLayer.cpp layer/SpectrogramLayer.h |
diffstat | 7 files changed, 96 insertions(+), 45 deletions(-) [+] |
line wrap: on
line diff
--- a/layer/Colour3DPlotRenderer.cpp Fri Aug 05 14:00:58 2016 +0100 +++ b/layer/Colour3DPlotRenderer.cpp Fri Aug 05 14:31:16 2016 +0100 @@ -483,7 +483,9 @@ bool timeConstrained) { Profiler profiler("Colour3DPlotRenderer::renderToCachePixelResolution"); +#ifdef DEBUG_COLOUR_PLOT_REPAINT cerr << "renderToCachePixelResolution" << endl; +#endif // Draw to the draw buffer, and then copy from there. The draw // buffer is at the same resolution as the target in the cache, so @@ -523,12 +525,14 @@ } } +#ifdef DEBUG_COLOUR_PLOT_REPAINT cerr << "[PIX] zoomLevel = " << zoomLevel << ", binResolution " << binResolution << ", binsPerPeak " << binsPerPeak << ", peak cache " << m_sources.peaks << ", usePeaksCache = " << usePeaksCache << endl; +#endif for (int y = 0; y < h; ++y) { binfory[y] = m_sources.verticalBinLayer->getBinForY(v, h - y - 1); @@ -578,7 +582,9 @@ int x0, int repaintWidth) { Profiler profiler("Colour3DPlotRenderer::renderToCacheBinResolution"); +#ifdef DEBUG_COLOUR_PLOT_REPAINT cerr << "renderToCacheBinResolution" << endl; +#endif // Draw to the draw buffer, and then scale-copy from there. Draw // buffer is at bin resolution, i.e. buffer x == source column @@ -643,8 +649,10 @@ binforx[x] = int(leftBoundaryFrame / binResolution) + x; } +#ifdef DEBUG_COLOUR_PLOT_REPAINT cerr << "[BIN] binResolution " << binResolution << endl; +#endif for (int y = 0; y < h; ++y) { binfory[y] = m_sources.verticalBinLayer->getBinForY(v, h - y - 1); @@ -663,9 +671,11 @@ int scaledLeft = v->getXForFrame(leftBoundaryFrame); int scaledRight = v->getXForFrame(rightBoundaryFrame); +#ifdef DEBUG_COLOUR_PLOT_REPAINT cerr << "scaling draw buffer from width " << m_drawBuffer.width() << " to " << (scaledRight - scaledLeft) << " (nb drawBufferWidth = " << drawBufferWidth << ")" << endl; +#endif QImage scaled = m_drawBuffer.scaled (scaledRight - scaledLeft, h, @@ -691,8 +701,10 @@ sourceLeft = 0; } +#ifdef DEBUG_COLOUR_PLOT_REPAINT cerr << "repaintWidth = " << repaintWidth << ", targetWidth = " << targetWidth << endl; +#endif if (targetWidth > 0) { // we are copying from an image that has already been scaled, @@ -706,9 +718,6 @@ // but the mag range vector has not been scaled int sourceIx = int((double(i + sourceLeft) / scaled.width()) * int(m_magRanges.size())); -// int sourceIx = int((double(i) / targetWidth) * sourceWidth); - cerr << "mag range target ix = " << i << ", source ix = " - << sourceIx << ", of " << m_magRanges.size() << endl; if (in_range_for(m_magRanges, sourceIx)) { m_magCache.sampleColumn(i, m_magRanges.at(sourceIx)); } @@ -765,8 +774,10 @@ int modelWidth = sourceModel->getWidth(); +#ifdef DEBUG_COLOUR_PLOT_REPAINT cerr << "modelWidth " << modelWidth << ", divisor " << divisor << endl; - +#endif + for (int x = start; x != finish; x += step) { // x is the on-canvas pixel coord; sx (later) will be the @@ -912,8 +923,10 @@ vector<float> preparedColumn; int modelWidth = fft->getWidth(); +#ifdef DEBUG_COLOUR_PLOT_REPAINT cerr << "modelWidth " << modelWidth << endl; - +#endif + double minFreq = (double(minbin) * fft->getSampleRate()) / fft->getFFTSize(); double maxFreq =
--- a/layer/ColourScale.cpp Fri Aug 05 14:00:58 2016 +0100 +++ b/layer/ColourScale.cpp Fri Aug 05 14:31:16 2016 +0100 @@ -89,12 +89,11 @@ if (m_params.scaleType == ColourScaleType::Phase) { double half = (maxPixF - 1.f) / 2.f; int pixel = 1 + int((value * half) / M_PI + half); +// cerr << "phase = " << value << " pixel = " << pixel << endl; return pixel; } value *= m_params.gain; - -// value = pow(value, m_params.multiple); if (value < m_params.threshold) return 0;
--- a/layer/ScrollableImageCache.cpp Fri Aug 05 14:00:58 2016 +0100 +++ b/layer/ScrollableImageCache.cpp Fri Aug 05 14:31:16 2016 +0100 @@ -17,7 +17,7 @@ #include <iostream> using namespace std; -#define DEBUG_SCROLLABLE_IMAGE_CACHE 1 +//#define DEBUG_SCROLLABLE_IMAGE_CACHE 1 void ScrollableImageCache::scrollTo(const LayerGeometryProvider *v,
--- a/layer/ScrollableMagRangeCache.cpp Fri Aug 05 14:00:58 2016 +0100 +++ b/layer/ScrollableMagRangeCache.cpp Fri Aug 05 14:31:16 2016 +0100 @@ -17,7 +17,7 @@ #include <iostream> using namespace std; -#define DEBUG_SCROLLABLE_MAG_RANGE_CACHE 1 +//#define DEBUG_SCROLLABLE_MAG_RANGE_CACHE 1 void ScrollableMagRangeCache::scrollTo(const LayerGeometryProvider *v, @@ -76,11 +76,13 @@ m_ranges = newRanges; } +#ifdef DEBUG_SCROLLABLE_MAG_RANGE_CACHE cerr << "maxes (" << m_ranges.size() << ") now: "; for (int i = 0; in_range_for(m_ranges, i); ++i) { cerr << m_ranges[i].getMax() << " "; } cerr << endl; +#endif } MagnitudeRange @@ -109,23 +111,3 @@ } } -//!!! unneeded? -void -ScrollableMagRangeCache::sampleColumn(const LayerGeometryProvider *v, - sv_frame_t frame, - const MagnitudeRange &r) -{ - int x = (v->getXForFrame(frame) - - v->getXForFrame(m_startFrame)); - - if (!in_range_for(m_ranges, x)) { - cerr << "WARNING: ScrollableMagRangeCache::sampleColumn: column " << x - << " arising from frame " << frame << " is out of range for cache " - << "of width " << m_ranges.size() - << " (with start frame " << m_startFrame << ")" << endl; - throw logic_error("column out of range"); - } else { - sampleColumn(x, r); - } -} -
--- a/layer/ScrollableMagRangeCache.h Fri Aug 05 14:00:58 2016 +0100 +++ b/layer/ScrollableMagRangeCache.h Fri Aug 05 14:31:16 2016 +0100 @@ -130,12 +130,6 @@ */ void sampleColumn(int column, const MagnitudeRange &r); - /** - * Update a column in the cache, by frame. - */ - void sampleColumn(const LayerGeometryProvider *v, sv_frame_t frame, - const MagnitudeRange &r); - private: std::vector<MagnitudeRange> m_ranges; sv_frame_t m_startFrame;
--- a/layer/SpectrogramLayer.cpp Fri Aug 05 14:00:58 2016 +0100 +++ b/layer/SpectrogramLayer.cpp Fri Aug 05 14:31:16 2016 +0100 @@ -51,8 +51,8 @@ #include <alloca.h> #endif -#define DEBUG_SPECTROGRAM 1 -#define DEBUG_SPECTROGRAM_REPAINT 1 +//#define DEBUG_SPECTROGRAM 1 +//#define DEBUG_SPECTROGRAM_REPAINT 1 using namespace std; @@ -1507,9 +1507,11 @@ result = renderer->renderTimeConstrained(v, paint, rect); +#ifdef DEBUG_SPECTROGRAM_REPAINT cerr << "rect width from this paint: " << result.rendered.width() << ", mag range in this paint: " << result.range.getMin() << " -> " << result.range.getMax() << endl; +#endif QRect uncached = renderer->getLargestUncachedRect(v); if (uncached.width() > 0) { @@ -1522,15 +1524,19 @@ if (magRange.isSet()) { if (m_viewMags[viewId] != magRange) { m_viewMags[viewId] = magRange; +#ifdef DEBUG_SPECTROGRAM_REPAINT cerr << "mag range in this view has changed: " << magRange.getMin() << " -> " << magRange.getMax() << endl; +#endif } } if (!continuingPaint && m_normalizeVisibleArea && m_viewMags[viewId] != m_lastRenderedMags[viewId]) { +#ifdef DEBUG_SPECTROGRAM_REPAINT cerr << "mag range has changed from last rendered range: re-rendering" << endl; +#endif delete m_renderers[viewId]; m_renderers.erase(viewId); v->updatePaintRect(v->getPaintRect()); @@ -1571,8 +1577,10 @@ return; } +#ifdef DEBUG_SPECTROGRAM_REPAINT cerr << "SpectrogramLayer: illuminateLocalFeatures(" << localPos.x() << "," << localPos.y() << ")" << endl; +#endif double s0, s1; double f0, f1; @@ -1589,8 +1597,10 @@ int y1 = int(getYForFrequency(v, f1)); int y0 = int(getYForFrequency(v, f0)); +#ifdef DEBUG_SPECTROGRAM_REPAINT cerr << "SpectrogramLayer: illuminate " << x0 << "," << y1 << " -> " << x1 << "," << y0 << endl; +#endif paint.setPen(v->getForeground()); @@ -2093,6 +2103,11 @@ QPainter &paint, QRect rect) const { // The colour scale + + if (m_colourScale == ColourScaleType::Phase) { + paintDetailedScalePhase(v, paint, rect); + return; + } int h = rect.height(); int textHeight = paint.fontMetrics().height(); @@ -2102,7 +2117,6 @@ int cbw = paint.fontMetrics().width("dB"); int topLines = 2; - if (m_colourScale == ColourScaleType::Phase) topLines = 1; int ch = h - textHeight * (topLines + 1) - 8; // paint.drawRect(4, textHeight + 4, cw - 1, ch + 1); @@ -2135,12 +2149,8 @@ << endl; #endif - //!!! & phase etc - - if (m_colourScale != ColourScaleType::Phase) { - paint.drawText((cw + 6 - paint.fontMetrics().width("dBFS")) / 2, - 2 + textHeight + toff, "dBFS"); - } + paint.drawText((cw + 6 - paint.fontMetrics().width("dBFS")) / 2, + 2 + textHeight + toff, "dBFS"); // paint.drawText((cw + 6 - paint.fontMetrics().width(top)) / 2, paint.drawText(3 + cw - cbw - paint.fontMetrics().width(top), @@ -2189,6 +2199,56 @@ paint.restore(); } +void +SpectrogramLayer::paintDetailedScalePhase(LayerGeometryProvider *v, + QPainter &paint, QRect rect) const +{ + // The colour scale in phase mode + + int h = rect.height(); + int textHeight = paint.fontMetrics().height(); + int toff = -textHeight + paint.fontMetrics().ascent() + 2; + + int cw = getColourScaleWidth(paint); + + // Phase is not measured in dB of course, but this places the + // scale at the same position as in the magnitude spectrogram + int cbw = paint.fontMetrics().width("dB"); + + int topLines = 1; + + int ch = h - textHeight * (topLines + 1) - 8; + paint.drawRect(4 + cw - cbw, textHeight * topLines + 4, cbw - 1, ch + 1); + + QString top, bottom, middle; + top = QString("%1").arg(QChar(0x3c0)); // pi + bottom = "-" + top; + middle = "0"; + + double min = -M_PI; + double max = M_PI; + + paint.drawText(3 + cw - cbw - paint.fontMetrics().width(top), + 2 + textHeight * topLines + toff + textHeight/2, top); + + paint.drawText(3 + cw - cbw - paint.fontMetrics().width(middle), + 2 + textHeight * topLines + ch/2 + toff + textHeight/2, middle); + + paint.drawText(3 + cw - cbw - paint.fontMetrics().width(bottom), + h + toff - 3 - textHeight/2, bottom); + + paint.save(); + paint.setBrush(Qt::NoBrush); + + for (int i = 0; i < ch; ++i) { + double val = min + (((max - min) * i) / (ch - 1)); + paint.setPen(getRenderer(v)->getColour(val)); + int y = textHeight * topLines + 4 + ch - i; + paint.drawLine(5 + cw - cbw, y, cw + 2, y); + } + paint.restore(); +} + class SpectrogramRangeMapper : public RangeMapper { public:
--- a/layer/SpectrogramLayer.h Fri Aug 05 14:00:58 2016 +0100 +++ b/layer/SpectrogramLayer.h Fri Aug 05 14:31:16 2016 +0100 @@ -322,7 +322,10 @@ void paintWithRenderer(LayerGeometryProvider *v, QPainter &paint, QRect rect) const; - void paintDetailedScale(LayerGeometryProvider *v, QPainter &paint, QRect rect) const; + void paintDetailedScale(LayerGeometryProvider *v, + QPainter &paint, QRect rect) const; + void paintDetailedScalePhase(LayerGeometryProvider *v, + QPainter &paint, QRect rect) const; virtual void updateMeasureRectYCoords(LayerGeometryProvider *v, const MeasureRect &r) const;