Mercurial > hg > svgui
diff layer/SpectrogramLayer.cpp @ 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 | 8072264dc61f |
children | 5d3a6ecdf2db 6a8d922f991d |
line wrap: on
line diff
--- 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);