clip indicator improvements (do not show clipping too early)

This commit is contained in:
Volker Fischer 2020-06-23 19:51:53 +02:00
parent 68a9fc7c7e
commit 04bb03c2f4
6 changed files with 27 additions and 24 deletions

View file

@ -210,7 +210,7 @@ public slots:
void OnMuteStateHasChangedReceived ( int iChanID, bool bIsMuted ) void OnMuteStateHasChangedReceived ( int iChanID, bool bIsMuted )
{ MainMixerBoard->SetRemoteFaderIsMute ( iChanID, bIsMuted ); } { MainMixerBoard->SetRemoteFaderIsMute ( iChanID, bIsMuted ); }
void OnCLChannelLevelListReceived ( CHostAddress /* unused */, void OnCLChannelLevelListReceived ( CHostAddress /* unused */,
CVector<uint16_t> vecLevelList ) CVector<uint16_t> vecLevelList )
{ MainMixerBoard->SetChannelLevels ( vecLevelList ); } { MainMixerBoard->SetChannelLevels ( vecLevelList ); }

View file

@ -178,8 +178,12 @@ void CLevelMeter::SetValue ( const double dValue )
} }
} }
// clip LED management // clip LED management (note that in case of clipping, i.e. full
if ( dValue > LEV_METER_CLIP_LIMIT_RATIO * NUM_STEPS_LED_BAR) // scale level, the value is above NUM_STEPS_LED_BAR since the minimum
// value of int16 is -32768 but we normalize with 32767 -> therefore
// we really only show the clipping indicator, if actually the largest
// value of int16 is used)
if ( dValue > NUM_STEPS_LED_BAR )
{ {
vecpLEDs[NUM_STEPS_LED_BAR]->SetColor ( cLED::RL_RED ); vecpLEDs[NUM_STEPS_LED_BAR]->SetColor ( cLED::RL_RED );
TimerClip.start(); TimerClip.start();

View file

@ -35,9 +35,8 @@
/* Definitions ****************************************************************/ /* Definitions ****************************************************************/
#define LEV_METER_CLIP_LIMIT_RATIO 0.99 #define NUM_LEDS_INCL_CLIP_LED ( NUM_STEPS_LED_BAR + 1 )
#define NUM_LEDS_INCL_CLIP_LED ( NUM_STEPS_LED_BAR + 1 ) #define CLIP_IND_TIME_OUT_MS 20000
#define CLIP_IND_TIME_OUT_MS 20000
/* Classes ********************************************************************/ /* Classes ********************************************************************/

View file

@ -1681,8 +1681,8 @@ bool CServer::CreateLevelsForAllConChannels ( const int i
const CVector<int16_t>& vecsData = vecvecsData[j]; const CVector<int16_t>& vecsData = vecvecsData[j];
// Speed optimization: // Speed optimization:
// - we only make use of the positive values and ignore the negative ones // - we only make use of the negative values and ignore the positive ones (since
// -> we do not need to call the fabs() function // int16 has range {-32768, 32767}) -> we do not need to call the fabs() function
// - we only evaluate every third sample // - we only evaluate every third sample
int16_t sMax = 0; int16_t sMax = 0;
@ -1691,7 +1691,7 @@ bool CServer::CreateLevelsForAllConChannels ( const int i
// mono // mono
for ( i = 0; i < iServerFrameSizeSamples; i += 3 ) for ( i = 0; i < iServerFrameSizeSamples; i += 3 )
{ {
sMax = std::max ( sMax, vecsData[i] ); sMax = std::min ( sMax, vecsData[i] );
} }
} }
else else
@ -1700,14 +1700,14 @@ bool CServer::CreateLevelsForAllConChannels ( const int i
for ( i = 0, k = 0; i < iServerFrameSizeSamples; i += 3, k += 6 ) // 2 * 3 = 6 -> stereo for ( i = 0, k = 0; i < iServerFrameSizeSamples; i += 3, k += 6 ) // 2 * 3 = 6 -> stereo
{ {
// left/right channels separately // left/right channels separately
sMax = std::max ( sMax, vecsData[k] ); sMax = std::min ( sMax, vecsData[k] );
sMax = std::max ( sMax, vecsData[k + 1] ); sMax = std::min ( sMax, vecsData[k + 1] );
} }
} }
// smoothing // smoothing
const int iChId = vecChanIDsCurConChan[j]; const int iChId = vecChanIDsCurConChan[j];
const double dCurLevel = std::max ( static_cast<double> ( sMax ), vecChannels[iChId].GetPrevLevel() * 0.5 ); const double dCurLevel = std::max ( -static_cast<double> ( sMax ), vecChannels[iChId].GetPrevLevel() * 0.5 );
vecChannels[iChId].SetPrevLevel ( dCurLevel ); vecChannels[iChId].SetPrevLevel ( dCurLevel );
// logarithmic measure // logarithmic measure

View file

@ -36,8 +36,8 @@ void CStereoSignalLevelMeter::Update ( const CVector<short>& vecsAudio )
// Get maximum of current block // Get maximum of current block
// //
// Speed optimization: // Speed optimization:
// - we only make use of the positive values and ignore the negative ones // - we only make use of the negative values and ignore the positive ones (since
// -> we do not need to call the fabs() function // int16 has range {-32768, 32767}) -> we do not need to call the fabs() function
// - we only evaluate every third sample // - we only evaluate every third sample
// //
// With these speed optimizations we might loose some information in // With these speed optimizations we might loose some information in
@ -50,18 +50,18 @@ void CStereoSignalLevelMeter::Update ( const CVector<short>& vecsAudio )
for ( int i = 0; i < iStereoVecSize; i += 6 ) // 2 * 3 = 6 -> stereo for ( int i = 0; i < iStereoVecSize; i += 6 ) // 2 * 3 = 6 -> stereo
{ {
// left channel // left channel
sMaxL = std::max ( sMaxL, vecsAudio[i] ); sMaxL = std::min ( sMaxL, vecsAudio[i] );
// right channel // right channel
sMaxR = std::max ( sMaxR, vecsAudio[i + 1] ); sMaxR = std::min ( sMaxR, vecsAudio[i + 1] );
} }
dCurLevelL = UpdateCurLevel ( dCurLevelL, sMaxL ); dCurLevelL = UpdateCurLevel ( dCurLevelL, -sMaxL );
dCurLevelR = UpdateCurLevel ( dCurLevelR, sMaxR ); dCurLevelR = UpdateCurLevel ( dCurLevelR, -sMaxR );
} }
double CStereoSignalLevelMeter::UpdateCurLevel ( double dCurLevel, double CStereoSignalLevelMeter::UpdateCurLevel ( double dCurLevel,
const short& sMax ) double dMax )
{ {
// decrease max with time // decrease max with time
if ( dCurLevel >= METER_FLY_BACK ) if ( dCurLevel >= METER_FLY_BACK )
@ -77,9 +77,9 @@ double CStereoSignalLevelMeter::UpdateCurLevel ( double dCurLevel,
} }
// update current level -> only use maximum // update current level -> only use maximum
if ( static_cast<double> ( sMax ) > dCurLevel ) if ( dMax > dCurLevel )
{ {
return static_cast<double> ( sMax ); return dMax;
} }
else else
{ {

View file

@ -726,8 +726,8 @@ public:
} }
protected: protected:
double UpdateCurLevel ( double dCurLevel, double UpdateCurLevel ( double dCurLevel,
const short& sMax ); double dMax );
double dCurLevelL; double dCurLevelL;
double dCurLevelR; double dCurLevelR;