Mercurial > hg > svgui
changeset 719:67e6d518ac27
Bodge in Matthias's suggested normalise-to-log as an option in spectrogram and colour 3d plot layers (not wired into gui)
author | Chris Cannam |
---|---|
date | Tue, 28 Jan 2014 17:37:42 +0000 |
parents | b81f21f2c4c3 |
children | 5f9c0147d1d6 5d3a6ecdf2db |
files | layer/Colour3DPlotLayer.cpp layer/Colour3DPlotLayer.h layer/SpectrogramLayer.cpp layer/SpectrogramLayer.h |
diffstat | 4 files changed, 96 insertions(+), 50 deletions(-) [+] |
line wrap: on
line diff
--- a/layer/Colour3DPlotLayer.cpp Wed Dec 04 14:00:27 2013 +0000 +++ b/layer/Colour3DPlotLayer.cpp Tue Jan 28 17:37:42 2014 +0000 @@ -51,6 +51,7 @@ m_binScale(LinearBinScale), m_normalizeColumns(false), m_normalizeVisibleArea(false), + m_normalizeHybrid(false), m_invertVertical(false), m_opaque(false), m_smooth(false), @@ -430,6 +431,21 @@ } void +Colour3DPlotLayer::setNormalizeHybrid(bool n) +{ + if (m_normalizeHybrid == n) return; + m_normalizeHybrid = n; + cacheInvalid(); + emit layerParametersChanged(); +} + +bool +Colour3DPlotLayer::getNormalizeHybrid() const +{ + return m_normalizeHybrid; +} + +void Colour3DPlotLayer::setNormalizeVisibleArea(bool n) { if (m_normalizeVisibleArea == n) return; @@ -882,7 +898,7 @@ { DenseThreeDimensionalModel::Column values = m_model->getColumn(col); while (values.size() < m_model->getHeight()) values.push_back(0.f); - if (!m_normalizeColumns) return values; + if (!m_normalizeColumns && !m_normalizeHybrid) return values; float colMax = 0.f, colMin = 0.f; float min = 0.f, max = 0.f; @@ -905,6 +921,13 @@ if (value != newvalue) values[y] = newvalue; } + if (m_normalizeHybrid && (colMax > 0.0)) { + float logmax = log10(colMax); + for (size_t y = 0; y < values.size(); ++y) { + values[y] *= logmax; + } + } + return values; }
--- a/layer/Colour3DPlotLayer.h Wed Dec 04 14:00:27 2013 +0000 +++ b/layer/Colour3DPlotLayer.h Tue Jan 28 17:37:42 2014 +0000 @@ -116,12 +116,26 @@ void setBinScale(BinScale); BinScale getBinScale() const; + /** + * Normalize each column to its maximum value, independent of its + * neighbours. + */ void setNormalizeColumns(bool n); bool getNormalizeColumns() const; + /** + * Normalize each value against the maximum in the visible region. + */ void setNormalizeVisibleArea(bool n); bool getNormalizeVisibleArea() const; + /** + * Normalize each column to its maximum value, and then scale by + * the log of the (absolute) maximum value. + */ + void setNormalizeHybrid(bool n); + bool getNormalizeHybrid() const; + void setInvertVertical(bool i); bool getInvertVertical() const; @@ -168,6 +182,7 @@ BinScale m_binScale; bool m_normalizeColumns; bool m_normalizeVisibleArea; + bool m_normalizeHybrid; bool m_invertVertical; bool m_opaque; bool m_smooth;
--- a/layer/SpectrogramLayer.cpp Wed Dec 04 14:00:27 2013 +0000 +++ b/layer/SpectrogramLayer.cpp Tue Jan 28 17:37:42 2014 +0000 @@ -75,6 +75,7 @@ m_binDisplay(AllBins), m_normalizeColumns(false), m_normalizeVisibleArea(false), + m_normalizeHybrid(false), m_lastEmittedZoomStep(-1), m_synchronous(false), m_haveDetailedScale(false), @@ -951,6 +952,24 @@ } void +SpectrogramLayer::setNormalizeHybrid(bool n) +{ + if (m_normalizeHybrid == n) return; + + invalidateImageCaches(); + invalidateMagnitudes(); + m_normalizeHybrid = n; + + emit layerParametersChanged(); +} + +bool +SpectrogramLayer::getNormalizeHybrid() const +{ + return m_normalizeHybrid; +} + +void SpectrogramLayer::setNormalizeVisibleArea(bool n) { SVDEBUG << "SpectrogramLayer::setNormalizeVisibleArea(" << n @@ -1245,50 +1264,6 @@ } float -SpectrogramLayer::getInputForDisplayValue(unsigned char uc) const -{ - //!!! unused - - int value = uc; - float input; - - //!!! incorrect for normalizing visible area (and also out of date) - - switch (m_colourScale) { - - default: - case LinearColourScale: - input = float(value - 1) / 255.0 / (m_normalizeColumns ? 1 : 50); - break; - - case MeterColourScale: - input = AudioLevel::preview_to_multiplier(value - 1, 255) - / (m_normalizeColumns ? 1.0 : 50.0); - break; - - case dBSquaredColourScale: - input = float(value - 1) / 255.0; - input = (input * 80.0) - 80.0; - input = powf(10.0, input) / 20.0; - value = int(input); - break; - - case dBColourScale: - input = float(value - 1) / 255.0; - input = (input * 80.0) - 80.0; - input = powf(10.0, input) / 20.0; - value = int(input); - break; - - case PhaseColourScale: - input = float(value - 128) * M_PI / 127.0; - break; - } - - return input; -} - -float SpectrogramLayer::getEffectiveMinFrequency() const { int sr = m_model->getSampleRate(); @@ -2556,6 +2531,14 @@ fft->getPhasesAt(sx, values, minbin, maxbin - minbin + 1); } else if (m_normalizeColumns) { fft->getNormalizedMagnitudesAt(sx, values, minbin, maxbin - minbin + 1); + } else if (m_normalizeHybrid) { + fft->getNormalizedMagnitudesAt(sx, values, minbin, maxbin - minbin + 1); + float max = fft->getMaximumMagnitudeAt(sx); + if (max > 0.f) { + for (int i = minbin; i <= maxbin; ++i) { + values[i - minbin] *= log10(max); + } + } } else { fft->getMagnitudesAt(sx, values, minbin, maxbin - minbin + 1); } @@ -2574,7 +2557,7 @@ float value = values[bin - minbin]; if (m_colourScale != PhaseColourScale) { - if (!m_normalizeColumns) { + if (!m_normalizeColumns && !m_normalizeHybrid) { value /= (m_fftSize/2.f); } mag.sample(value); @@ -2715,6 +2698,14 @@ fft->getPhasesAt(sx, autoarray, minbin, maxbin - minbin + 1); } else if (m_normalizeColumns) { fft->getNormalizedMagnitudesAt(sx, autoarray, minbin, maxbin - minbin + 1); + } else if (m_normalizeHybrid) { + fft->getNormalizedMagnitudesAt(sx, autoarray, minbin, maxbin - minbin + 1); + float max = fft->getMaximumMagnitudeAt(sx); + for (int i = minbin; i <= maxbin; ++i) { + if (max > 0.f) { + autoarray[i - minbin] *= log10(max); + } + } } else { fft->getMagnitudesAt(sx, autoarray, minbin, maxbin - minbin + 1); } @@ -2723,7 +2714,7 @@ SVDEBUG << "Retrieving column " << sx << " from peaks cache" << endl; #endif c = sourceModel->getColumn(sx); - if (m_normalizeColumns) { + if (m_normalizeColumns || m_normalizeHybrid) { for (int y = 0; y < h; ++y) { if (c[y] > columnMax) columnMax = c[y]; } @@ -2823,9 +2814,12 @@ float peak = peaks[y]; if (m_colourScale != PhaseColourScale && - m_normalizeColumns && + (m_normalizeColumns || m_normalizeHybrid) && columnMax > 0.f) { peak /= columnMax; + if (m_normalizeHybrid) { + peak *= log10(columnMax); + } } unsigned char peakpix = getDisplayValue(v, peak);
--- a/layer/SpectrogramLayer.h Wed Dec 04 14:00:27 2013 +0000 +++ b/layer/SpectrogramLayer.h Tue Jan 28 17:37:42 2014 +0000 @@ -170,13 +170,27 @@ */ void setBinDisplay(BinDisplay); BinDisplay getBinDisplay() const; - + + /** + * Normalize each column to its maximum value, independent of its + * neighbours. + */ void setNormalizeColumns(bool n); bool getNormalizeColumns() const; + /** + * Normalize each value against the maximum in the visible region. + */ void setNormalizeVisibleArea(bool n); bool getNormalizeVisibleArea() const; + /** + * Normalize each column to its maximum value, and then scale by + * the log of the (absolute) maximum value. + */ + void setNormalizeHybrid(bool n); + bool getNormalizeHybrid() const; + void setColourMap(int map); int getColourMap() const; @@ -260,6 +274,7 @@ BinDisplay m_binDisplay; bool m_normalizeColumns; bool m_normalizeVisibleArea; + bool m_normalizeHybrid; int m_lastEmittedZoomStep; bool m_synchronous; @@ -320,7 +335,6 @@ void rotatePalette(int distance); unsigned char getDisplayValue(View *v, float input) const; - float getInputForDisplayValue(unsigned char uc) const; int getColourScaleWidth(QPainter &) const;