mirror of
https://github.com/LMMS/lmms.git
synced 2026-04-16 12:07:26 -04:00
Spectrum analyzer update (#5160)
* advanced config: expose hidden constants to user screen * advanced config: add support for FFT window overlapping * waterfall: display at native resolution on high-DPI screens * waterfall: add cursor and improve label density * FFT: fix normalization so that 0 dBFS matches full-scale sinewave * FFT: decouple data acquisition from processing and display * FFT: separate lock for reallocation (to avoid some needless waiting) * moved ranges and other constants to a separate file * debug: better performance measurements * minor fixes * build the ringbuffer library as part of LMMS core
This commit is contained in:
committed by
Johannes Lorenz
parent
2f0010270e
commit
da73ddd242
@@ -50,7 +50,17 @@ SaControls::SaControls(Analyzer *effect) :
|
||||
m_freqRangeModel(this, tr("Frequency range")),
|
||||
m_ampRangeModel(this, tr("Amplitude range")),
|
||||
m_blockSizeModel(this, tr("FFT block size")),
|
||||
m_windowModel(this, tr("FFT window type"))
|
||||
m_windowModel(this, tr("FFT window type")),
|
||||
|
||||
// Advanced settings knobs
|
||||
m_envelopeResolutionModel(0.25f, 0.1f, 3.0f, 0.05f, this, tr("Peak envelope resolution")),
|
||||
m_spectrumResolutionModel(1.5f, 0.1f, 3.0f, 0.05f, this, tr("Spectrum display resolution")),
|
||||
m_peakDecayFactorModel(0.992f, 0.95f, 0.999f, 0.001f, this, tr("Peak decay multiplier")),
|
||||
m_averagingWeightModel(0.15f, 0.01f, 0.5f, 0.01f, this, tr("Averaging weight")),
|
||||
m_waterfallHeightModel(300.0f, 50.0f, 1000.0f, 50.0f, this, tr("Waterfall history size")),
|
||||
m_waterfallGammaModel(0.30f, 0.10f, 1.00f, 0.05f, this, tr("Waterfall gamma correction")),
|
||||
m_windowOverlapModel(2.0f, 1.0f, 4.0f, 1.0f, this, tr("FFT window overlap")),
|
||||
m_zeroPaddingModel(2.0f, 0.0f, 4.0f, 1.0f, this, tr("FFT zero padding"))
|
||||
{
|
||||
// Frequency and amplitude ranges; order must match
|
||||
// FREQUENCY_RANGES and AMPLITUDE_RANGES defined in SaControls.h
|
||||
@@ -62,10 +72,10 @@ SaControls::SaControls(Analyzer *effect) :
|
||||
m_freqRangeModel.setValue(m_freqRangeModel.findText(tr("Full (auto)")));
|
||||
|
||||
m_ampRangeModel.addItem(tr("Extended"));
|
||||
m_ampRangeModel.addItem(tr("Default"));
|
||||
m_ampRangeModel.addItem(tr("Audible"));
|
||||
m_ampRangeModel.addItem(tr("Noise"));
|
||||
m_ampRangeModel.setValue(m_ampRangeModel.findText(tr("Default")));
|
||||
m_ampRangeModel.addItem(tr("Loud"));
|
||||
m_ampRangeModel.addItem(tr("Silent"));
|
||||
m_ampRangeModel.setValue(m_ampRangeModel.findText(tr("Audible")));
|
||||
|
||||
// FFT block size labels are generated automatically, based on
|
||||
// FFT_BLOCK_SIZES vector defined in fft_helpers.h
|
||||
@@ -95,12 +105,15 @@ SaControls::SaControls(Analyzer *effect) :
|
||||
|
||||
// Colors
|
||||
// Background color is defined by Qt / theme.
|
||||
// Make sure the sum of colors for L and R channel stays lower or equal
|
||||
// to 255. Otherwise the Waterfall pixels may overflow back to 0 even when
|
||||
// the input signal isn't clipping (over 1.0).
|
||||
// Make sure the sum of colors for L and R channel results into a neutral
|
||||
// color that has at least one component equal to 255 (i.e. ideally white).
|
||||
// This means the color overflows to zero exactly when signal reaches
|
||||
// clipping threshold, indicating the problematic frequency to user.
|
||||
// Mono waterfall color should have similarly at least one component at 255.
|
||||
m_colorL = QColor(51, 148, 204, 135);
|
||||
m_colorR = QColor(204, 107, 51, 135);
|
||||
m_colorMono = QColor(51, 148, 204, 204);
|
||||
m_colorMonoW = QColor(64, 185, 255, 255);
|
||||
m_colorBG = QColor(7, 7, 7, 255); // ~20 % gray (after gamma correction)
|
||||
m_colorGrid = QColor(30, 34, 38, 255); // ~40 % gray (slightly cold / blue)
|
||||
m_colorLabels = QColor(192, 202, 212, 255); // ~90 % gray (slightly cold / blue)
|
||||
@@ -126,6 +139,15 @@ void SaControls::loadSettings(const QDomElement &_this)
|
||||
m_ampRangeModel.loadSettings(_this, "RangeY");
|
||||
m_blockSizeModel.loadSettings(_this, "BlockSize");
|
||||
m_windowModel.loadSettings(_this, "WindowType");
|
||||
|
||||
m_envelopeResolutionModel.loadSettings(_this, "EnvelopeRes");
|
||||
m_spectrumResolutionModel.loadSettings(_this, "SpectrumRes");
|
||||
m_peakDecayFactorModel.loadSettings(_this, "PeakDecayFactor");
|
||||
m_averagingWeightModel.loadSettings(_this, "AverageWeight");
|
||||
m_waterfallHeightModel.loadSettings(_this, "WaterfallHeight");
|
||||
m_waterfallGammaModel.loadSettings(_this, "WaterfallGamma");
|
||||
m_windowOverlapModel.loadSettings(_this, "WindowOverlap");
|
||||
m_zeroPaddingModel.loadSettings(_this, "ZeroPadding");
|
||||
}
|
||||
|
||||
|
||||
@@ -141,4 +163,14 @@ void SaControls::saveSettings(QDomDocument &doc, QDomElement &parent)
|
||||
m_ampRangeModel.saveSettings(doc, parent, "RangeY");
|
||||
m_blockSizeModel.saveSettings(doc, parent, "BlockSize");
|
||||
m_windowModel.saveSettings(doc, parent, "WindowType");
|
||||
|
||||
m_envelopeResolutionModel.saveSettings(doc, parent, "EnvelopeRes");
|
||||
m_spectrumResolutionModel.saveSettings(doc, parent, "SpectrumRes");
|
||||
m_peakDecayFactorModel.saveSettings(doc, parent, "PeakDecayFactor");
|
||||
m_averagingWeightModel.saveSettings(doc, parent, "AverageWeight");
|
||||
m_waterfallHeightModel.saveSettings(doc, parent, "WaterfallHeight");
|
||||
m_waterfallGammaModel.saveSettings(doc, parent, "WaterfallGamma");
|
||||
m_windowOverlapModel.saveSettings(doc, parent, "WindowOverlap");
|
||||
m_zeroPaddingModel.saveSettings(doc, parent, "ZeroPadding");
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user