Mercurial > hg > svgui
diff layer/SpectrumLayer.cpp @ 1403:10e768adaee5
Retain consistent min freq (rather than min bin no) when changing fft parameters in spectrum; scale ffts by window size rather than fft size in case of oversampling, to avoid fading out because of scale factor including zero padding
author | Chris Cannam |
---|---|
date | Thu, 15 Nov 2018 15:08:08 +0000 |
parents | decb7741d036 |
children | c8a6fd3f9dff |
line wrap: on
line diff
--- a/layer/SpectrumLayer.cpp Thu Nov 15 14:18:26 2018 +0000 +++ b/layer/SpectrumLayer.cpp Thu Nov 15 15:08:08 2018 +0000 @@ -41,7 +41,8 @@ m_windowHopLevel(3), m_oversampling(1), m_showPeaks(false), - m_newFFTNeeded(true) + m_newFFTNeeded(true), + m_freqOfMinBin(0.0) { m_binAlignment = BinsCentredOnScalePoints; @@ -126,6 +127,8 @@ if (m_minbin == 0 && m_maxbin == 0) { m_minbin = 1; + m_freqOfMinBin = double(m_minbin * newFFT->getSampleRate()) + / getFFTSize(); m_maxbin = newFFT->getHeight(); } @@ -133,7 +136,9 @@ m_biasCurve.clear(); for (int i = 0; i < fftSize; ++i) { - m_biasCurve.push_back(1.f / (float(fftSize)/2.f)); + // Scale by the window size, not the FFT size, because we + // don't want to scale down by all the zero bins + m_biasCurve.push_back(1.f / (float(m_windowSize)/2.f)); } m_newFFTNeeded = false; @@ -298,12 +303,12 @@ SVDEBUG << "setWindowSize: from " << m_windowSize << " to " << ws << ": updating min and max bins from " << m_minbin << " and " << m_maxbin << " to "; - /* - m_minbin = int(round((double(m_minbin) / m_windowSize) * ws)); - */ - m_maxbin = int(round((double(m_maxbin) / m_windowSize) * ws)); + int previousWs = m_windowSize; m_windowSize = ws; + + m_minbin = int(round(getBinForFrequency(m_freqOfMinBin))); + m_maxbin = int(round((double(m_maxbin) / previousWs) * m_windowSize)); int h = getFFTSize() / 2 + 1; if (m_minbin > h) m_minbin = h; @@ -341,12 +346,13 @@ SVDEBUG << "setOversampling: from " << m_oversampling << " to " << oversampling << ": updating min and max bins from " << m_minbin << " and " << m_maxbin << " to "; -/* - m_minbin = int(round((double(m_minbin) / m_oversampling) * oversampling)); -*/ - m_maxbin = int(round((double(m_maxbin) / m_oversampling) * oversampling)); + int previousOversampling = m_oversampling; m_oversampling = oversampling; + + m_minbin = int(round(getBinForFrequency(m_freqOfMinBin))); + m_maxbin = int(round((double(m_maxbin) / previousOversampling) * + m_oversampling)); int h = getFFTSize() / 2 + 1; if (m_minbin > h) m_minbin = h; @@ -355,7 +361,6 @@ SVDEBUG << m_minbin << " and " << m_maxbin << endl; m_newFFTNeeded = true; - emit layerParametersChanged(); } @@ -385,6 +390,16 @@ } } +bool +SpectrumLayer::setDisplayExtents(double min, double max) +{ + bool result = SliceLayer::setDisplayExtents(min, max); + if (result) { + m_freqOfMinBin = getFrequencyForBin(m_minbin); + } + return result; +} + double SpectrumLayer::getBinForFrequency(double freq) const {