Mercurial > hg > svgui
diff layer/SpectrumLayer.cpp @ 1281:fc9d9f1103fa horizontal-scale
Provide linear horizontal scale in spectrum as well as log; fix bin positioning and colour scale property box updating; ensure proper background colour and visibility of peak lines
author | Chris Cannam |
---|---|
date | Thu, 03 May 2018 15:15:15 +0100 |
parents | 34394e8c2942 |
children | d79e21855aef |
line wrap: on
line diff
--- a/layer/SpectrumLayer.cpp Wed May 02 14:27:17 2018 +0100 +++ b/layer/SpectrumLayer.cpp Thu May 03 15:15:15 2018 +0100 @@ -26,7 +26,7 @@ #include "ColourMapper.h" #include "PaintAssistant.h" #include "PianoScale.h" -#include "LogNumericalScale.h" +#include "HorizontalFrequencyScale.h" #include <QPainter> #include <QTextStream> @@ -304,6 +304,9 @@ { if (!m_sliceableModel) return 0; double bin = getBinForX(v, x); + // we assume the frequency of a bin corresponds to the centre of + // its visual range + bin -= 0.5; return (m_sliceableModel->getSampleRate() * bin) / (m_sliceableModel->getHeight() * 2); } @@ -314,6 +317,8 @@ if (!m_sliceableModel) return 0; double bin = (freq * m_sliceableModel->getHeight() * 2) / m_sliceableModel->getSampleRate(); + // we want the centre of the bin range + bin += 0.5; return getXForBin(v, bin); } @@ -600,27 +605,22 @@ double thresh = (pow(10, -6) / m_gain) * (m_windowSize / 2.0); // -60dB adj int xorigin = getVerticalScaleWidth(v, false, paint) + 1; - int w = v->getPaintWidth() - xorigin - 1; - - int pkh = int(paint.fontMetrics().height() * 0.7 + 0.5); - if (pkh < 10) pkh = 10; - - int scaleh = LogNumericalScale().getWidth(v, paint, true); - - paint.save(); + int scaleHeight = getHorizontalScaleHeight(v, paint); if (fft && m_showPeaks) { // draw peak lines -// SVDEBUG << "Showing peaks..." << endl; - int col = int(v->getCentreFrame() / fft->getResolution()); paint.save(); paint.setRenderHint(QPainter::Antialiasing, false); - paint.setPen(QColor(160, 160, 160)); //!!! + ColourMapper mapper = + hasLightBackground() ? + ColourMapper(ColourMapper::BlackOnWhite, 0, 1) : + ColourMapper(ColourMapper::WhiteOnBlack, 0, 1); + int peakminbin = 0; int peakmaxbin = fft->getHeight() - 1; double peakmaxfreq = Pitch::getFrequencyForPitch(128); @@ -629,8 +629,6 @@ FFTModel::PeakSet peaks = fft->getPeakFrequencies (FFTModel::MajorPitchAdaptivePeaks, col, peakminbin, peakmaxbin); - ColourMapper mapper(ColourMapper::BlackOnWhite, 0, 1); - BiasCurve curve; getBiasCurve(curve); int cs = int(curve.size()); @@ -660,14 +658,38 @@ (void)getYForValue(v, values[bin], norm); // don't need return value, need norm paint.setPen(mapper.map(norm)); - paint.drawLine(x, 0, x, v->getPaintHeight() - scaleh - pkh - 1); + paint.drawLine(x, 0, x, v->getPaintHeight() - scaleHeight - 1); } paint.restore(); } + paint.save(); + SliceLayer::paint(v, paint, rect); + + paintHorizontalScale(v, paint, xorigin); + paint.restore(); +} + +int +SpectrumLayer::getHorizontalScaleHeight(LayerGeometryProvider *v, + QPainter &paint) const +{ + int pkh = int(paint.fontMetrics().height() * 0.7 + 0.5); + if (pkh < 10) pkh = 10; + + int scaleh = HorizontalFrequencyScale().getHeight(v, paint); + + return pkh + scaleh; +} + +void +SpectrumLayer::paintHorizontalScale(LayerGeometryProvider *v, + QPainter &paint, + int xorigin) const +{ //!!! All of this stuff relating to depicting frequencies // (keyboard, crosshairs etc) should be applicable to any slice // layer whose model has a vertical scale unit of Hz. However, @@ -677,17 +699,39 @@ // that could be relevant to Colour3DPlotLayer with unit Hz, but // that's a bigger proposition. - int h = v->getPaintHeight(); + if (!v->getViewManager()->shouldShowHorizontalValueScale()) { + return; + } + + int totalScaleHeight = getHorizontalScaleHeight(v, paint); // inc piano + int freqScaleHeight = HorizontalFrequencyScale().getHeight(v, paint); + int paintHeight = v->getPaintHeight(); + int paintWidth = v->getPaintWidth(); PianoScale().paintPianoHorizontal (v, this, paint, - QRect(xorigin, h - scaleh - pkh - 1, w + xorigin, pkh)); + QRect(xorigin, paintHeight - totalScaleHeight - 1, + paintWidth - 1, totalScaleHeight - freqScaleHeight)); - LogNumericalScale().paintHorizontal + int scaleLeft = int(getXForBin(v, 1)); + + paint.drawLine(int(getXForBin(v, 0)), paintHeight - freqScaleHeight, + scaleLeft, paintHeight - freqScaleHeight); + + QString hz = tr("Hz"); + int hzw = paint.fontMetrics().width(hz); + if (scaleLeft > hzw + 5) { + paint.drawText + (scaleLeft - hzw - 5, + paintHeight - freqScaleHeight + paint.fontMetrics().ascent() + 5, + hz); + } + + HorizontalFrequencyScale().paintScale (v, this, paint, - QRect(int(getXForBin(v, 1)), h - scaleh, w + xorigin, scaleh)); - - paint.restore(); + QRect(scaleLeft, paintHeight - freqScaleHeight, + paintWidth, totalScaleHeight), + m_binScale == LogBins); } void