Merge pull request #42 from pljones/feature/channel-meters
Feature/channel meters
|
@ -34,17 +34,29 @@ CChannelFader::CChannelFader ( QWidget* pNW,
|
||||||
// create new GUI control objects and store pointers to them (note that
|
// create new GUI control objects and store pointers to them (note that
|
||||||
// QWidget takes the ownership of the pMainGrid so that this only has
|
// QWidget takes the ownership of the pMainGrid so that this only has
|
||||||
// to be created locally in this constructor)
|
// to be created locally in this constructor)
|
||||||
pFrame = new QFrame ( pNW );
|
pFrame = new QFrame ( pNW );
|
||||||
QVBoxLayout* pMainGrid = new QVBoxLayout ( pFrame );
|
|
||||||
pFader = new QSlider ( Qt::Vertical, pFrame );
|
pLevelsBox = new QWidget ( pFrame );
|
||||||
pcbMute = new QCheckBox ( "Mute", pFrame );
|
plbrChannelLevel = new CMultiColorLEDBar ( pLevelsBox );
|
||||||
pcbSolo = new QCheckBox ( "Solo", pFrame );
|
pFader = new QSlider ( Qt::Vertical, pLevelsBox );
|
||||||
pLabelInstBox = new QGroupBox ( pFrame );
|
|
||||||
plblLabel = new QLabel ( "", pFrame );
|
pMuteSoloBox = new QWidget ( pFrame );
|
||||||
plblInstrument = new QLabel ( pFrame );
|
pcbMute = new QCheckBox ( "Mute", pMuteSoloBox );
|
||||||
plblCountryFlag = new QLabel ( pFrame );
|
pcbSolo = new QCheckBox ( "Solo", pMuteSoloBox );
|
||||||
QHBoxLayout* pLabelGrid = new QHBoxLayout ( pLabelInstBox );
|
|
||||||
QVBoxLayout* pLabelPictGrid = new QVBoxLayout();
|
pLabelInstBox = new QGroupBox ( pFrame );
|
||||||
|
plblLabel = new QLabel ( "", pFrame );
|
||||||
|
plblInstrument = new QLabel ( pFrame );
|
||||||
|
plblCountryFlag = new QLabel ( pFrame );
|
||||||
|
|
||||||
|
QVBoxLayout* pMainGrid = new QVBoxLayout ( pFrame );
|
||||||
|
QHBoxLayout* pLevelsGrid = new QHBoxLayout ( pLevelsBox );
|
||||||
|
QVBoxLayout* pMuteSoloGrid = new QVBoxLayout ( pMuteSoloBox );
|
||||||
|
QHBoxLayout* pLabelGrid = new QHBoxLayout ( pLabelInstBox );
|
||||||
|
QVBoxLayout* pLabelPictGrid = new QVBoxLayout ( );
|
||||||
|
|
||||||
|
// setup channel level
|
||||||
|
plbrChannelLevel->setContentsMargins( 0, 3, 2, 3 );
|
||||||
|
|
||||||
// setup slider
|
// setup slider
|
||||||
pFader->setPageStep ( 1 );
|
pFader->setPageStep ( 1 );
|
||||||
|
@ -62,18 +74,30 @@ CChannelFader::CChannelFader ( QWidget* pNW,
|
||||||
|
|
||||||
// set margins of the layouts to zero to get maximum space for the controls
|
// set margins of the layouts to zero to get maximum space for the controls
|
||||||
pMainGrid->setContentsMargins ( 0, 0, 0, 0 );
|
pMainGrid->setContentsMargins ( 0, 0, 0, 0 );
|
||||||
|
|
||||||
|
pLevelsGrid->setContentsMargins ( 0, 0, 0, 0 );
|
||||||
|
pLevelsGrid->setSpacing ( 0 ); // only minimal space
|
||||||
|
|
||||||
|
pMuteSoloGrid->setContentsMargins ( 0, 0, 0, 0 );
|
||||||
|
|
||||||
pLabelGrid->setContentsMargins ( 0, 0, 0, 0 );
|
pLabelGrid->setContentsMargins ( 0, 0, 0, 0 );
|
||||||
pLabelGrid->setSpacing ( 2 ); // only minimal space between picture and text
|
pLabelGrid->setSpacing ( 2 ); // only minimal space between picture and text
|
||||||
|
|
||||||
// add user controls to the grids
|
// add user controls to the grids
|
||||||
pLabelPictGrid->addWidget ( plblCountryFlag, 0, Qt::AlignHCenter );
|
pLabelPictGrid->addWidget ( plblCountryFlag, 0, Qt::AlignHCenter );
|
||||||
pLabelPictGrid->addWidget ( plblInstrument, 0, Qt::AlignHCenter );
|
pLabelPictGrid->addWidget ( plblInstrument, 0, Qt::AlignHCenter );
|
||||||
|
|
||||||
pLabelGrid->addLayout ( pLabelPictGrid );
|
pLabelGrid->addLayout ( pLabelPictGrid );
|
||||||
pLabelGrid->addWidget ( plblLabel, 0, Qt::AlignVCenter );
|
pLabelGrid->addWidget ( plblLabel, 0, Qt::AlignVCenter );
|
||||||
|
|
||||||
pMainGrid->addWidget ( pFader, 0, Qt::AlignHCenter );
|
pLevelsGrid->addWidget ( plbrChannelLevel, 0, Qt::AlignRight );
|
||||||
pMainGrid->addWidget ( pcbMute, 0, Qt::AlignLeft );
|
pLevelsGrid->addWidget ( pFader, 0, Qt::AlignLeft );
|
||||||
pMainGrid->addWidget ( pcbSolo, 0, Qt::AlignLeft );
|
|
||||||
|
pMuteSoloGrid->addWidget ( pcbMute, 0, Qt::AlignLeft );
|
||||||
|
pMuteSoloGrid->addWidget ( pcbSolo, 0, Qt::AlignLeft );
|
||||||
|
|
||||||
|
pMainGrid->addWidget ( pLevelsBox, 0, Qt::AlignHCenter );
|
||||||
|
pMainGrid->addWidget ( pMuteSoloBox, 0, Qt::AlignHCenter );
|
||||||
pMainGrid->addWidget ( pLabelInstBox );
|
pMainGrid->addWidget ( pLabelInstBox );
|
||||||
|
|
||||||
// add fader frame to audio mixer board layout
|
// add fader frame to audio mixer board layout
|
||||||
|
@ -83,17 +107,23 @@ CChannelFader::CChannelFader ( QWidget* pNW,
|
||||||
Reset();
|
Reset();
|
||||||
|
|
||||||
// add help text to controls
|
// add help text to controls
|
||||||
|
plbrChannelLevel->setWhatsThis ( tr ( "<b>Channel Level:</b> Displays the "
|
||||||
|
"pre-fader audio level of this channel. All connected clients at the "
|
||||||
|
"server will be assigned an audio level, the same value for each client." ) );
|
||||||
|
plbrChannelLevel->setAccessibleName ( tr ( "Input level of the current audio "
|
||||||
|
"channel at the server" ) );
|
||||||
|
|
||||||
pFader->setWhatsThis ( tr ( "<b>Mixer Fader:</b> Adjusts the audio level of "
|
pFader->setWhatsThis ( tr ( "<b>Mixer Fader:</b> Adjusts the audio level of "
|
||||||
"this channel. All connected clients at the server will be assigned "
|
"this channel. All connected clients at the server will be assigned "
|
||||||
"an audio fader at each client." ) );
|
"an audio fader at each client, adjusting the local mix." ) );
|
||||||
pFader->setAccessibleName ( tr ( "Mixer level setting of the connected client "
|
pFader->setAccessibleName ( tr ( "Local mix level setting of the current audio "
|
||||||
"at the server" ) );
|
"channel at the server" ) );
|
||||||
|
|
||||||
pcbMute->setWhatsThis ( tr ( "<b>Mute:</b> With the Mute checkbox, the current "
|
pcbMute->setWhatsThis ( tr ( "<b>Mute:</b> With the Mute checkbox, the "
|
||||||
"audio channel can be muted." ) );
|
"audio channel can be muted." ) );
|
||||||
pcbMute->setAccessibleName ( tr ( "Mute button" ) );
|
pcbMute->setAccessibleName ( tr ( "Mute button" ) );
|
||||||
|
|
||||||
pcbSolo->setWhatsThis ( tr ( "<b>Solo:</b> With the Solo checkbox, the current "
|
pcbSolo->setWhatsThis ( tr ( "<b>Solo:</b> With the Solo checkbox, the "
|
||||||
"audio channel can be set to solo which means that all other channels "
|
"audio channel can be set to solo which means that all other channels "
|
||||||
"except of the current channel are muted. It is possible to set more than "
|
"except of the current channel are muted. It is possible to set more than "
|
||||||
"one channel to solo." ) );
|
"one channel to solo." ) );
|
||||||
|
@ -158,6 +188,11 @@ void CChannelFader::SetGUIDesign ( const EGUIDesign eNewDesign )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CChannelFader::SetDisplayChannelLevel ( const bool eNDCL )
|
||||||
|
{
|
||||||
|
plbrChannelLevel->setHidden( !eNDCL );
|
||||||
|
}
|
||||||
|
|
||||||
void CChannelFader::SetupFaderTag ( const ESkillLevel eSkillLevel )
|
void CChannelFader::SetupFaderTag ( const ESkillLevel eSkillLevel )
|
||||||
{
|
{
|
||||||
// setup group box for label/instrument picture: set a thick black border
|
// setup group box for label/instrument picture: set a thick black border
|
||||||
|
@ -306,6 +341,11 @@ void CChannelFader::UpdateSoloState ( const bool bNewOtherSoloState )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CChannelFader::SetChannelLevel ( const uint16_t iLevel )
|
||||||
|
{
|
||||||
|
plbrChannelLevel->setValue ( iLevel );
|
||||||
|
}
|
||||||
|
|
||||||
void CChannelFader::SetText ( const CChannelInfo& ChanInfo )
|
void CChannelFader::SetText ( const CChannelInfo& ChanInfo )
|
||||||
{
|
{
|
||||||
// store original received name
|
// store original received name
|
||||||
|
@ -634,6 +674,17 @@ void CAudioMixerBoard::SetGUIDesign ( const EGUIDesign eNewDesign )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CAudioMixerBoard::SetDisplayChannelLevels ( const bool eNDCL )
|
||||||
|
{
|
||||||
|
bDisplayChannelLevels = eNDCL;
|
||||||
|
|
||||||
|
// apply preference to child GUI controls
|
||||||
|
for ( int i = 0; i < MAX_NUM_CHANNELS; i++ )
|
||||||
|
{
|
||||||
|
vecpChanFader[i]->SetDisplayChannelLevel ( bDisplayChannelLevels );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CAudioMixerBoard::HideAll()
|
void CAudioMixerBoard::HideAll()
|
||||||
{
|
{
|
||||||
// make all controls invisible
|
// make all controls invisible
|
||||||
|
@ -710,6 +761,9 @@ void CAudioMixerBoard::ApplyNewConClientList ( CVector<CChannelInfo>& vecChanInf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// At some future time a new level will arrive -- ???
|
||||||
|
vecpChanFader[i]->SetChannelLevel ( 0 );
|
||||||
|
|
||||||
// set the text in the fader
|
// set the text in the fader
|
||||||
vecpChanFader[i]->SetText ( vecChanInfo[j] );
|
vecpChanFader[i]->SetText ( vecChanInfo[j] );
|
||||||
|
|
||||||
|
@ -857,3 +911,17 @@ bool CAudioMixerBoard::GetStoredFaderSettings ( const CChannelInfo& ChanInfo,
|
||||||
// return "not OK" since we did not find matching fader settings
|
// return "not OK" since we did not find matching fader settings
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CAudioMixerBoard::SetChannelLevels ( const CVector<uint16_t>& vecChannelLevel )
|
||||||
|
{
|
||||||
|
const int iNumChannelLevels = vecChannelLevel.Size();
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for ( int iChId = 0; iChId < MAX_NUM_CHANNELS; iChId++ )
|
||||||
|
{
|
||||||
|
if ( vecpChanFader[iChId]->IsVisible() && i < iNumChannelLevels )
|
||||||
|
{
|
||||||
|
vecpChanFader[iChId]->SetChannelLevel ( vecChannelLevel[i++] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include <QHostAddress>
|
#include <QHostAddress>
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "multicolorledbar.h"
|
||||||
|
|
||||||
|
|
||||||
/* Classes ********************************************************************/
|
/* Classes ********************************************************************/
|
||||||
|
@ -55,6 +56,7 @@ public:
|
||||||
bool IsSolo() { return pcbSolo->isChecked(); }
|
bool IsSolo() { return pcbSolo->isChecked(); }
|
||||||
bool IsMute() { return pcbMute->isChecked(); }
|
bool IsMute() { return pcbMute->isChecked(); }
|
||||||
void SetGUIDesign ( const EGUIDesign eNewDesign );
|
void SetGUIDesign ( const EGUIDesign eNewDesign );
|
||||||
|
void SetDisplayChannelLevel ( const bool eNDCL );
|
||||||
|
|
||||||
void UpdateSoloState ( const bool bNewOtherSoloState );
|
void UpdateSoloState ( const bool bNewOtherSoloState );
|
||||||
void SetFaderLevel ( const int iLevel );
|
void SetFaderLevel ( const int iLevel );
|
||||||
|
@ -62,6 +64,7 @@ public:
|
||||||
void SetFaderIsMute ( const bool bIsMute );
|
void SetFaderIsMute ( const bool bIsMute );
|
||||||
int GetFaderLevel() { return pFader->value(); }
|
int GetFaderLevel() { return pFader->value(); }
|
||||||
void Reset();
|
void Reset();
|
||||||
|
void SetChannelLevel ( const uint16_t iLevel );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
double CalcFaderGain ( const int value );
|
double CalcFaderGain ( const int value );
|
||||||
|
@ -69,18 +72,24 @@ protected:
|
||||||
void SendFaderLevelToServer ( const int iLevel );
|
void SendFaderLevelToServer ( const int iLevel );
|
||||||
void SetupFaderTag ( const ESkillLevel eSkillLevel );
|
void SetupFaderTag ( const ESkillLevel eSkillLevel );
|
||||||
|
|
||||||
QFrame* pFrame;
|
QFrame* pFrame;
|
||||||
QGroupBox* pLabelInstBox;
|
|
||||||
QSlider* pFader;
|
|
||||||
QCheckBox* pcbMute;
|
|
||||||
QCheckBox* pcbSolo;
|
|
||||||
QLabel* plblLabel;
|
|
||||||
QLabel* plblInstrument;
|
|
||||||
QLabel* plblCountryFlag;
|
|
||||||
|
|
||||||
QString strReceivedName;
|
QWidget* pLevelsBox;
|
||||||
|
QWidget* pMuteSoloBox;
|
||||||
|
CMultiColorLEDBar* plbrChannelLevel;
|
||||||
|
QSlider* pFader;
|
||||||
|
|
||||||
bool bOtherChannelIsSolo;
|
QCheckBox* pcbMute;
|
||||||
|
QCheckBox* pcbSolo;
|
||||||
|
|
||||||
|
QGroupBox* pLabelInstBox;
|
||||||
|
QLabel* plblLabel;
|
||||||
|
QLabel* plblInstrument;
|
||||||
|
QLabel* plblCountryFlag;
|
||||||
|
|
||||||
|
QString strReceivedName;
|
||||||
|
|
||||||
|
bool bOtherChannelIsSolo;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void OnLevelValueChanged ( int value ) { SendFaderLevelToServer ( value ); }
|
void OnLevelValueChanged ( int value ) { SendFaderLevelToServer ( value ); }
|
||||||
|
@ -103,10 +112,13 @@ public:
|
||||||
void ApplyNewConClientList ( CVector<CChannelInfo>& vecChanInfo );
|
void ApplyNewConClientList ( CVector<CChannelInfo>& vecChanInfo );
|
||||||
void SetServerName ( const QString& strNewServerName );
|
void SetServerName ( const QString& strNewServerName );
|
||||||
void SetGUIDesign ( const EGUIDesign eNewDesign );
|
void SetGUIDesign ( const EGUIDesign eNewDesign );
|
||||||
|
void SetDisplayChannelLevels ( const bool eNDCL );
|
||||||
|
|
||||||
void SetFaderLevel ( const int iChannelIdx,
|
void SetFaderLevel ( const int iChannelIdx,
|
||||||
const int iValue );
|
const int iValue );
|
||||||
|
|
||||||
|
void SetChannelLevels ( const CVector<uint16_t>& vecChannelLevel );
|
||||||
|
|
||||||
// settings
|
// settings
|
||||||
CVector<QString> vecStoredFaderTags;
|
CVector<QString> vecStoredFaderTags;
|
||||||
CVector<int> vecStoredFaderLevels;
|
CVector<int> vecStoredFaderLevels;
|
||||||
|
@ -129,6 +141,7 @@ protected:
|
||||||
CVector<CChannelFader*> vecpChanFader;
|
CVector<CChannelFader*> vecpChanFader;
|
||||||
QGroupBox* pGroupBox;
|
QGroupBox* pGroupBox;
|
||||||
QHBoxLayout* pMainLayout;
|
QHBoxLayout* pMainLayout;
|
||||||
|
bool bDisplayChannelLevels;
|
||||||
bool bNoFaderVisible;
|
bool bNoFaderVisible;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
|
@ -102,6 +102,10 @@ qRegisterMetaType<CHostAddress> ( "CHostAddress" );
|
||||||
QObject::connect( &Protocol,
|
QObject::connect( &Protocol,
|
||||||
SIGNAL ( LicenceRequired ( ELicenceType ) ),
|
SIGNAL ( LicenceRequired ( ELicenceType ) ),
|
||||||
SIGNAL ( LicenceRequired ( ELicenceType ) ) );
|
SIGNAL ( LicenceRequired ( ELicenceType ) ) );
|
||||||
|
|
||||||
|
QObject::connect ( &Protocol,
|
||||||
|
SIGNAL ( ReqChannelLevelList ( bool ) ),
|
||||||
|
this, SLOT ( OnReqChannelLevelList ( bool ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CChannel::ProtocolIsEnabled()
|
bool CChannel::ProtocolIsEnabled()
|
||||||
|
|
|
@ -159,12 +159,18 @@ public:
|
||||||
void CreateReqConnClientsList() { Protocol.CreateReqConnClientsList(); }
|
void CreateReqConnClientsList() { Protocol.CreateReqConnClientsList(); }
|
||||||
void CreateChatTextMes ( const QString& strChatText ) { Protocol.CreateChatTextMes ( strChatText ); }
|
void CreateChatTextMes ( const QString& strChatText ) { Protocol.CreateChatTextMes ( strChatText ); }
|
||||||
void CreateLicReqMes ( const ELicenceType eLicenceType ) { Protocol.CreateLicenceRequiredMes ( eLicenceType ); }
|
void CreateLicReqMes ( const ELicenceType eLicenceType ) { Protocol.CreateLicenceRequiredMes ( eLicenceType ); }
|
||||||
|
void CreateReqChannelLevelListMes ( bool bOptIn ) { Protocol.CreateReqChannelLevelListMes ( bOptIn ); }
|
||||||
|
|
||||||
void CreateConClientListMes ( const CVector<CChannelInfo>& vecChanInfo )
|
void CreateConClientListMes ( const CVector<CChannelInfo>& vecChanInfo )
|
||||||
{ Protocol.CreateConClientListMes ( vecChanInfo ); }
|
{ Protocol.CreateConClientListMes ( vecChanInfo ); }
|
||||||
|
|
||||||
CNetworkTransportProps GetNetworkTransportPropsFromCurrentSettings();
|
CNetworkTransportProps GetNetworkTransportPropsFromCurrentSettings();
|
||||||
|
|
||||||
|
bool ChannelLevelsRequired() const { return bChannelLevelsRequired; }
|
||||||
|
|
||||||
|
double GetPrevLevel() const { return dPrevLevel; }
|
||||||
|
void SetPrevLevel ( const double nPL ) { dPrevLevel = nPL; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool ProtocolIsEnabled();
|
bool ProtocolIsEnabled();
|
||||||
|
|
||||||
|
@ -177,6 +183,8 @@ protected:
|
||||||
iNetwFrameSizeFact = FRAME_SIZE_FACTOR_PREFERRED;
|
iNetwFrameSizeFact = FRAME_SIZE_FACTOR_PREFERRED;
|
||||||
iNetwFrameSize = CELT_MINIMUM_NUM_BYTES;
|
iNetwFrameSize = CELT_MINIMUM_NUM_BYTES;
|
||||||
iNumAudioChannels = 1; // mono
|
iNumAudioChannels = 1; // mono
|
||||||
|
|
||||||
|
dPrevLevel = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// connection parameters
|
// connection parameters
|
||||||
|
@ -216,6 +224,9 @@ protected:
|
||||||
QMutex MutexSocketBuf;
|
QMutex MutexSocketBuf;
|
||||||
QMutex MutexConvBuf;
|
QMutex MutexConvBuf;
|
||||||
|
|
||||||
|
bool bChannelLevelsRequired;
|
||||||
|
double dPrevLevel;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void OnSendProtMessage ( CVector<uint8_t> vecMessage );
|
void OnSendProtMessage ( CVector<uint8_t> vecMessage );
|
||||||
void OnJittBufSizeChange ( int iNewJitBufSize );
|
void OnJittBufSizeChange ( int iNewJitBufSize );
|
||||||
|
@ -249,6 +260,8 @@ public slots:
|
||||||
|
|
||||||
void OnNewConnection() { emit NewConnection(); }
|
void OnNewConnection() { emit NewConnection(); }
|
||||||
|
|
||||||
|
void OnReqChannelLevelList ( bool bOptIn ) { bChannelLevelsRequired = bOptIn; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void MessReadyForSending ( CVector<uint8_t> vecMessage );
|
void MessReadyForSending ( CVector<uint8_t> vecMessage );
|
||||||
void NewConnection();
|
void NewConnection();
|
||||||
|
|
|
@ -65,6 +65,7 @@ CClient::CClient ( const quint16 iPortNumber,
|
||||||
bFraSiFactDefSupported ( false ),
|
bFraSiFactDefSupported ( false ),
|
||||||
bFraSiFactSafeSupported ( false ),
|
bFraSiFactSafeSupported ( false ),
|
||||||
eGUIDesign ( GD_ORIGINAL ),
|
eGUIDesign ( GD_ORIGINAL ),
|
||||||
|
bDisplayChannelLevels ( true ),
|
||||||
bJitterBufferOK ( true ),
|
bJitterBufferOK ( true ),
|
||||||
strCentralServerAddress ( "" ),
|
strCentralServerAddress ( "" ),
|
||||||
bUseDefaultCentralServerAddress ( true ),
|
bUseDefaultCentralServerAddress ( true ),
|
||||||
|
@ -191,6 +192,10 @@ CClient::CClient ( const quint16 iPortNumber,
|
||||||
SIGNAL ( CLVersionAndOSReceived ( CHostAddress, COSUtil::EOpSystemType, QString ) ) );
|
SIGNAL ( CLVersionAndOSReceived ( CHostAddress, COSUtil::EOpSystemType, QString ) ) );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QObject::connect ( &ConnLessProtocol,
|
||||||
|
SIGNAL ( CLChannelLevelListReceived ( CHostAddress, CVector<uint16_t> ) ),
|
||||||
|
this, SLOT ( OnCLChannelLevelListReceived ( CHostAddress, CVector<uint16_t> ) ) );
|
||||||
|
|
||||||
// other
|
// other
|
||||||
QObject::connect ( &Sound, SIGNAL ( ReinitRequest ( int ) ),
|
QObject::connect ( &Sound, SIGNAL ( ReinitRequest ( int ) ),
|
||||||
this, SLOT ( OnSndCrdReinitRequest ( int ) ) );
|
this, SLOT ( OnSndCrdReinitRequest ( int ) ) );
|
||||||
|
@ -279,6 +284,9 @@ void CClient::OnNewConnection()
|
||||||
// Same problem is with the jitter buffer message.
|
// Same problem is with the jitter buffer message.
|
||||||
Channel.CreateReqConnClientsList();
|
Channel.CreateReqConnClientsList();
|
||||||
CreateServerJitterBufferMessage();
|
CreateServerJitterBufferMessage();
|
||||||
|
|
||||||
|
// send opt-in / out for Channel Level updates
|
||||||
|
Channel.CreateReqChannelLevelListMes ( bDisplayChannelLevels );
|
||||||
}
|
}
|
||||||
|
|
||||||
void CClient::CreateServerJitterBufferMessage()
|
void CClient::CreateServerJitterBufferMessage()
|
||||||
|
@ -387,6 +395,14 @@ bool CClient::GetAndResetbJitterBufferOKFlag()
|
||||||
return bSocketJitBufOKFlag;
|
return bSocketJitBufOKFlag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CClient::SetDisplayChannelLevels ( const bool bNDCL )
|
||||||
|
{
|
||||||
|
bDisplayChannelLevels = bNDCL;
|
||||||
|
|
||||||
|
// tell any connected server about the change
|
||||||
|
Channel.CreateReqChannelLevelListMes ( bDisplayChannelLevels );
|
||||||
|
}
|
||||||
|
|
||||||
void CClient::SetSndCrdPrefFrameSizeFactor ( const int iNewFactor )
|
void CClient::SetSndCrdPrefFrameSizeFactor ( const int iNewFactor )
|
||||||
{
|
{
|
||||||
// first check new input parameter
|
// first check new input parameter
|
||||||
|
@ -598,6 +614,12 @@ void CClient::OnSndCrdReinitRequest ( int iSndCrdResetType )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CClient::OnCLChannelLevelListReceived ( CHostAddress InetAddr,
|
||||||
|
CVector<uint16_t> vecLevelList )
|
||||||
|
{
|
||||||
|
emit CLChannelLevelListReceived ( InetAddr, vecLevelList );
|
||||||
|
}
|
||||||
|
|
||||||
void CClient::Start()
|
void CClient::Start()
|
||||||
{
|
{
|
||||||
// always use the OPUS codec
|
// always use the OPUS codec
|
||||||
|
|
10
src/client.h
|
@ -128,6 +128,9 @@ public:
|
||||||
EGUIDesign GetGUIDesign() const { return eGUIDesign; }
|
EGUIDesign GetGUIDesign() const { return eGUIDesign; }
|
||||||
void SetGUIDesign ( const EGUIDesign eNGD ) { eGUIDesign = eNGD; }
|
void SetGUIDesign ( const EGUIDesign eNGD ) { eGUIDesign = eNGD; }
|
||||||
|
|
||||||
|
bool GetDisplayChannelLevels() const { return bDisplayChannelLevels; }
|
||||||
|
void SetDisplayChannelLevels ( const bool bNDCL );
|
||||||
|
|
||||||
EAudioQuality GetAudioQuality() const { return eAudioQuality; }
|
EAudioQuality GetAudioQuality() const { return eAudioQuality; }
|
||||||
void SetAudioQuality ( const EAudioQuality eNAudioQuality );
|
void SetAudioQuality ( const EAudioQuality eNAudioQuality );
|
||||||
|
|
||||||
|
@ -359,6 +362,7 @@ protected:
|
||||||
int iStereoBlockSizeSam;
|
int iStereoBlockSizeSam;
|
||||||
|
|
||||||
EGUIDesign eGUIDesign;
|
EGUIDesign eGUIDesign;
|
||||||
|
bool bDisplayChannelLevels;
|
||||||
|
|
||||||
bool bJitterBufferOK;
|
bool bJitterBufferOK;
|
||||||
|
|
||||||
|
@ -398,6 +402,9 @@ public slots:
|
||||||
|
|
||||||
void OnSndCrdReinitRequest ( int iSndCrdResetType );
|
void OnSndCrdReinitRequest ( int iSndCrdResetType );
|
||||||
|
|
||||||
|
void OnCLChannelLevelListReceived ( CHostAddress InetAddr,
|
||||||
|
CVector<uint16_t> vecLevelList );
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void ConClientListMesReceived ( CVector<CChannelInfo> vecChanInfo );
|
void ConClientListMesReceived ( CVector<CChannelInfo> vecChanInfo );
|
||||||
void ChatTextReceived ( QString strChatText );
|
void ChatTextReceived ( QString strChatText );
|
||||||
|
@ -420,6 +427,9 @@ signals:
|
||||||
QString strVersion );
|
QString strVersion );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void CLChannelLevelListReceived ( CHostAddress InetAddr,
|
||||||
|
CVector<uint16_t> vecLevelList );
|
||||||
|
|
||||||
void Disconnected();
|
void Disconnected();
|
||||||
void ControllerInFaderLevel ( int iChannelIdx, int iValue );
|
void ControllerInFaderLevel ( int iChannelIdx, int iValue );
|
||||||
};
|
};
|
||||||
|
|
|
@ -185,6 +185,9 @@ CClientDlg::CClientDlg ( CClient* pNCliP,
|
||||||
// reset mixer board
|
// reset mixer board
|
||||||
MainMixerBoard->HideAll();
|
MainMixerBoard->HideAll();
|
||||||
|
|
||||||
|
// restore channel level display preference
|
||||||
|
MainMixerBoard->SetDisplayChannelLevels ( pClient->GetDisplayChannelLevels() );
|
||||||
|
|
||||||
// restore fader settings
|
// restore fader settings
|
||||||
MainMixerBoard->vecStoredFaderTags = pClient->vecStoredFaderTags;
|
MainMixerBoard->vecStoredFaderTags = pClient->vecStoredFaderTags;
|
||||||
MainMixerBoard->vecStoredFaderLevels = pClient->vecStoredFaderLevels;
|
MainMixerBoard->vecStoredFaderLevels = pClient->vecStoredFaderLevels;
|
||||||
|
@ -483,6 +486,10 @@ CClientDlg::CClientDlg ( CClient* pNCliP,
|
||||||
SIGNAL ( ControllerInFaderLevel ( int, int ) ),
|
SIGNAL ( ControllerInFaderLevel ( int, int ) ),
|
||||||
this, SLOT ( OnControllerInFaderLevel ( int, int ) ) );
|
this, SLOT ( OnControllerInFaderLevel ( int, int ) ) );
|
||||||
|
|
||||||
|
QObject::connect ( pClient,
|
||||||
|
SIGNAL ( CLChannelLevelListReceived ( CHostAddress, CVector<uint16_t> ) ),
|
||||||
|
this, SLOT ( OnCLChannelLevelListReceived ( CHostAddress, CVector<uint16_t> ) ) );
|
||||||
|
|
||||||
#ifdef ENABLE_CLIENT_VERSION_AND_OS_DEBUGGING
|
#ifdef ENABLE_CLIENT_VERSION_AND_OS_DEBUGGING
|
||||||
QObject::connect ( pClient,
|
QObject::connect ( pClient,
|
||||||
SIGNAL ( CLVersionAndOSReceived ( CHostAddress, COSUtil::EOpSystemType, QString ) ),
|
SIGNAL ( CLVersionAndOSReceived ( CHostAddress, COSUtil::EOpSystemType, QString ) ),
|
||||||
|
@ -495,6 +502,9 @@ CClientDlg::CClientDlg ( CClient* pNCliP,
|
||||||
QObject::connect ( &ClientSettingsDlg, SIGNAL ( GUIDesignChanged() ),
|
QObject::connect ( &ClientSettingsDlg, SIGNAL ( GUIDesignChanged() ),
|
||||||
this, SLOT ( OnGUIDesignChanged() ) );
|
this, SLOT ( OnGUIDesignChanged() ) );
|
||||||
|
|
||||||
|
QObject::connect ( &ClientSettingsDlg, SIGNAL ( DisplayChannelLevelsChanged() ),
|
||||||
|
this, SLOT ( OnDisplayChannelLevelsChanged() ) );
|
||||||
|
|
||||||
QObject::connect ( &ClientSettingsDlg, SIGNAL ( AudioChannelsChanged() ),
|
QObject::connect ( &ClientSettingsDlg, SIGNAL ( AudioChannelsChanged() ),
|
||||||
this, SLOT ( OnAudioChannelsChanged() ) );
|
this, SLOT ( OnAudioChannelsChanged() ) );
|
||||||
|
|
||||||
|
@ -906,7 +916,7 @@ void CClientDlg::OnTimerSigMet()
|
||||||
// linear transformation of the input level range to the progress-bar
|
// linear transformation of the input level range to the progress-bar
|
||||||
// range
|
// range
|
||||||
dCurSigLevelL -= LOW_BOUND_SIG_METER;
|
dCurSigLevelL -= LOW_BOUND_SIG_METER;
|
||||||
dCurSigLevelL *= NUM_STEPS_INP_LEV_METER /
|
dCurSigLevelL *= NUM_STEPS_LED_BAR /
|
||||||
( UPPER_BOUND_SIG_METER - LOW_BOUND_SIG_METER );
|
( UPPER_BOUND_SIG_METER - LOW_BOUND_SIG_METER );
|
||||||
|
|
||||||
// lower bound the signal
|
// lower bound the signal
|
||||||
|
@ -916,7 +926,7 @@ void CClientDlg::OnTimerSigMet()
|
||||||
}
|
}
|
||||||
|
|
||||||
dCurSigLevelR -= LOW_BOUND_SIG_METER;
|
dCurSigLevelR -= LOW_BOUND_SIG_METER;
|
||||||
dCurSigLevelR *= NUM_STEPS_INP_LEV_METER /
|
dCurSigLevelR *= NUM_STEPS_LED_BAR /
|
||||||
( UPPER_BOUND_SIG_METER - LOW_BOUND_SIG_METER );
|
( UPPER_BOUND_SIG_METER - LOW_BOUND_SIG_METER );
|
||||||
|
|
||||||
// lower bound the signal
|
// lower bound the signal
|
||||||
|
|
|
@ -60,10 +60,6 @@
|
||||||
#define BUFFER_LED_UPDATE_TIME_MS 300 // ms
|
#define BUFFER_LED_UPDATE_TIME_MS 300 // ms
|
||||||
#define LED_BAR_UPDATE_TIME_MS 1000 // ms
|
#define LED_BAR_UPDATE_TIME_MS 1000 // ms
|
||||||
|
|
||||||
// range for signal level meter
|
|
||||||
#define LOW_BOUND_SIG_METER ( -50.0 ) // dB
|
|
||||||
#define UPPER_BOUND_SIG_METER ( 0.0 ) // dB
|
|
||||||
|
|
||||||
// number of ping times > upper bound until error message is shown
|
// number of ping times > upper bound until error message is shown
|
||||||
#define NUM_HIGH_PINGS_UNTIL_ERROR 5
|
#define NUM_HIGH_PINGS_UNTIL_ERROR 5
|
||||||
|
|
||||||
|
@ -196,12 +192,19 @@ public slots:
|
||||||
CVector<CChannelInfo> vecChanInfo )
|
CVector<CChannelInfo> vecChanInfo )
|
||||||
{ ConnectDlg.SetConnClientsList ( InetAddr, vecChanInfo ); }
|
{ ConnectDlg.SetConnClientsList ( InetAddr, vecChanInfo ); }
|
||||||
|
|
||||||
|
void OnCLChannelLevelListReceived ( CHostAddress /* unused */,
|
||||||
|
CVector<uint16_t> vecLevelList )
|
||||||
|
{ MainMixerBoard->SetChannelLevels ( vecLevelList ); }
|
||||||
|
|
||||||
void OnConnectDlgAccepted();
|
void OnConnectDlgAccepted();
|
||||||
void OnDisconnected();
|
void OnDisconnected();
|
||||||
|
|
||||||
void OnGUIDesignChanged()
|
void OnGUIDesignChanged()
|
||||||
{ SetGUIDesign ( pClient->GetGUIDesign() ); }
|
{ SetGUIDesign ( pClient->GetGUIDesign() ); }
|
||||||
|
|
||||||
|
void OnDisplayChannelLevelsChanged()
|
||||||
|
{ MainMixerBoard->SetDisplayChannelLevels ( pClient->GetDisplayChannelLevels() ); }
|
||||||
|
|
||||||
void OnAudioChannelsChanged() { UpdateRevSelection(); }
|
void OnAudioChannelsChanged() { UpdateRevSelection(); }
|
||||||
void OnNumClientsChanged ( int iNewNumClients );
|
void OnNumClientsChanged ( int iNewNumClients );
|
||||||
void OnNewClientLevelChanged() { MainMixerBoard->iNewClientFaderLevel = pClient->iNewClientFaderLevel; }
|
void OnNewClientLevelChanged() { MainMixerBoard->iNewClientFaderLevel = pClient->iNewClientFaderLevel; }
|
||||||
|
|
|
@ -189,6 +189,12 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
|
||||||
|
|
||||||
chbGUIDesignFancy->setAccessibleName ( tr ( "Fancy skin check box" ) );
|
chbGUIDesignFancy->setAccessibleName ( tr ( "Fancy skin check box" ) );
|
||||||
|
|
||||||
|
// display channel levels
|
||||||
|
chbDisplayChannelLevels->setWhatsThis ( tr ( "<b>Display Channel Levels:</b> "
|
||||||
|
"If enabled, each client channel will display a pre-fader level bar." ) );
|
||||||
|
|
||||||
|
chbDisplayChannelLevels->setAccessibleName ( tr ( "Display channel levels check box" ) );
|
||||||
|
|
||||||
// audio channels
|
// audio channels
|
||||||
QString strAudioChannels = tr ( "<b>Audio Channels:</b> "
|
QString strAudioChannels = tr ( "<b>Audio Channels:</b> "
|
||||||
"Select the number of audio channels to be used. There are three "
|
"Select the number of audio channels to be used. There are three "
|
||||||
|
@ -323,6 +329,9 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
|
||||||
chbGUIDesignFancy->setCheckState ( Qt::Checked );
|
chbGUIDesignFancy->setCheckState ( Qt::Checked );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Display Channel Levels check box
|
||||||
|
chbDisplayChannelLevels->setCheckState ( pClient->GetDisplayChannelLevels() ? Qt::Checked : Qt::Unchecked );
|
||||||
|
|
||||||
// "Audio Channels" combo box
|
// "Audio Channels" combo box
|
||||||
cbxAudioChannels->clear();
|
cbxAudioChannels->clear();
|
||||||
cbxAudioChannels->addItem ( "Mono" ); // CC_MONO
|
cbxAudioChannels->addItem ( "Mono" ); // CC_MONO
|
||||||
|
@ -386,6 +395,9 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
|
||||||
QObject::connect ( chbGUIDesignFancy, SIGNAL ( stateChanged ( int ) ),
|
QObject::connect ( chbGUIDesignFancy, SIGNAL ( stateChanged ( int ) ),
|
||||||
this, SLOT ( OnGUIDesignFancyStateChanged ( int ) ) );
|
this, SLOT ( OnGUIDesignFancyStateChanged ( int ) ) );
|
||||||
|
|
||||||
|
QObject::connect ( chbDisplayChannelLevels, SIGNAL ( stateChanged ( int ) ),
|
||||||
|
this, SLOT ( OnDisplayChannelLevelsStateChanged ( int ) ) );
|
||||||
|
|
||||||
QObject::connect ( chbAutoJitBuf, SIGNAL ( stateChanged ( int ) ),
|
QObject::connect ( chbAutoJitBuf, SIGNAL ( stateChanged ( int ) ),
|
||||||
this, SLOT ( OnAutoJitBufStateChanged ( int ) ) );
|
this, SLOT ( OnAutoJitBufStateChanged ( int ) ) );
|
||||||
|
|
||||||
|
@ -704,6 +716,12 @@ void CClientSettingsDlg::OnGUIDesignFancyStateChanged ( int value )
|
||||||
UpdateDisplay();
|
UpdateDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CClientSettingsDlg::OnDisplayChannelLevelsStateChanged ( int value )
|
||||||
|
{
|
||||||
|
pClient->SetDisplayChannelLevels ( value != Qt::Unchecked );
|
||||||
|
emit DisplayChannelLevelsChanged();
|
||||||
|
}
|
||||||
|
|
||||||
void CClientSettingsDlg::OnDefaultCentralServerStateChanged ( int value )
|
void CClientSettingsDlg::OnDefaultCentralServerStateChanged ( int value )
|
||||||
{
|
{
|
||||||
// apply new setting to the client
|
// apply new setting to the client
|
||||||
|
|
|
@ -90,6 +90,7 @@ protected:
|
||||||
void OnSliderSndCrdBufferDelay ( int value );
|
void OnSliderSndCrdBufferDelay ( int value );
|
||||||
void OnAutoJitBufStateChanged ( int value );
|
void OnAutoJitBufStateChanged ( int value );
|
||||||
void OnGUIDesignFancyStateChanged ( int value );
|
void OnGUIDesignFancyStateChanged ( int value );
|
||||||
|
void OnDisplayChannelLevelsStateChanged ( int value );
|
||||||
void OnDefaultCentralServerStateChanged ( int value );
|
void OnDefaultCentralServerStateChanged ( int value );
|
||||||
void OnCentralServerAddressEditingFinished();
|
void OnCentralServerAddressEditingFinished();
|
||||||
void OnNewClientLevelEditingFinished();
|
void OnNewClientLevelEditingFinished();
|
||||||
|
@ -105,6 +106,7 @@ protected:
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void GUIDesignChanged();
|
void GUIDesignChanged();
|
||||||
|
void DisplayChannelLevelsChanged();
|
||||||
void AudioChannelsChanged();
|
void AudioChannelsChanged();
|
||||||
void NewClientLevelChanged();
|
void NewClientLevelChanged();
|
||||||
};
|
};
|
||||||
|
|
|
@ -530,11 +530,22 @@
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="chbGUIDesignFancy">
|
<layout class="QHBoxLayout">
|
||||||
<property name="text">
|
<item>
|
||||||
<string>Fancy Skin</string>
|
<widget class="QCheckBox" name="chbGUIDesignFancy">
|
||||||
</property>
|
<property name="text">
|
||||||
</widget>
|
<string>Fancy Skin</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="chbDisplayChannelLevels">
|
||||||
|
<property name="text">
|
||||||
|
<string>Display Channel Levels</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout">
|
<layout class="QHBoxLayout">
|
||||||
|
@ -719,6 +730,7 @@
|
||||||
<tabstop>cbxAudioQuality</tabstop>
|
<tabstop>cbxAudioQuality</tabstop>
|
||||||
<tabstop>edtNewClientLevel</tabstop>
|
<tabstop>edtNewClientLevel</tabstop>
|
||||||
<tabstop>chbGUIDesignFancy</tabstop>
|
<tabstop>chbGUIDesignFancy</tabstop>
|
||||||
|
<tabstop>chbDisplayChannelFaders</tabstop>
|
||||||
<tabstop>chbDefaultCentralServer</tabstop>
|
<tabstop>chbDefaultCentralServer</tabstop>
|
||||||
<tabstop>edtCentralServerAddress</tabstop>
|
<tabstop>edtCentralServerAddress</tabstop>
|
||||||
</tabstops>
|
</tabstops>
|
||||||
|
|
15
src/global.h
|
@ -169,10 +169,14 @@ LED bar: lbr
|
||||||
// maximum number of fader settings to be stored (together with the fader tags)
|
// maximum number of fader settings to be stored (together with the fader tags)
|
||||||
#define MAX_NUM_STORED_FADER_SETTINGS 100
|
#define MAX_NUM_STORED_FADER_SETTINGS 100
|
||||||
|
|
||||||
// defines for LED input level meter
|
// defines for LED level meter CMultiColorLEDBar
|
||||||
#define NUM_STEPS_INP_LEV_METER 8
|
#define NUM_STEPS_LED_BAR 8
|
||||||
#define RED_BOUND_INP_LEV_METER 7
|
#define RED_BOUND_LED_BAR 7
|
||||||
#define YELLOW_BOUND_INP_LEV_METER 5
|
#define YELLOW_BOUND_LED_BAR 5
|
||||||
|
|
||||||
|
// range for signal level meter
|
||||||
|
#define LOW_BOUND_SIG_METER ( -50.0 ) // dB
|
||||||
|
#define UPPER_BOUND_SIG_METER ( 0.0 ) // dB
|
||||||
|
|
||||||
// Maximum number of connected clients at the server. If you want to change this
|
// Maximum number of connected clients at the server. If you want to change this
|
||||||
// paramter you have to modify the code on some places, too! The code tag
|
// paramter you have to modify the code on some places, too! The code tag
|
||||||
|
@ -195,6 +199,9 @@ LED bar: lbr
|
||||||
// list
|
// list
|
||||||
#define PING_UPDATE_TIME_SERVER_LIST_MS 2000 // ms
|
#define PING_UPDATE_TIME_SERVER_LIST_MS 2000 // ms
|
||||||
|
|
||||||
|
// defines the interval between Channel Level updates from the server
|
||||||
|
#define CHANNEL_LEVEL_UPDATE_INTERVAL 100 // number of frames
|
||||||
|
|
||||||
// time-out until a registered server is deleted from the server list if no
|
// time-out until a registered server is deleted from the server list if no
|
||||||
// new registering was made in minutes
|
// new registering was made in minutes
|
||||||
#define SERVLIST_TIME_OUT_MINUTES 60 // minutes
|
#define SERVLIST_TIME_OUT_MINUTES 60 // minutes
|
||||||
|
|
|
@ -33,7 +33,7 @@ CMultiColorLEDBar::CMultiColorLEDBar ( QWidget* parent, Qt::WindowFlags f )
|
||||||
: QFrame ( parent, f )
|
: QFrame ( parent, f )
|
||||||
{
|
{
|
||||||
// set total number of LEDs
|
// set total number of LEDs
|
||||||
iNumLEDs = NUM_STEPS_INP_LEV_METER;
|
iNumLEDs = NUM_STEPS_LED_BAR;
|
||||||
|
|
||||||
// create layout and set spacing to zero
|
// create layout and set spacing to zero
|
||||||
pMainLayout = new QVBoxLayout ( this );
|
pMainLayout = new QVBoxLayout ( this );
|
||||||
|
@ -105,14 +105,14 @@ void CMultiColorLEDBar::setValue ( const int value )
|
||||||
if ( iLEDIdx < value )
|
if ( iLEDIdx < value )
|
||||||
{
|
{
|
||||||
// check which color we should use (green, yellow or red)
|
// check which color we should use (green, yellow or red)
|
||||||
if ( iLEDIdx < YELLOW_BOUND_INP_LEV_METER )
|
if ( iLEDIdx < YELLOW_BOUND_LED_BAR )
|
||||||
{
|
{
|
||||||
// green region
|
// green region
|
||||||
vecpLEDs[iLEDIdx]->setColor ( cLED::RL_GREEN );
|
vecpLEDs[iLEDIdx]->setColor ( cLED::RL_GREEN );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( iLEDIdx < RED_BOUND_INP_LEV_METER )
|
if ( iLEDIdx < RED_BOUND_LED_BAR )
|
||||||
{
|
{
|
||||||
// yellow region
|
// yellow region
|
||||||
vecpLEDs[iLEDIdx]->setColor ( cLED::RL_YELLOW );
|
vecpLEDs[iLEDIdx]->setColor ( cLED::RL_YELLOW );
|
||||||
|
|
135
src/protocol.cpp
|
@ -153,6 +153,14 @@ MESSAGES (with connection)
|
||||||
| 1 byte licence type |
|
| 1 byte licence type |
|
||||||
+---------------------+
|
+---------------------+
|
||||||
|
|
||||||
|
- PROTMESSID_CLM_REQ_CHANNEL_LEVEL_LIST: Opt in or out of the channel level list
|
||||||
|
|
||||||
|
+---------------+
|
||||||
|
| 1 byte option |
|
||||||
|
+---------------+
|
||||||
|
|
||||||
|
option is boolean, true to opt in, false to opt out
|
||||||
|
|
||||||
|
|
||||||
// #### COMPATIBILITY OLD VERSION, TO BE REMOVED ####
|
// #### COMPATIBILITY OLD VERSION, TO BE REMOVED ####
|
||||||
- PROTMESSID_OPUS_SUPPORTED: Informs that OPUS codec is supported
|
- PROTMESSID_OPUS_SUPPORTED: Informs that OPUS codec is supported
|
||||||
|
@ -276,6 +284,27 @@ CONNECTION LESS MESSAGES
|
||||||
|
|
||||||
note: does not have any data -> n = 0
|
note: does not have any data -> n = 0
|
||||||
|
|
||||||
|
- PROTMESSID_CLM_CHANNEL_LEVEL_LIST: The channel level list
|
||||||
|
|
||||||
|
+----------------------------------+
|
||||||
|
| ( ( n + 1 ) / 2 ) * 4 bit values |
|
||||||
|
+----------------------------------+
|
||||||
|
|
||||||
|
n is number of connected clients
|
||||||
|
|
||||||
|
the values are the maximum channel levels for a client frame converted
|
||||||
|
to the range of CMultiColorLEDBar in 4 bits, two entries per byte
|
||||||
|
with the earlier channel in the lower half of the byte
|
||||||
|
|
||||||
|
where an odd number of clients is connected, there will be four unused
|
||||||
|
upper bits in the final byte, containing 0xF (which is out of range)
|
||||||
|
|
||||||
|
the server may compute them message when any client has used
|
||||||
|
PROTMESSID_CLM_REQ_CHANNEL_LEVEL_LIST to opt in
|
||||||
|
|
||||||
|
the server may issue to message only to a client that has used
|
||||||
|
PROTMESSID_CLM_REQ_CHANNEL_LEVEL_LIST to opt in
|
||||||
|
|
||||||
|
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
|
@ -549,6 +578,10 @@ if ( rand() < ( RAND_MAX / 2 ) ) return false;
|
||||||
case PROTMESSID_LICENCE_REQUIRED:
|
case PROTMESSID_LICENCE_REQUIRED:
|
||||||
bRet = EvaluateLicenceRequiredMes ( vecbyMesBodyData );
|
bRet = EvaluateLicenceRequiredMes ( vecbyMesBodyData );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROTMESSID_REQ_CHANNEL_LEVEL_LIST:
|
||||||
|
bRet = EvaluateReqChannelLevelListMes ( vecbyMesBodyData );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// immediately send acknowledge message
|
// immediately send acknowledge message
|
||||||
|
@ -634,6 +667,10 @@ if ( rand() < ( RAND_MAX / 2 ) ) return false;
|
||||||
case PROTMESSID_CLM_REQ_CONN_CLIENTS_LIST:
|
case PROTMESSID_CLM_REQ_CONN_CLIENTS_LIST:
|
||||||
bRet = EvaluateCLReqConnClientsListMes ( InetAddr );
|
bRet = EvaluateCLReqConnClientsListMes ( InetAddr );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROTMESSID_CLM_CHANNEL_LEVEL_LIST:
|
||||||
|
bRet = EvaluateCLChannelLevelListMes ( InetAddr, vecbyMesBodyData );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1234,6 +1271,40 @@ void CProtocol::CreateOpusSupportedMes()
|
||||||
CVector<uint8_t> ( 0 ) );
|
CVector<uint8_t> ( 0 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CProtocol::CreateReqChannelLevelListMes ( const bool bRCL )
|
||||||
|
{
|
||||||
|
CVector<uint8_t> vecData ( 1 ); // 1 byte of data
|
||||||
|
int iPos = 0; // init position pointer
|
||||||
|
PutValOnStream ( vecData, iPos,
|
||||||
|
static_cast<uint32_t> ( bRCL ), 1 );
|
||||||
|
|
||||||
|
CreateAndSendMessage ( PROTMESSID_REQ_CHANNEL_LEVEL_LIST, vecData );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CProtocol::EvaluateReqChannelLevelListMes ( const CVector<uint8_t>& vecData )
|
||||||
|
{
|
||||||
|
int iPos = 0; // init position pointer
|
||||||
|
|
||||||
|
// check size
|
||||||
|
if ( vecData.Size() != 1 )
|
||||||
|
{
|
||||||
|
return true; // return error code
|
||||||
|
}
|
||||||
|
|
||||||
|
// extract opt in / out for channel levels
|
||||||
|
uint32_t val = GetValFromStream ( vecData, iPos, 1 );
|
||||||
|
|
||||||
|
if ( val != 0 && val != 1 )
|
||||||
|
{
|
||||||
|
return true; // return error code
|
||||||
|
}
|
||||||
|
|
||||||
|
// invoke message action
|
||||||
|
emit ReqChannelLevelList ( static_cast<bool> ( val ) );
|
||||||
|
|
||||||
|
return false; // no error
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Connection less messages ----------------------------------------------------
|
// Connection less messages ----------------------------------------------------
|
||||||
void CProtocol::CreateCLPingMes ( const CHostAddress& InetAddr, const int iMs )
|
void CProtocol::CreateCLPingMes ( const CHostAddress& InetAddr, const int iMs )
|
||||||
|
@ -1936,6 +2007,70 @@ bool CProtocol::EvaluateCLReqConnClientsListMes ( const CHostAddress& InetAddr )
|
||||||
return false; // no error
|
return false; // no error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CProtocol::CreateCLChannelLevelListMes ( const CHostAddress& InetAddr,
|
||||||
|
const CVector<uint16_t>& vecLevelList,
|
||||||
|
const int iNumClients )
|
||||||
|
{
|
||||||
|
// This must be a multiple of bytes at four bits per client
|
||||||
|
const int iNumBytes = ( iNumClients + 1 ) / 2;
|
||||||
|
CVector<uint8_t> vecData( iNumBytes );
|
||||||
|
int iPos = 0; // init position pointer
|
||||||
|
|
||||||
|
for ( int i = 0, j = 0; i < iNumClients; i += 2 /* pack two per byte */, j++ )
|
||||||
|
{
|
||||||
|
uint16_t levelLo = vecLevelList[i] & 0x0F;
|
||||||
|
uint16_t levelHi = ( i + 1 < iNumClients ) ? vecLevelList[i + 1] & 0x0F : 0x0F;
|
||||||
|
uint8_t byte = static_cast<uint8_t> ( levelLo | ( levelHi << 4 ) );
|
||||||
|
|
||||||
|
PutValOnStream ( vecData, iPos,
|
||||||
|
static_cast<uint32_t> ( byte ), 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateAndImmSendConLessMessage ( PROTMESSID_CLM_CHANNEL_LEVEL_LIST,
|
||||||
|
vecData,
|
||||||
|
InetAddr );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CProtocol::EvaluateCLChannelLevelListMes ( const CHostAddress& InetAddr,
|
||||||
|
const CVector<uint8_t>& vecData )
|
||||||
|
{
|
||||||
|
int iPos = 0; // init position pointer
|
||||||
|
const int iDataLen = vecData.Size(); // four bits per channel, 2 channels per byte
|
||||||
|
// may have one too many entries, last being 0xF
|
||||||
|
int iVecLen = iDataLen * 2; // one ushort per channel
|
||||||
|
|
||||||
|
if ( iVecLen > MAX_NUM_CHANNELS )
|
||||||
|
{
|
||||||
|
return true; // return error code
|
||||||
|
}
|
||||||
|
|
||||||
|
CVector<uint16_t> vecLevelList ( iVecLen );
|
||||||
|
|
||||||
|
for (int i = 0, j = 0; i < iDataLen; i++, j += 2 )
|
||||||
|
{
|
||||||
|
uint8_t byte = static_cast<uint8_t> ( GetValFromStream ( vecData, iPos, 1 ) );
|
||||||
|
uint16_t levelLo = byte & 0x0F;
|
||||||
|
uint16_t levelHi = ( byte >> 4 ) & 0x0F;
|
||||||
|
|
||||||
|
vecLevelList[j] = levelLo;
|
||||||
|
|
||||||
|
if ( levelHi != 0x0F )
|
||||||
|
{
|
||||||
|
vecLevelList[j + 1] = levelHi;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vecLevelList.resize ( iVecLen - 1 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// invoke message action
|
||||||
|
emit CLChannelLevelListReceived ( InetAddr, vecLevelList );
|
||||||
|
|
||||||
|
return false; // no error
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************\
|
/******************************************************************************\
|
||||||
* Message generation and parsing *
|
* Message generation and parsing *
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
#define PROTMESSID_CHANNEL_INFOS 25 // set channel infos
|
#define PROTMESSID_CHANNEL_INFOS 25 // set channel infos
|
||||||
#define PROTMESSID_OPUS_SUPPORTED 26 // tells that OPUS codec is supported
|
#define PROTMESSID_OPUS_SUPPORTED 26 // tells that OPUS codec is supported
|
||||||
#define PROTMESSID_LICENCE_REQUIRED 27 // licence required
|
#define PROTMESSID_LICENCE_REQUIRED 27 // licence required
|
||||||
|
#define PROTMESSID_REQ_CHANNEL_LEVEL_LIST 28 // request the channel level list
|
||||||
|
|
||||||
// message IDs of connection less messages (CLM)
|
// message IDs of connection less messages (CLM)
|
||||||
// DEFINITION -> start at 1000, end at 1999, see IsConnectionLessMessageID
|
// DEFINITION -> start at 1000, end at 1999, see IsConnectionLessMessageID
|
||||||
|
@ -71,6 +72,7 @@
|
||||||
#define PROTMESSID_CLM_REQ_VERSION_AND_OS 1012 // request version number and operating system
|
#define PROTMESSID_CLM_REQ_VERSION_AND_OS 1012 // request version number and operating system
|
||||||
#define PROTMESSID_CLM_CONN_CLIENTS_LIST 1013 // channel infos for connected clients
|
#define PROTMESSID_CLM_CONN_CLIENTS_LIST 1013 // channel infos for connected clients
|
||||||
#define PROTMESSID_CLM_REQ_CONN_CLIENTS_LIST 1014 // request the connected clients list
|
#define PROTMESSID_CLM_REQ_CONN_CLIENTS_LIST 1014 // request the connected clients list
|
||||||
|
#define PROTMESSID_CLM_CHANNEL_LEVEL_LIST 1015 // channel level list
|
||||||
|
|
||||||
// lengths of message as defined in protocol.cpp file
|
// lengths of message as defined in protocol.cpp file
|
||||||
#define MESS_HEADER_LENGTH_BYTE 7 // TAG (2), ID (2), cnt (1), length (2)
|
#define MESS_HEADER_LENGTH_BYTE 7 // TAG (2), ID (2), cnt (1), length (2)
|
||||||
|
@ -102,6 +104,7 @@ public:
|
||||||
void CreateReqNetwTranspPropsMes();
|
void CreateReqNetwTranspPropsMes();
|
||||||
void CreateLicenceRequiredMes ( const ELicenceType eLicenceType );
|
void CreateLicenceRequiredMes ( const ELicenceType eLicenceType );
|
||||||
void CreateOpusSupportedMes();
|
void CreateOpusSupportedMes();
|
||||||
|
void CreateReqChannelLevelListMes ( const bool bRCL );
|
||||||
|
|
||||||
void CreateCLPingMes ( const CHostAddress& InetAddr, const int iMs );
|
void CreateCLPingMes ( const CHostAddress& InetAddr, const int iMs );
|
||||||
void CreateCLPingWithNumClientsMes ( const CHostAddress& InetAddr,
|
void CreateCLPingWithNumClientsMes ( const CHostAddress& InetAddr,
|
||||||
|
@ -123,6 +126,9 @@ public:
|
||||||
void CreateCLConnClientsListMes ( const CHostAddress& InetAddr,
|
void CreateCLConnClientsListMes ( const CHostAddress& InetAddr,
|
||||||
const CVector<CChannelInfo>& vecChanInfo );
|
const CVector<CChannelInfo>& vecChanInfo );
|
||||||
void CreateCLReqConnClientsListMes ( const CHostAddress& InetAddr );
|
void CreateCLReqConnClientsListMes ( const CHostAddress& InetAddr );
|
||||||
|
void CreateCLChannelLevelListMes ( const CHostAddress& InetAddr,
|
||||||
|
const CVector<uint16_t>& vecLevelList,
|
||||||
|
const int iNumClients );
|
||||||
|
|
||||||
static bool ParseMessageFrame ( const CVector<uint8_t>& vecbyData,
|
static bool ParseMessageFrame ( const CVector<uint8_t>& vecbyData,
|
||||||
const int iNumBytesIn,
|
const int iNumBytesIn,
|
||||||
|
@ -205,17 +211,18 @@ protected:
|
||||||
const CVector<uint8_t>& vecData,
|
const CVector<uint8_t>& vecData,
|
||||||
const CHostAddress& InetAddr );
|
const CHostAddress& InetAddr );
|
||||||
|
|
||||||
bool EvaluateJitBufMes ( const CVector<uint8_t>& vecData );
|
bool EvaluateJitBufMes ( const CVector<uint8_t>& vecData );
|
||||||
bool EvaluateReqJitBufMes();
|
bool EvaluateReqJitBufMes();
|
||||||
bool EvaluateChanGainMes ( const CVector<uint8_t>& vecData );
|
bool EvaluateChanGainMes ( const CVector<uint8_t>& vecData );
|
||||||
bool EvaluateConClientListMes ( const CVector<uint8_t>& vecData );
|
bool EvaluateConClientListMes ( const CVector<uint8_t>& vecData );
|
||||||
bool EvaluateReqConnClientsList();
|
bool EvaluateReqConnClientsList();
|
||||||
bool EvaluateChanInfoMes ( const CVector<uint8_t>& vecData );
|
bool EvaluateChanInfoMes ( const CVector<uint8_t>& vecData );
|
||||||
bool EvaluateReqChanInfoMes();
|
bool EvaluateReqChanInfoMes();
|
||||||
bool EvaluateChatTextMes ( const CVector<uint8_t>& vecData );
|
bool EvaluateChatTextMes ( const CVector<uint8_t>& vecData );
|
||||||
bool EvaluateNetwTranspPropsMes ( const CVector<uint8_t>& vecData );
|
bool EvaluateNetwTranspPropsMes ( const CVector<uint8_t>& vecData );
|
||||||
bool EvaluateReqNetwTranspPropsMes();
|
bool EvaluateReqNetwTranspPropsMes();
|
||||||
bool EvaluateLicenceRequiredMes ( const CVector<uint8_t>& vecData );
|
bool EvaluateLicenceRequiredMes ( const CVector<uint8_t>& vecData );
|
||||||
|
bool EvaluateReqChannelLevelListMes ( const CVector<uint8_t>& vecData );
|
||||||
|
|
||||||
bool EvaluateCLPingMes ( const CHostAddress& InetAddr,
|
bool EvaluateCLPingMes ( const CHostAddress& InetAddr,
|
||||||
const CVector<uint8_t>& vecData );
|
const CVector<uint8_t>& vecData );
|
||||||
|
@ -236,6 +243,8 @@ protected:
|
||||||
bool EvaluateCLConnClientsListMes ( const CHostAddress& InetAddr,
|
bool EvaluateCLConnClientsListMes ( const CHostAddress& InetAddr,
|
||||||
const CVector<uint8_t>& vecData );
|
const CVector<uint8_t>& vecData );
|
||||||
bool EvaluateCLReqConnClientsListMes ( const CHostAddress& InetAddr );
|
bool EvaluateCLReqConnClientsListMes ( const CHostAddress& InetAddr );
|
||||||
|
bool EvaluateCLChannelLevelListMes ( const CHostAddress& InetAddr,
|
||||||
|
const CVector<uint8_t>& vecData );
|
||||||
|
|
||||||
int iOldRecID;
|
int iOldRecID;
|
||||||
int iOldRecCnt;
|
int iOldRecCnt;
|
||||||
|
@ -270,6 +279,7 @@ signals:
|
||||||
void NetTranspPropsReceived ( CNetworkTransportProps NetworkTransportProps );
|
void NetTranspPropsReceived ( CNetworkTransportProps NetworkTransportProps );
|
||||||
void ReqNetTranspProps();
|
void ReqNetTranspProps();
|
||||||
void LicenceRequired ( ELicenceType eLicenceType );
|
void LicenceRequired ( ELicenceType eLicenceType );
|
||||||
|
void ReqChannelLevelList ( bool bOptIn );
|
||||||
|
|
||||||
void CLPingReceived ( CHostAddress InetAddr,
|
void CLPingReceived ( CHostAddress InetAddr,
|
||||||
int iMs );
|
int iMs );
|
||||||
|
@ -291,4 +301,6 @@ signals:
|
||||||
void CLConnClientsListMesReceived ( CHostAddress InetAddr,
|
void CLConnClientsListMesReceived ( CHostAddress InetAddr,
|
||||||
CVector<CChannelInfo> vecChanInfo );
|
CVector<CChannelInfo> vecChanInfo );
|
||||||
void CLReqConnClientsList ( CHostAddress InetAddr );
|
void CLReqConnClientsList ( CHostAddress InetAddr );
|
||||||
|
void CLChannelLevelListReceived ( CHostAddress InetAddr,
|
||||||
|
CVector<uint16_t> vecLevelList );
|
||||||
};
|
};
|
||||||
|
|
BIN
src/res/homepage/displaychannellevels.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 60 KiB |
|
@ -81,11 +81,11 @@ The reverberation effect requires significant CPU so that it should only be used
|
||||||
level fader is set to minimum (which is the default setting), the reverberation effect is switched off and does
|
level fader is set to minimum (which is the default setting), the reverberation effect is switched off and does
|
||||||
not cause any additional CPU usage.
|
not cause any additional CPU usage.
|
||||||
|
|
||||||
### Local audio input fader
|
### Local audio pan / balance control
|
||||||
|
|
||||||
![Local audio input fader](audiofader.jpg)
|
![Local audio pan / balance control](audiofader.jpg)
|
||||||
|
|
||||||
With the audio fader, the relative levels of the left and right local audio channels can be changed. For a mono signal
|
With the balance control, the relative levels of the left and right local audio channels can be changed. For a mono signal
|
||||||
it acts like a panning between the two channels. If, e.g., a microphone is connected to the right input channel and
|
it acts like a panning between the two channels. If, e.g., a microphone is connected to the right input channel and
|
||||||
an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader
|
an instrument is connected to the left input channel which is much louder than the microphone, move the audio fader
|
||||||
in a direction where the label above the fader shows L -x, where x is the current attenuation indicator.
|
in a direction where the label above the fader shows L -x, where x is the current attenuation indicator.
|
||||||
|
@ -94,11 +94,13 @@ in a direction where the label above the fader shows L -x, where x is the curren
|
||||||
|
|
||||||
![Audio faders](faders.jpg)
|
![Audio faders](faders.jpg)
|
||||||
|
|
||||||
In the audio mixer frame, a fader for each connected client at the server is shown. This includes a fader for the own signal.
|
In the audio mixer frame, a fader is shown for each connected client at the server, including yourself.
|
||||||
With the faders, the audio level of each client can be modified individually.
|
The faders allow you to adjust the level of what you hear without affecting what others hear.
|
||||||
|
The VU meter shows the input level at the server - that is, what you are sending.
|
||||||
|
|
||||||
With the Mute checkbox, the current audio channel can be muted. With the Solo checkbox, the current audio channel can
|
Using the Mute checkbox prevents the indicated channel being heard in your local mix.
|
||||||
be set to solo which means that all other channels except of the current channel are muted.
|
|
||||||
|
The solo checkboxes allow you to hear only one, or several, channels, with those not soloed being muted.
|
||||||
|
|
||||||
Settings Window
|
Settings Window
|
||||||
---------------
|
---------------
|
||||||
|
@ -206,6 +208,12 @@ that client was already stored.
|
||||||
|
|
||||||
If enabled, a fancy skin will be applied to the main window.
|
If enabled, a fancy skin will be applied to the main window.
|
||||||
|
|
||||||
|
### Display channel levels
|
||||||
|
|
||||||
|
![Display channel levels](displaychannellevels.png)
|
||||||
|
|
||||||
|
If enabled, the channel input level for each connected client will be displayed in the mixer.
|
||||||
|
|
||||||
### Central server address
|
### Central server address
|
||||||
|
|
||||||
![Central server address](centralserveraddress.png)
|
![Central server address](centralserveraddress.png)
|
||||||
|
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 71 KiB |
|
@ -335,6 +335,8 @@ CServer::CServer ( const int iNewMaxNumChan,
|
||||||
// allocate worst case memory for the coded data
|
// allocate worst case memory for the coded data
|
||||||
vecbyCodedData.Init ( MAX_SIZE_BYTES_NETW_BUF );
|
vecbyCodedData.Init ( MAX_SIZE_BYTES_NETW_BUF );
|
||||||
|
|
||||||
|
// allocate worst case memory for the channel levels
|
||||||
|
vecChannelLevels.Init ( iMaxNumChannels );
|
||||||
|
|
||||||
// enable history graph (if requested)
|
// enable history graph (if requested)
|
||||||
if ( !strHistoryFileName.isEmpty() )
|
if ( !strHistoryFileName.isEmpty() )
|
||||||
|
@ -864,6 +866,7 @@ JitterMeas.Measure();
|
||||||
// some inits
|
// some inits
|
||||||
int iNumClients = 0; // init connected client counter
|
int iNumClients = 0; // init connected client counter
|
||||||
bool bChannelIsNowDisconnected = false;
|
bool bChannelIsNowDisconnected = false;
|
||||||
|
bool bSendChannelLevels = false;
|
||||||
|
|
||||||
// Make put and get calls thread safe. Do not forget to unlock mutex
|
// Make put and get calls thread safe. Do not forget to unlock mutex
|
||||||
// afterwards!
|
// afterwards!
|
||||||
|
@ -1007,6 +1010,29 @@ JitterMeas.Measure();
|
||||||
// one client is connected.
|
// one client is connected.
|
||||||
if ( iNumClients > 0 )
|
if ( iNumClients > 0 )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// Low frequency updates
|
||||||
|
if ( iFrameCount > CHANNEL_LEVEL_UPDATE_INTERVAL )
|
||||||
|
{
|
||||||
|
iFrameCount = 0;
|
||||||
|
|
||||||
|
// Calculate channel levels if any client has requested them
|
||||||
|
for ( int i = 0; i < iNumClients; i++ )
|
||||||
|
{
|
||||||
|
if ( vecChannels[ vecChanIDsCurConChan[i] ].ChannelLevelsRequired() )
|
||||||
|
{
|
||||||
|
bSendChannelLevels = true;
|
||||||
|
|
||||||
|
CreateLevelsForAllConChannels ( iNumClients,
|
||||||
|
vecNumAudioChannels,
|
||||||
|
vecvecsData,
|
||||||
|
vecChannelLevels );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iFrameCount++;
|
||||||
|
|
||||||
for ( int i = 0; i < iNumClients; i++ )
|
for ( int i = 0; i < iNumClients; i++ )
|
||||||
{
|
{
|
||||||
// get actual ID of current channel
|
// get actual ID of current channel
|
||||||
|
@ -1095,6 +1121,12 @@ opus_custom_encoder_ctl ( CurOpusEncoder,
|
||||||
|
|
||||||
// update socket buffer size
|
// update socket buffer size
|
||||||
vecChannels[iCurChanID].UpdateSocketBufferSize();
|
vecChannels[iCurChanID].UpdateSocketBufferSize();
|
||||||
|
|
||||||
|
// send channel levels
|
||||||
|
if ( bSendChannelLevels && vecChannels[iCurChanID].ChannelLevelsRequired() )
|
||||||
|
{
|
||||||
|
ConnLessProtocol.CreateCLChannelLevelListMes ( vecChannels[iCurChanID].GetAddress(), vecChannelLevels, iNumClients );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1574,3 +1606,69 @@ void CServer::customEvent ( QEvent* pEvent )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief Compute frame peak level for each client
|
||||||
|
void CServer::CreateLevelsForAllConChannels ( const int iNumClients,
|
||||||
|
const CVector<int>& vecNumAudioChannels,
|
||||||
|
const CVector<CVector<int16_t> > vecvecsData,
|
||||||
|
CVector<uint16_t>& vecLevelsOut )
|
||||||
|
{
|
||||||
|
int i, j, k;
|
||||||
|
|
||||||
|
// init return vector with zeros since we mix all channels on that vector
|
||||||
|
vecLevelsOut.Reset ( 0 );
|
||||||
|
|
||||||
|
for ( j = 0; j < iNumClients; j++ )
|
||||||
|
{
|
||||||
|
// get a reference to the audio data
|
||||||
|
const CVector<int16_t>& vecsData = vecvecsData[j];
|
||||||
|
|
||||||
|
double dCurLevel = 0.0;
|
||||||
|
if ( vecNumAudioChannels[j] == 1 )
|
||||||
|
{
|
||||||
|
// mono
|
||||||
|
for ( i = 0; i < SYSTEM_FRAME_SIZE_SAMPLES; i += 3 )
|
||||||
|
{
|
||||||
|
dCurLevel = std::max ( dCurLevel, std::abs ( static_cast<double> ( vecsData[i] ) ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// stereo: apply stereo-to-mono attenuation
|
||||||
|
for ( i = 0, k = 0; i < SYSTEM_FRAME_SIZE_SAMPLES; i += 3, k += 6 )
|
||||||
|
{
|
||||||
|
double sMix = ( static_cast<double> ( vecsData[k] ) + vecsData[k + 1] ) / 2;
|
||||||
|
dCurLevel = std::max ( dCurLevel, std::abs ( sMix ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// smoothing
|
||||||
|
int iChId = vecChanIDsCurConChan [ j ];
|
||||||
|
dCurLevel = std::max ( dCurLevel, vecChannels[ iChId ].GetPrevLevel() * 0.5 );
|
||||||
|
vecChannels[ iChId ].SetPrevLevel ( dCurLevel );
|
||||||
|
|
||||||
|
// logarithmic measure
|
||||||
|
const double dNormChanLevel = dCurLevel / _MAXSHORT;
|
||||||
|
double dCurSigLevel;
|
||||||
|
if ( dNormChanLevel > 0 )
|
||||||
|
{
|
||||||
|
dCurSigLevel = 20.0 * log10 ( dNormChanLevel );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dCurSigLevel = -100000.0; // large negative value
|
||||||
|
}
|
||||||
|
|
||||||
|
// map to signal level meter
|
||||||
|
dCurSigLevel -= LOW_BOUND_SIG_METER;
|
||||||
|
dCurSigLevel *= NUM_STEPS_LED_BAR /
|
||||||
|
( UPPER_BOUND_SIG_METER - LOW_BOUND_SIG_METER );
|
||||||
|
|
||||||
|
if ( dCurSigLevel < 0 )
|
||||||
|
{
|
||||||
|
dCurSigLevel = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
vecLevelsOut[j] = static_cast<uint16_t> ( ceil ( dCurSigLevel ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
12
src/server.h
|
@ -28,6 +28,7 @@
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QHostAddress>
|
#include <QHostAddress>
|
||||||
|
#include <algorithm>
|
||||||
#ifdef USE_OPUS_SHARED_LIB
|
#ifdef USE_OPUS_SHARED_LIB
|
||||||
# include "opus/opus_custom.h"
|
# include "opus/opus_custom.h"
|
||||||
#else
|
#else
|
||||||
|
@ -225,6 +226,11 @@ protected:
|
||||||
// if server mode is normal or double system frame size
|
// if server mode is normal or double system frame size
|
||||||
bool bUseDoubleSystemFrameSize;
|
bool bUseDoubleSystemFrameSize;
|
||||||
|
|
||||||
|
void CreateLevelsForAllConChannels ( const int iNumClients,
|
||||||
|
const CVector<int>& vecNumAudioChannels,
|
||||||
|
const CVector<CVector<int16_t> > vecvecsData,
|
||||||
|
CVector<uint16_t>& vecLevelsOut );
|
||||||
|
|
||||||
// do not use the vector class since CChannel does not have appropriate
|
// do not use the vector class since CChannel does not have appropriate
|
||||||
// copy constructor/operator
|
// copy constructor/operator
|
||||||
CChannel vecChannels[MAX_NUM_CHANNELS];
|
CChannel vecChannels[MAX_NUM_CHANNELS];
|
||||||
|
@ -255,12 +261,18 @@ protected:
|
||||||
CVector<int16_t> vecsSendData;
|
CVector<int16_t> vecsSendData;
|
||||||
CVector<uint8_t> vecbyCodedData;
|
CVector<uint8_t> vecbyCodedData;
|
||||||
|
|
||||||
|
// Channel levels
|
||||||
|
CVector<uint16_t> vecChannelLevels;
|
||||||
|
|
||||||
// actual working objects
|
// actual working objects
|
||||||
CHighPrioSocket Socket;
|
CHighPrioSocket Socket;
|
||||||
|
|
||||||
// logging
|
// logging
|
||||||
CServerLogging Logging;
|
CServerLogging Logging;
|
||||||
|
|
||||||
|
// channel level update frame interval counter
|
||||||
|
uint16_t iFrameCount;
|
||||||
|
|
||||||
// recording thread
|
// recording thread
|
||||||
recorder::CJamRecorder JamRecorder;
|
recorder::CJamRecorder JamRecorder;
|
||||||
bool bEnableRecording;
|
bool bEnableRecording;
|
||||||
|
|
|
@ -250,6 +250,12 @@ void CSettings::Load()
|
||||||
pClient->SetGUIDesign ( static_cast<EGUIDesign> ( iValue ) );
|
pClient->SetGUIDesign ( static_cast<EGUIDesign> ( iValue ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// display channel levels preference
|
||||||
|
if ( GetFlagIniSet ( IniXMLDocument, "client", "displaychannellevels", bValue ) )
|
||||||
|
{
|
||||||
|
pClient->SetDisplayChannelLevels ( bValue );
|
||||||
|
}
|
||||||
|
|
||||||
// audio channels
|
// audio channels
|
||||||
if ( GetNumericIniSet ( IniXMLDocument, "client", "audiochannels",
|
if ( GetNumericIniSet ( IniXMLDocument, "client", "audiochannels",
|
||||||
0, 2 /* CC_STEREO */, iValue ) )
|
0, 2 /* CC_STEREO */, iValue ) )
|
||||||
|
@ -490,6 +496,10 @@ void CSettings::Save()
|
||||||
SetNumericIniSet ( IniXMLDocument, "client", "guidesign",
|
SetNumericIniSet ( IniXMLDocument, "client", "guidesign",
|
||||||
static_cast<int> ( pClient->GetGUIDesign() ) );
|
static_cast<int> ( pClient->GetGUIDesign() ) );
|
||||||
|
|
||||||
|
// display channel levels preference
|
||||||
|
SetFlagIniSet ( IniXMLDocument, "client", "displaychannellevels",
|
||||||
|
pClient->GetDisplayChannelLevels() );
|
||||||
|
|
||||||
// audio channels
|
// audio channels
|
||||||
SetNumericIniSet ( IniXMLDocument, "client", "audiochannels",
|
SetNumericIniSet ( IniXMLDocument, "client", "audiochannels",
|
||||||
static_cast<int> ( pClient->GetAudioChannels() ) );
|
static_cast<int> ( pClient->GetAudioChannels() ) );
|
||||||
|
|