# HG changeset patch # User Chris Cannam # Date 1541590671 0 # Node ID 2df1af7ac7529036156a1cd3fe6e3b7074af7774 # Parent 2f4476993ae624e30a751df03f2093321e070729 Add oversampling option to spectrum as well diff -r 2f4476993ae6 -r 2df1af7ac752 layer/SliceLayer.cpp --- a/layer/SliceLayer.cpp Tue Nov 06 15:42:35 2018 +0000 +++ b/layer/SliceLayer.cpp Wed Nov 07 11:37:51 2018 +0000 @@ -368,7 +368,7 @@ !m_sliceableModel->isReady()) return; paint.save(); - paint.setRenderHint(QPainter::Antialiasing, false); + paint.setRenderHint(QPainter::Antialiasing, m_plotStyle == PlotLines); paint.setBrush(Qt::NoBrush); if (v->getViewManager() && v->getViewManager()->shouldShowScaleGuides()) { diff -r 2f4476993ae6 -r 2df1af7ac752 layer/SpectrogramLayer.cpp --- a/layer/SpectrogramLayer.cpp Tue Nov 06 15:42:35 2018 +0000 +++ b/layer/SpectrogramLayer.cpp Wed Nov 07 11:37:51 2018 +0000 @@ -741,13 +741,9 @@ SpectrogramLayer::setWindowSize(int ws) { if (m_windowSize == ws) return; - invalidateRenderers(); - m_windowSize = ws; - recreateFFTModel(); - emit layerParametersChanged(); } @@ -761,13 +757,9 @@ SpectrogramLayer::setWindowHopLevel(int v) { if (m_windowHopLevel == v) return; - invalidateRenderers(); - m_windowHopLevel = v; - recreateFFTModel(); - emit layerParametersChanged(); } @@ -2538,11 +2530,13 @@ s += QString("channel=\"%1\" " "windowSize=\"%2\" " "windowHopLevel=\"%3\" " - "gain=\"%4\" " - "threshold=\"%5\" ") + "oversampling=\"%4\" " + "gain=\"%5\" " + "threshold=\"%6\" ") .arg(m_channel) .arg(m_windowSize) .arg(m_windowHopLevel) + .arg(m_oversampling) .arg(m_gain) .arg(m_threshold); @@ -2621,6 +2615,9 @@ } } + int oversampling = attributes.value("oversampling").toUInt(&ok); + if (ok) setOversampling(oversampling); + float gain = attributes.value("gain").toFloat(&ok); if (ok) setGain(gain); diff -r 2f4476993ae6 -r 2df1af7ac752 layer/SpectrumLayer.cpp --- a/layer/SpectrumLayer.cpp Tue Nov 06 15:42:35 2018 +0000 +++ b/layer/SpectrumLayer.cpp Wed Nov 07 11:37:51 2018 +0000 @@ -39,6 +39,7 @@ m_windowSize(4096), m_windowType(HanningWindow), m_windowHopLevel(3), + m_oversampling(1), m_showPeaks(false), m_newFFTNeeded(true) { @@ -112,18 +113,20 @@ return; } + int fftSize = getFFTSize(); + FFTModel *newFFT = new FFTModel(m_originModel, m_channel, m_windowType, m_windowSize, getWindowIncrement(), - m_windowSize); + fftSize); setSliceableModel(newFFT); m_biasCurve.clear(); - for (int i = 0; i < m_windowSize; ++i) { - m_biasCurve.push_back(1.f / (float(m_windowSize)/2.f)); + for (int i = 0; i < fftSize; ++i) { + m_biasCurve.push_back(1.f / (float(fftSize)/2.f)); } m_newFFTNeeded = false; @@ -135,6 +138,7 @@ PropertyList list = SliceLayer::getProperties(); list.push_back("Window Size"); list.push_back("Window Increment"); + list.push_back("Oversampling"); list.push_back("Show Peak Frequencies"); return list; } @@ -144,6 +148,7 @@ { if (name == "Window Size") return tr("Window Size"); if (name == "Window Increment") return tr("Window Overlap"); + if (name == "Oversampling") return tr("Oversampling"); if (name == "Show Peak Frequencies") return tr("Show Peak Frequencies"); return SliceLayer::getPropertyLabel(name); } @@ -160,6 +165,7 @@ { if (name == "Window Size") return ValueProperty; if (name == "Window Increment") return ValueProperty; + if (name == "Oversampling") return ValueProperty; if (name == "Show Peak Frequencies") return ToggleProperty; return SliceLayer::getPropertyType(name); } @@ -168,7 +174,8 @@ SpectrumLayer::getPropertyGroupName(const PropertyName &name) const { if (name == "Window Size" || - name == "Window Increment") return tr("Window"); + name == "Window Increment" || + name == "Oversampling") return tr("Window"); if (name == "Show Peak Frequencies") return tr("Bins"); return SliceLayer::getPropertyGroupName(name); } @@ -202,6 +209,16 @@ val = m_windowHopLevel; + } else if (name == "Oversampling") { + + *min = 0; + *max = 3; + *deflt = 0; + + val = 0; + int ov = m_oversampling; + while (ov > 1) { ov >>= 1; val ++; } + } else if (name == "Show Peak Frequencies") { return m_showPeaks ? 1 : 0; @@ -232,6 +249,15 @@ case 5: return tr("93.75 %"); } } + if (name == "Oversampling") { + switch (value) { + default: + case 0: return tr("1x"); + case 1: return tr("2x"); + case 2: return tr("4x"); + case 3: return tr("8x"); + } + } return SliceLayer::getPropertyValueLabel(name, value); } @@ -248,6 +274,8 @@ setWindowSize(32 << value); } else if (name == "Window Increment") { setWindowHopLevel(value); + } else if (name == "Oversampling") { + setOversampling(1 << value); } else if (name == "Show Peak Frequencies") { setShowPeaks(value ? true : false); } else { @@ -283,6 +311,21 @@ } void +SpectrumLayer::setOversampling(int oversampling) +{ + if (m_oversampling == oversampling) return; + m_oversampling = oversampling; + m_newFFTNeeded = true; + emit layerParametersChanged(); +} + +int +SpectrumLayer::getOversampling() const +{ + return m_oversampling; +} + +void SpectrumLayer::setShowPeaks(bool show) { if (m_showPeaks == show) return; @@ -294,7 +337,10 @@ SpectrumLayer::preferenceChanged(PropertyContainer::PropertyName name) { if (name == "Window Type") { - setWindowType(Preferences::getInstance()->getWindowType()); + auto type = Preferences::getInstance()->getWindowType(); + SVDEBUG << "SpectrumLayer::preferenceChanged: Window type changed to " + << type << endl; + setWindowType(type); return; } } @@ -518,10 +564,10 @@ QString binstr; QString hzstr; int minfreq = int(lrint((minbin * m_sliceableModel->getSampleRate()) / - m_windowSize)); + getFFTSize())); int maxfreq = int(lrint((std::max(maxbin, minbin) * m_sliceableModel->getSampleRate()) / - m_windowSize)); + getFFTSize())); if (maxbin != minbin) { binstr = tr("%1 - %2").arg(minbin+1).arg(maxbin+1); @@ -602,7 +648,7 @@ FFTModel *fft = dynamic_cast (const_cast(m_sliceableModel)); - double thresh = (pow(10, -6) / m_gain) * (m_windowSize / 2.0); // -60dB adj + double thresh = (pow(10, -6) / m_gain) * (getFFTSize() / 2.0); // -60dB adj int xorigin = getVerticalScaleWidth(v, false, paint) + 1; int scaleHeight = getHorizontalScaleHeight(v, paint); @@ -746,9 +792,11 @@ { QString s = QString("windowSize=\"%1\" " "windowHopLevel=\"%2\" " - "showPeaks=\"%3\" ") + "oversampling=\"%3\" " + "showPeaks=\"%4\" ") .arg(m_windowSize) .arg(m_windowHopLevel) + .arg(m_oversampling) .arg(m_showPeaks ? "true" : "false"); SliceLayer::toXml(stream, indent, extraAttributes + " " + s); @@ -767,6 +815,9 @@ int windowHopLevel = attributes.value("windowHopLevel").toUInt(&ok); if (ok) setWindowHopLevel(windowHopLevel); + int oversampling = attributes.value("oversampling").toUInt(&ok); + if (ok) setOversampling(oversampling); + bool showPeaks = (attributes.value("showPeaks").trimmed() == "true"); setShowPeaks(showPeaks); } diff -r 2f4476993ae6 -r 2df1af7ac752 layer/SpectrumLayer.h --- a/layer/SpectrumLayer.h Tue Nov 06 15:42:35 2018 +0000 +++ b/layer/SpectrumLayer.h Wed Nov 07 11:37:51 2018 +0000 @@ -90,9 +90,14 @@ void setWindowHopLevel(int level); int getWindowHopLevel() const { return m_windowHopLevel; } + void setOversampling(int oversampling); + int getOversampling() const; + + int getFFTSize() const { return getWindowSize() * getOversampling(); } + void setWindowType(WindowType type); WindowType getWindowType() const { return m_windowType; } - + void setShowPeaks(bool); bool getShowPeaks() const { return m_showPeaks; } @@ -114,6 +119,7 @@ int m_windowSize; WindowType m_windowType; int m_windowHopLevel; + int m_oversampling; bool m_showPeaks; mutable bool m_newFFTNeeded;