diff options
-rw-r--r-- | src/engine/enginevumeter.cpp | 30 | ||||
-rw-r--r-- | src/engine/enginevumeter.h | 4 | ||||
-rw-r--r-- | src/sampleutil.cpp | 11 | ||||
-rw-r--r-- | src/sampleutil.h | 6 |
4 files changed, 43 insertions, 8 deletions
diff --git a/src/engine/enginevumeter.cpp b/src/engine/enginevumeter.cpp index 7cbbdf2c6b..4e34d783a3 100644 --- a/src/engine/enginevumeter.cpp +++ b/src/engine/enginevumeter.cpp @@ -33,6 +33,10 @@ EngineVuMeter::EngineVuMeter(QString group) { // knowledge could use something more suitable... m_ctrlPeakIndicator = new ControlPotmeter(ConfigKey(group, "PeakIndicator"), 0., 1.); + m_ctrlPeakIndicatorL = new ControlPotmeter(ConfigKey(group, "PeakIndicatorL"), + 0., 1.); + m_ctrlPeakIndicatorR = new ControlPotmeter(ConfigKey(group, "PeakIndicatorR"), + 0., 1.); m_pSampleRate = new ControlObjectSlave("[Master]", "samplerate", this); @@ -46,6 +50,8 @@ EngineVuMeter::~EngineVuMeter() delete m_ctrlVuMeterL; delete m_ctrlVuMeterR; delete m_ctrlPeakIndicator; + delete m_ctrlPeakIndicatorL; + delete m_ctrlPeakIndicatorR; } void EngineVuMeter::process(CSAMPLE* pIn, const int iBufferSize) { @@ -53,7 +59,7 @@ void EngineVuMeter::process(CSAMPLE* pIn, const int iBufferSize) { int sampleRate = (int)m_pSampleRate->get(); - bool clipped = SampleUtil::sumAbsPerChannel(&fVolSumL, &fVolSumR, pIn, iBufferSize); + int clipped = SampleUtil::sumAbsPerChannel(&fVolSumL, &fVolSumR, pIn, iBufferSize); m_fRMSvolumeSumL += fVolSumL; m_fRMSvolumeSumR += fVolSumR; @@ -93,6 +99,24 @@ void EngineVuMeter::process(CSAMPLE* pIn, const int iBufferSize) { } else { --m_peakDuration; } + + if (clipped & 1) { + m_ctrlPeakIndicatorL->set(1.); + m_peakDurationL = PEAK_DURATION * sampleRate / iBufferSize / 2000; + } else if (m_peakDurationL <= 0) { + m_ctrlPeakIndicatorL->set(0.); + } else { + --m_peakDurationL; + } + + if (clipped & 2) { + m_ctrlPeakIndicatorR->set(1.); + m_peakDurationR = PEAK_DURATION * sampleRate / iBufferSize / 2000; + } else if (m_peakDurationR <= 0) { + m_ctrlPeakIndicatorR->set(0.); + } else { + --m_peakDurationR; + } } void EngineVuMeter::collectFeatures(GroupFeatureState* pGroupFeatures) const { @@ -117,6 +141,8 @@ void EngineVuMeter::reset() { m_ctrlVuMeterL->set(0); m_ctrlVuMeterR->set(0); m_ctrlPeakIndicator->set(0); + m_ctrlPeakIndicatorL->set(0); + m_ctrlPeakIndicatorR->set(0); m_iSamplesCalculated = 0; m_fRMSvolumeL = 0; @@ -124,4 +150,6 @@ void EngineVuMeter::reset() { m_fRMSvolumeR = 0; m_fRMSvolumeSumR = 0; m_peakDuration = 0; + m_peakDurationL = 0; + m_peakDurationR = 0; } diff --git a/src/engine/enginevumeter.h b/src/engine/enginevumeter.h index d56086e560..202069d9cd 100644 --- a/src/engine/enginevumeter.h +++ b/src/engine/enginevumeter.h @@ -56,7 +56,11 @@ class EngineVuMeter : public EngineObject { int m_iSamplesCalculated; ControlPotmeter* m_ctrlPeakIndicator; + ControlPotmeter* m_ctrlPeakIndicatorL; + ControlPotmeter* m_ctrlPeakIndicatorR; int m_peakDuration; + int m_peakDurationL; + int m_peakDurationR; ControlObjectSlave* m_pSampleRate; }; diff --git a/src/sampleutil.cpp b/src/sampleutil.cpp index fa2cc93aad..efa7fcdcdf 100644 --- a/src/sampleutil.cpp +++ b/src/sampleutil.cpp @@ -296,26 +296,27 @@ void SampleUtil::convertS16ToFloat32(CSAMPLE* _RESTRICT pDest, const SAMPLE* _RE } // static -bool SampleUtil::sumAbsPerChannel(CSAMPLE* pfAbsL, CSAMPLE* pfAbsR, +int SampleUtil::sumAbsPerChannel(CSAMPLE* pfAbsL, CSAMPLE* pfAbsR, const CSAMPLE* pBuffer, int iNumSamples) { CSAMPLE fAbsL = CSAMPLE_ZERO; CSAMPLE fAbsR = CSAMPLE_ZERO; - CSAMPLE clipped = 0; + CSAMPLE clippedL = 0; + CSAMPLE clippedR = 0; // note: LOOP VECTORIZED. for (int i = 0; i < iNumSamples / 2; ++i) { CSAMPLE absl = fabs(pBuffer[i * 2]); fAbsL += absl; - clipped += absl > CSAMPLE_PEAK ? 1 : 0; + clippedL += absl > CSAMPLE_PEAK ? 1 : 0; CSAMPLE absr = fabs(pBuffer[i * 2 + 1]); fAbsR += absr; // Replacing the code with a bool clipped will prevent vetorizing - clipped += absr > CSAMPLE_PEAK ? 1 : 0; + clippedR += absr > CSAMPLE_PEAK ? 1 : 0; } *pfAbsL = fAbsL; *pfAbsR = fAbsR; - return (clipped != 0); + return (((clippedR != 0) << 1) | (clippedL != 0)); } // static diff --git a/src/sampleutil.h b/src/sampleutil.h index 627aad81ff..6505d77b8f 100644 --- a/src/sampleutil.h +++ b/src/sampleutil.h @@ -168,8 +168,10 @@ class SampleUtil { // For each pair of samples in pBuffer (l,r) -- stores the sum of the // absolute values of l in pfAbsL, and the sum of the absolute values of r // in pfAbsR. - // returns true in case of clipping > +-1 - static bool sumAbsPerChannel(CSAMPLE* pfAbsL, CSAMPLE* pfAbsR, + // returns >0 in case of clipping (> +-1) + // The returned int is a bitmask: if the first bit is set the L + // channel is clipping, if the second bit is set, the R channel does. + static int sumAbsPerChannel(CSAMPLE* pfAbsL, CSAMPLE* pfAbsR, const CSAMPLE* pBuffer, int iNumSamples); // Copies every sample in pSrc to pDest, limiting the values in pDest |