summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/engine/enginevumeter.cpp30
-rw-r--r--src/engine/enginevumeter.h4
-rw-r--r--src/sampleutil.cpp11
-rw-r--r--src/sampleutil.h6
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