From e73b198f9291437a9cac90b8b9e94363ebbabc52 Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Thu, 18 Jun 2020 19:16:31 +0200 Subject: [PATCH] the local pan middle position is no longer attenuated in Mono-in/Stereo-out mode (#353) --- ChangeLog | 1 + src/client.cpp | 12 +++++++----- src/server.cpp | 4 ++-- src/util.h | 19 +++++++++++++------ 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index f453a3ff..38b29771 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,7 @@ - add a headless build type which does not depend on QtGui/QtWidgets, coded by marcan (#322) +- the local pan middle position is no longer attenuated in Mono-in/Stereo-out mode (#353) diff --git a/src/client.cpp b/src/client.cpp index 35b8fea5..b88ace5a 100755 --- a/src/client.cpp +++ b/src/client.cpp @@ -991,8 +991,8 @@ void CClient::ProcessAudioDataIntern ( CVector& vecsStereoSndCrd ) if ( eAudioChannelConf == CC_STEREO ) { // for stereo only apply pan attenuation on one channel (same as pan in the server) - const double dGainL = std::min ( 0.5, 1 - dPan ) * 2; - const double dGainR = std::min ( 0.5, dPan ) * 2; + const double dGainL = MathUtils::GetLeftPan ( dPan, false ); + const double dGainR = MathUtils::GetRightPan ( dPan, false ); for ( i = 0, j = 0; i < iMonoBlockSizeSam; i++, j += 2 ) { @@ -1004,12 +1004,14 @@ void CClient::ProcessAudioDataIntern ( CVector& vecsStereoSndCrd ) } else { - // for mono implement a cross-fade between channels and mix them - const double dGainL = 1 - dPan; - const double dGainR = dPan; + // for mono implement a cross-fade between channels and mix them, for + // mono-in/stereo-out use no attenuation in pan center + const double dGainL = MathUtils::GetLeftPan ( dPan, eAudioChannelConf != CC_MONO_IN_STEREO_OUT ); + const double dGainR = MathUtils::GetRightPan ( dPan, eAudioChannelConf != CC_MONO_IN_STEREO_OUT ); for ( i = 0, j = 0; i < iMonoBlockSizeSam; i++, j += 2 ) { + // note that we need the Double2Short for stereo pan mode vecsStereoSndCrd[i] = Double2Short ( dGainL * vecsStereoSndCrd[j] + dGainR * vecsStereoSndCrd[j + 1] ); } diff --git a/src/server.cpp b/src/server.cpp index 8c449e8b..0f2aa184 100755 --- a/src/server.cpp +++ b/src/server.cpp @@ -1203,8 +1203,8 @@ void CServer::ProcessData ( const CVector >& vecvecsData, // calculate combined gain/pan for each stereo channel where we define // the panning that center equals full gain for both channels - const double dGainL = std::min ( 0.5, 1 - dPan ) * 2 * dGain; - const double dGainR = std::min ( 0.5, dPan ) * 2 * dGain; + const double dGainL = MathUtils::GetLeftPan ( dPan, false ) * dGain; + const double dGainR = MathUtils::GetRightPan ( dPan, false ) * dGain; // if channel gain is 1, avoid multiplication for speed optimization if ( ( dGainL == static_cast ( 1.0 ) ) && ( dGainR == static_cast ( 1.0 ) ) ) diff --git a/src/util.h b/src/util.h index 9118f617..ee70d662 100755 --- a/src/util.h +++ b/src/util.h @@ -508,8 +508,6 @@ private: /******************************************************************************\ * Other Classes/Enums * \******************************************************************************/ - - // Audio channel configuration ------------------------------------------------- enum EAudChanConf { @@ -1199,13 +1197,11 @@ public: // different IIR weights for up and down direction if ( dNewValue < dOldValue ) { - dOldValue = - dOldValue * dWeightDown + ( 1.0 - dWeightDown ) * dNewValue; + dOldValue = dOldValue * dWeightDown + ( 1.0 - dWeightDown ) * dNewValue; } else { - dOldValue = - dOldValue * dWeightUp + ( 1.0 - dWeightUp ) * dNewValue; + dOldValue = dOldValue * dWeightUp + ( 1.0 - dWeightUp ) * dNewValue; } } @@ -1223,6 +1219,17 @@ public: return round ( dValue + dHysteresis ); } } + + // calculate pan gains: in cross fade mode the pan center is attenuated + // by 6 dB, otherwise the center equals full gain for both channels + static inline double GetLeftPan ( const double dPan, const bool bXFade) + { + return bXFade ? 1 - dPan : std::min ( 0.5, 1 - dPan ) * 2; + } + static inline double GetRightPan ( const double dPan, const bool bXFade) + { + return bXFade ? dPan : std::min ( 0.5, dPan ) * 2; + } };