From 449ab02ab5adb783583ad6f0e068e60721c084c3 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Sat, 24 Feb 2024 00:17:02 +0100 Subject: [PATCH] Fix fader display for Equalizer shelves and peaks The peak values for the shelves and peaks of the Equalizer plugin are computed in `EqEffect::peakBand`. The previous implementation evaluated the bins of the corresponding frequency spectrum and determined the "loudest" one. The value of this bin was then converted to dbFS and mapped to the interval [0, inf[ where all values less or equal to -60 dbFS were mapped to 0 and a value of 40 dbFS was mapped to 1. So effectively everything was mapped somewhere into [0, 1] yet in a quite "distorted" way because a signal of 40 dbFS resulted in being displayed as unity in the fader. This commit directly returns the value of the maximum bin, i.e. it does not map first to dbFS and then linearize the result anymore. This should work because the `Fader` class assumes a "linear" input signal and if the value of the bin was previously mapped to dbFS it should have some "linear" character. Please note that this is still somewhat of a "proxy" value because ideally the summed amplitude of all relevant bins in the frequency range would be shown and not just the "loudest" one. ## Other changes Rename `peakBand` to `linearPeakBand` to make more clear that a linear value is returned. Handle a potential division by zero by checking the value of `fft->getEnergy()` before using it. Index into `fft->m_bands` so that no parallel incrementing of the pointer is needed. This also enables the removal of the local variable `b`. --- plugins/Eq/EqControls.h | 2 ++ plugins/Eq/EqEffect.cpp | 35 ++++++++++++++++++++--------------- plugins/Eq/EqEffect.h | 2 +- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/plugins/Eq/EqControls.h b/plugins/Eq/EqControls.h index 6db82f3e33f..80680c7fb5a 100644 --- a/plugins/Eq/EqControls.h +++ b/plugins/Eq/EqControls.h @@ -66,6 +66,8 @@ class EqControls : public EffectControls float m_inPeakR; float m_outPeakL; float m_outPeakR; + + // The following are linear peaks float m_lowShelfPeakL, m_lowShelfPeakR; float m_para1PeakL, m_para1PeakR; float m_para2PeakL, m_para2PeakR; diff --git a/plugins/Eq/EqEffect.cpp b/plugins/Eq/EqEffect.cpp index 8a795414429..9361881938a 100644 --- a/plugins/Eq/EqEffect.cpp +++ b/plugins/Eq/EqEffect.cpp @@ -287,21 +287,26 @@ bool EqEffect::processAudioBuffer( sampleFrame *buf, const fpp_t frames ) -float EqEffect::peakBand( float minF, float maxF, EqAnalyser *fft, int sr ) +float EqEffect::linearPeakBand(float minF, float maxF, EqAnalyser* fft, int sr) { - float peak = -60; - float *b = fft->m_bands; - float h = 0; - for( int x = 0; x < MAX_BANDS; x++, b++ ) + auto const fftEnergy = fft->getEnergy(); + if (fftEnergy == 0) { - if( bandToFreq( x ,sr) >= minF && bandToFreq( x,sr ) <= maxF ) + // No energy -> no signal + return 0; + } + + float peakLinear = 0.; + + for (int i = 0; i < MAX_BANDS; ++i) + { + if (bandToFreq(i, sr) >= minF && bandToFreq(i, sr) <= maxF) { - h = 20 * ( log10( *b / fft->getEnergy() ) ); - peak = h > peak ? h : peak; + peakLinear = std::max(peakLinear, fft->m_bands[i] / fftEnergy); } } - return ( peak + 60 ) / 100; + return peakLinear; } @@ -310,41 +315,41 @@ float EqEffect::peakBand( float minF, float maxF, EqAnalyser *fft, int sr ) void EqEffect::setBandPeaks( EqAnalyser *fft, int samplerate ) { m_eqControls.m_lowShelfPeakR = m_eqControls.m_lowShelfPeakL = - peakBand( m_eqControls.m_lowShelfFreqModel.value() + linearPeakBand( m_eqControls.m_lowShelfFreqModel.value() * ( 1 - m_eqControls.m_lowShelfResModel.value() * 0.5 ), m_eqControls.m_lowShelfFreqModel.value(), fft , samplerate ); m_eqControls.m_para1PeakL = m_eqControls.m_para1PeakR = - peakBand( m_eqControls.m_para1FreqModel.value() + linearPeakBand( m_eqControls.m_para1FreqModel.value() * ( 1 - m_eqControls.m_para1BwModel.value() * 0.5 ), m_eqControls.m_para1FreqModel.value() * ( 1 + m_eqControls.m_para1BwModel.value() * 0.5 ), fft , samplerate ); m_eqControls.m_para2PeakL = m_eqControls.m_para2PeakR = - peakBand( m_eqControls.m_para2FreqModel.value() + linearPeakBand( m_eqControls.m_para2FreqModel.value() * ( 1 - m_eqControls.m_para2BwModel.value() * 0.5 ), m_eqControls.m_para2FreqModel.value() * ( 1 + m_eqControls.m_para2BwModel.value() * 0.5 ), fft , samplerate ); m_eqControls.m_para3PeakL = m_eqControls.m_para3PeakR = - peakBand( m_eqControls.m_para3FreqModel.value() + linearPeakBand( m_eqControls.m_para3FreqModel.value() * ( 1 - m_eqControls.m_para3BwModel.value() * 0.5 ), m_eqControls.m_para3FreqModel.value() * ( 1 + m_eqControls.m_para3BwModel.value() * 0.5 ), fft , samplerate ); m_eqControls.m_para4PeakL = m_eqControls.m_para4PeakR = - peakBand( m_eqControls.m_para4FreqModel.value() + linearPeakBand( m_eqControls.m_para4FreqModel.value() * ( 1 - m_eqControls.m_para4BwModel.value() * 0.5 ), m_eqControls.m_para4FreqModel.value() * ( 1 + m_eqControls.m_para4BwModel.value() * 0.5 ), fft , samplerate ); m_eqControls.m_highShelfPeakL = m_eqControls.m_highShelfPeakR = - peakBand( m_eqControls.m_highShelfFreqModel.value(), + linearPeakBand( m_eqControls.m_highShelfFreqModel.value(), m_eqControls.m_highShelfFreqModel.value() * ( 1 + m_eqControls.m_highShelfResModel.value() * 0.5 ), fft, samplerate ); diff --git a/plugins/Eq/EqEffect.h b/plugins/Eq/EqEffect.h index 9b23b51b57e..7e91ee40142 100644 --- a/plugins/Eq/EqEffect.h +++ b/plugins/Eq/EqEffect.h @@ -87,7 +87,7 @@ class EqEffect : public Effect float m_inGain; float m_outGain; - float peakBand( float minF, float maxF, EqAnalyser *, int ); + float linearPeakBand(float minF, float maxF, EqAnalyser*, int); inline float bandToFreq ( int index , int sampleRate ) {