From 9eb7bb9e1f78bf27c2702a6cf67cca8adf9a4776 Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Sun, 2 Aug 2009 17:44:45 +0000 Subject: [PATCH] some GUI work --- src/buffer.cpp | 26 ++++++----- src/client.cpp | 36 ++++++++------- src/clientsettingsdlg.cpp | 75 +++++++++++++++++------------- src/clientsettingsdlg.h | 20 ++++---- src/clientsettingsdlgbase.ui | 90 ++++++++---------------------------- src/global.h | 7 +++ src/settings.cpp | 11 ++++- src/util.h | 89 ++++++++++++++++++----------------- 8 files changed, 167 insertions(+), 187 deletions(-) diff --git a/src/buffer.cpp b/src/buffer.cpp index cab70344..a46bff33 100755 --- a/src/buffer.cpp +++ b/src/buffer.cpp @@ -29,7 +29,8 @@ /* Implementation *************************************************************/ -void CNetBuf::Init ( const int iNewBlockSize, const int iNewNumBlocks ) +void CNetBuf::Init ( const int iNewBlockSize, + const int iNewNumBlocks ) { // total size -> size of one block times number of blocks iBlockSize = iNewBlockSize; @@ -226,24 +227,25 @@ int CNetBuf::GetAvailData() const void CNetBuf::Clear ( const EClearType eClearType ) { + int iMiddleOfBuffer = 0; - int iMiddleOfBuffer; - + if ( iBlockSize != 0 ) + { #if 0 - /* with the following operation we set the new get pos to a block - boundary (one block below the middle of the buffer in case of odd - number of blocks, e.g.: - [buffer size]: [get pos] - 1: 0 / 2: 0 / 3: 1 / 4: 1 / ... */ - iMiddleOfBuffer = ( ( ( iMemSize - iBlockSize) / 2 ) / iBlockSize ) * iBlockSize; + /* with the following operation we set the new get pos to a block + boundary (one block below the middle of the buffer in case of odd + number of blocks, e.g.: + [buffer size]: [get pos] + 1: 0 / 2: 0 / 3: 1 / 4: 1 / ... */ + iMiddleOfBuffer = ( ( ( iMemSize - iBlockSize) / 2 ) / iBlockSize ) * iBlockSize; #else // old code // somehow the old code seems to work better than the sophisticated new one....? - /* 1: 0 / 2: 1 / 3: 1 / 4: 2 / ... */ - iMiddleOfBuffer = ( ( iMemSize / 2 ) / iBlockSize ) * iBlockSize; + /* 1: 0 / 2: 1 / 3: 1 / 4: 2 / ... */ + iMiddleOfBuffer = ( ( iMemSize / 2 ) / iBlockSize ) * iBlockSize; #endif - + } // different behaviour for get and put corrections if ( eClearType == CT_GET ) diff --git a/src/client.cpp b/src/client.cpp index 4148b675..89223580 100755 --- a/src/client.cpp +++ b/src/client.cpp @@ -36,7 +36,7 @@ CClient::CClient ( const quint16 iPortNumber ) : vstrIPAddress ( MAX_NUM_SERVER_ADDR_ITEMS, "" ), strName ( "" ), bOpenChatOnNewMessage ( true ), bDoAutoSockBufSize ( true ), - iSndCrdPreferredMonoBlSizeIndex ( CSndCrdBufferSizes::GetDefaultIndex() ) + iSndCrdPreferredMonoBlSizeIndex ( FRAME_SIZE_FACTOR_DEFAULT ) { // connection for protocol QObject::connect ( &Channel, @@ -148,25 +148,27 @@ bool CClient::SetServerAddr ( QString strNAddr ) void CClient::SetSndCrdPreferredMonoBlSizeIndex ( const int iNewIdx ) { // right now we simply set the internal value - if ( ( iNewIdx >= 0 ) && ( CSndCrdBufferSizes::GetNumOfBufferSizes() ) ) + if ( ( iNewIdx == FRAME_SIZE_FACTOR_PREFERRED ) || + ( iNewIdx == FRAME_SIZE_FACTOR_DEFAULT ) || + ( iNewIdx == FRAME_SIZE_FACTOR_SAFE ) ) { iSndCrdPreferredMonoBlSizeIndex = iNewIdx; - } - // init with new parameter, if client was running then first - // stop it and restart again after new initialization - const bool bWasRunning = Sound.IsRunning(); - if ( bWasRunning ) - { - Sound.Stop(); - } + // init with new parameter, if client was running then first + // stop it and restart again after new initialization + const bool bWasRunning = Sound.IsRunning(); + if ( bWasRunning ) + { + Sound.Stop(); + } - // init with new block size index parameter - Init ( iSndCrdPreferredMonoBlSizeIndex ); + // init with new block size index parameter + Init ( iSndCrdPreferredMonoBlSizeIndex ); - if ( bWasRunning ) - { - Sound.Start(); + if ( bWasRunning ) + { + Sound.Start(); + } } } @@ -259,8 +261,8 @@ void CClient::AudioCallback ( CVector& psData, void* arg ) void CClient::Init ( const int iPrefMonoBlockSizeSamIndexAtSndCrdSamRate ) { // translate block size index in actual block size - const int iPrefMonoBlockSizeSamAtSndCrdSamRate = CSndCrdBufferSizes:: - GetBufferSizeFromIndex ( iPrefMonoBlockSizeSamIndexAtSndCrdSamRate ); + const int iPrefMonoBlockSizeSamAtSndCrdSamRate = + iPrefMonoBlockSizeSamIndexAtSndCrdSamRate * SYSTEM_BLOCK_FRAME_SAMPLES; // get actual sound card buffer size using preferred size iMonoBlockSizeSam = Sound.Init ( iPrefMonoBlockSizeSamAtSndCrdSamRate ); diff --git a/src/clientsettingsdlg.cpp b/src/clientsettingsdlg.cpp index 971ed511..522beea5 100755 --- a/src/clientsettingsdlg.cpp +++ b/src/clientsettingsdlg.cpp @@ -65,11 +65,6 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent, SliderNetBuf->setRange ( MIN_NET_BUF_SIZE_NUM_BL, MAX_NET_BUF_SIZE_NUM_BL ); UpdateJitterBufferFrame(); - // sound card buffer size - SliderSndCrdBufferDelay->setRange ( 0, - CSndCrdBufferSizes::GetNumOfBufferSizes() - 1 ); - SliderSndCrdBufferDelay->setPageStep ( 1 ); // improves setting with a mouse click - // init combo box containing all available sound cards in the system cbSoundcard->clear(); for ( int iSndDevIdx = 0; iSndDevIdx < pClient->GetSndCrdNumDev(); iSndDevIdx++ ) @@ -88,26 +83,38 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent, cbOpenChatOnNewMessage->setCheckState ( Qt::Unchecked ); } - // audio compression type + // set text for sound card buffer delay radio buttons + rButBufferDelayPreferred->setText ( GenSndCrdBufferDelayString ( + FRAME_SIZE_FACTOR_PREFERRED * SYSTEM_BLOCK_FRAME_SAMPLES, + ", preferred" ) ); + + rButBufferDelayDefault->setText ( GenSndCrdBufferDelayString ( + FRAME_SIZE_FACTOR_DEFAULT * SYSTEM_BLOCK_FRAME_SAMPLES, + ", default" ) ); + + rButBufferDelaySafe->setText ( GenSndCrdBufferDelayString ( + FRAME_SIZE_FACTOR_SAFE * SYSTEM_BLOCK_FRAME_SAMPLES ) ); + /* - switch ( pClient->GetAudioCompressionOut() ) + // sound card buffer delay + switch ( pClient->[]() ) { case CT_NONE: - radioButtonNoAudioCompr->setChecked ( true ); + rButBufferDelayPreferred->setChecked ( true ); break; case CT_IMAADPCM: - radioButtonIMA_ADPCM->setChecked ( true ); + rButBufferDelayDefault->setChecked ( true ); break; case CT_MSADPCM: - radioButtonMS_ADPCM->setChecked ( true ); + rButBufferDelaySafe->setChecked ( true ); break; } */ - AudioCompressionButtonGroup.addButton ( radioButtonNoAudioCompr ); - AudioCompressionButtonGroup.addButton ( radioButtonIMA_ADPCM ); - AudioCompressionButtonGroup.addButton ( radioButtonMS_ADPCM ); + SndCrdBufferDelayButtonGroup.addButton ( rButBufferDelayPreferred ); + SndCrdBufferDelayButtonGroup.addButton ( rButBufferDelayDefault ); + SndCrdBufferDelayButtonGroup.addButton ( rButBufferDelaySafe ); // Connections ------------------------------------------------------------- @@ -120,8 +127,6 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent, // slider controls QObject::connect ( SliderNetBuf, SIGNAL ( valueChanged ( int ) ), this, SLOT ( OnSliderNetBuf ( int ) ) ); - QObject::connect ( SliderSndCrdBufferDelay, SIGNAL ( valueChanged ( int ) ), - this, SLOT ( OnSliderSndCrdBufferDelay ( int ) ) ); // check boxes QObject::connect ( cbOpenChatOnNewMessage, SIGNAL ( stateChanged ( int ) ), @@ -141,9 +146,9 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent, QObject::connect ( pClient, SIGNAL ( PingTimeReceived ( int ) ), this, SLOT ( OnPingTimeResult ( int ) ) ); - QObject::connect ( &AudioCompressionButtonGroup, + QObject::connect ( &SndCrdBufferDelayButtonGroup, SIGNAL ( buttonClicked ( QAbstractButton* ) ), this, - SLOT ( OnAudioCompressionButtonGroupClicked ( QAbstractButton* ) ) ); + SLOT ( OnSndCrdBufferDelayButtonGroupClicked ( QAbstractButton* ) ) ); // Timers ------------------------------------------------------------------ @@ -164,31 +169,35 @@ void CClientSettingsDlg::UpdateJitterBufferFrame() TextNetBuf->setEnabled ( !pClient->GetDoAutoSockBufSize() ); } +QString CClientSettingsDlg::GenSndCrdBufferDelayString ( const int iFrameSize, + const QString strAddText ) +{ + // use two times the buffer delay for the entire delay since + // we have input and output + return QString().setNum ( (double) iFrameSize * 2 * + 1000 / SYSTEM_SAMPLE_RATE, 'f', 2 ) + " ms (" + + QString().setNum ( iFrameSize ) + strAddText + ")"; +} + void CClientSettingsDlg::UpdateSoundCardFrame() { // update slider value and text const int iCurPrefBufIdx = pClient->GetSndCrdPreferredMonoBlSizeIndex(); const int iCurActualBufSize = pClient->GetSndCrdActualMonoBlSize(); + +/* SliderSndCrdBufferDelay->setValue ( iCurPrefBufIdx ); // preferred size const int iPrefBufSize = CSndCrdBufferSizes::GetBufferSizeFromIndex ( iCurPrefBufIdx ); - - // use two times the buffer delay for the entire delay since - // we have input and output - TextLabelPreferredSndCrdBufDelay->setText ( - QString().setNum ( (double) iPrefBufSize * 2 * - 1000 / SYSTEM_SAMPLE_RATE, 'f', 2 ) + " ms (" + - QString().setNum ( iPrefBufSize ) + ")" ); - +*/ // actual size (use yellow color if different from preferred size) const QString strActSizeValues = - QString().setNum ( (double) iCurActualBufSize * 2 * - 1000 / SYSTEM_SAMPLE_RATE, 'f', 2 ) + " ms (" + - QString().setNum ( iCurActualBufSize ) + ")"; + GenSndCrdBufferDelayString ( iCurActualBufSize ); - if ( iPrefBufSize != iCurActualBufSize ) +// if ( iPrefBufSize != iCurActualBufSize ) +if ( 0 ) // TEST { TextLabelActualSndCrdBufDelay->setText ( "" + strActSizeValues + "" ); @@ -259,20 +268,20 @@ void CClientSettingsDlg::OnOpenChatOnNewMessageStateChanged ( int value ) UpdateDisplay(); } -void CClientSettingsDlg::OnAudioCompressionButtonGroupClicked ( QAbstractButton* button ) +void CClientSettingsDlg::OnSndCrdBufferDelayButtonGroupClicked ( QAbstractButton* button ) { /* - if ( button == radioButtonNoAudioCompr ) + if ( button == rButBufferDelayPreferred ) { pClient->SetAudioCompressionOut ( CT_NONE ); } - if ( button == radioButtonIMA_ADPCM ) + if ( button == rButBufferDelayDefault ) { pClient->SetAudioCompressionOut ( CT_IMAADPCM ); } - if ( button == radioButtonMS_ADPCM ) + if ( button == rButBufferDelaySafe ) { pClient->SetAudioCompressionOut ( CT_MSADPCM ); } diff --git a/src/clientsettingsdlg.h b/src/clientsettingsdlg.h index e2826f2f..fbafb75d 100755 --- a/src/clientsettingsdlg.h +++ b/src/clientsettingsdlg.h @@ -62,26 +62,28 @@ public: void SetStatus ( const int iMessType, const int iStatus ); protected: - CClient* pClient; - QTimer TimerStatus; - QTimer TimerPing; - QButtonGroup AudioCompressionButtonGroup; - void UpdateDisplay(); + void UpdateJitterBufferFrame(); + void UpdateSoundCardFrame(); + QString GenSndCrdBufferDelayString ( const int iFrameSize, + const QString strAddText = "" ); virtual void showEvent ( QShowEvent* showEvent ); virtual void hideEvent ( QHideEvent* hideEvent ); - void UpdateJitterBufferFrame(); - void UpdateSoundCardFrame(); + CClient* pClient; + QTimer TimerStatus; + QTimer TimerPing; + QButtonGroup SndCrdBufferDelayButtonGroup; + void UpdateDisplay(); -public slots: + public slots: void OnTimerStatus() { UpdateDisplay(); } void OnTimerPing(); void OnSliderNetBuf ( int value ); void OnSliderSndCrdBufferDelay ( int value ); void OnAutoJitBuf ( int value ); void OnOpenChatOnNewMessageStateChanged ( int value ); - void OnAudioCompressionButtonGroupClicked ( QAbstractButton* button ); + void OnSndCrdBufferDelayButtonGroupClicked ( QAbstractButton* button ); void OnPingTimeResult ( int iPingTime ); void OnSoundCrdSelection ( int iSndDevIdx ); void OnDriverSetupBut(); diff --git a/src/clientsettingsdlgbase.ui b/src/clientsettingsdlgbase.ui index c5e3f058..d9be6dff 100755 --- a/src/clientsettingsdlgbase.ui +++ b/src/clientsettingsdlgbase.ui @@ -212,8 +212,8 @@ - 201 - 20 + 71 + 16 @@ -225,54 +225,32 @@ - - - Qt::Horizontal + + + (preferred) - - QSlider::TicksBelow + + + + + + (default) + + + + + + + (safe) - - - - - - Preferred - - - true - - - - - - - - 110 - 20 - - - - QFrame::Panel - - - QFrame::Sunken - - - val - - - - - - Actual + Actual Value @@ -323,36 +301,6 @@ - - - - Audio Compression - - - - - - IMA ADPCM - - - - - - - MS ADPCM - - - - - - - None - - - - - - diff --git a/src/global.h b/src/global.h index f8ff6908..91b24562 100755 --- a/src/global.h +++ b/src/global.h @@ -66,6 +66,13 @@ ( static_cast ( SYSTEM_BLOCK_FRAME_SAMPLES ) / \ SYSTEM_SAMPLE_RATE * 1000 ) +// define the allowed audio frame size factors (since the +// "SYSTEM_BLOCK_FRAME_SAMPLES" is quite small, it may be that on some +// computers a larger value is required) +#define FRAME_SIZE_FACTOR_PREFERRED 1 // 128 (for frame size 128) +#define FRAME_SIZE_FACTOR_DEFAULT 2 // 256 (for frame size 128) +#define FRAME_SIZE_FACTOR_SAFE 4 // 512 (for frame size 128) + // define the maximum mono audio buffer size at a sample rate // of 48 kHz, this is important for defining the maximum number // of bytes to be expected from the network interface diff --git a/src/settings.cpp b/src/settings.cpp index 75312758..5f104f60 100755 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -110,9 +110,16 @@ void CSettings::ReadIniFile ( const QString& sFileName ) // sound card preferred buffer size index if ( GetNumericIniSet ( IniXMLDocument, "client", "prefsndcrdbufidx", - 0, CSndCrdBufferSizes::GetNumOfBufferSizes(), iValue ) ) + FRAME_SIZE_FACTOR_PREFERRED, FRAME_SIZE_FACTOR_SAFE, iValue ) ) { - pClient->SetSndCrdPreferredMonoBlSizeIndex ( iValue ); + // additional check required since only a subset of factors are + // defined + if ( ( iValue == FRAME_SIZE_FACTOR_PREFERRED ) || + ( iValue == FRAME_SIZE_FACTOR_DEFAULT ) || + ( iValue == FRAME_SIZE_FACTOR_SAFE ) ) + { + pClient->SetSndCrdPreferredMonoBlSizeIndex ( iValue ); + } } // automatic network jitter buffer size setting diff --git a/src/util.h b/src/util.h index 7ab6f154..5c7a83eb 100755 --- a/src/util.h +++ b/src/util.h @@ -379,15 +379,23 @@ protected: class CHostAddress { public: - CHostAddress() : InetAddr ( (quint32) 0 ), iPort ( 0 ) {} - CHostAddress ( const QHostAddress NInetAddr, const quint16 iNPort ) : - InetAddr ( NInetAddr ), iPort ( iNPort ) {} + CHostAddress() : + InetAddr ( (quint32) 0 ), + iPort ( 0 ) {} + + CHostAddress ( const QHostAddress NInetAddr, + const quint16 iNPort ) : + InetAddr ( NInetAddr ), + iPort ( iNPort ) {} + CHostAddress ( const CHostAddress& NHAddr ) : - InetAddr ( NHAddr.InetAddr ), iPort ( NHAddr.iPort ) {} + InetAddr ( NHAddr.InetAddr ), + iPort ( NHAddr.iPort ) {} // copy and compare operators CHostAddress& operator= ( const CHostAddress& NHAddr ) { InetAddr = NHAddr.InetAddr; iPort = NHAddr.iPort; return *this; } + bool operator== ( const CHostAddress& CompAddr ) // compare operator { return ( ( CompAddr.InetAddr == InetAddr ) && ( CompAddr.iPort == iPort ) ); } @@ -397,16 +405,24 @@ public: return InetAddr.toString().section ( ".", 0, 2 ) + ".x"; } - QHostAddress InetAddr; - quint16 iPort; + QHostAddress InetAddr; + quint16 iPort; }; class CChannelShortInfo { public: - CChannelShortInfo() : iChanID ( 0 ), iIpAddr ( 0 ), strName ( "" ) {} - CChannelShortInfo ( const int iNID, const quint32 nIP, const QString nN ) : - iChanID ( iNID ), iIpAddr ( nIP ), strName ( nN ) {} + CChannelShortInfo() : + iChanID ( 0 ), + iIpAddr ( 0 ), + strName ( "" ) {} + + CChannelShortInfo ( const int iNID, + const quint32 nIP, + const QString nN ) : + iChanID ( iNID ), + iIpAddr ( nIP ), + strName ( nN ) {} int iChanID; quint32 iIpAddr; @@ -430,17 +446,28 @@ enum EGetDataStat class CNetworkTransportProps { public: - CNetworkTransportProps() : iNetworkPacketSize ( 0 ), iBlockSizeFact ( 0 ), - iNumAudioChannels ( 0 ), iSampleRate ( 0 ), - eAudioCodingType ( CT_NONE ), iAudioCodingArg ( 0 ) {} + CNetworkTransportProps() : + iNetworkPacketSize ( 0 ), + iBlockSizeFact ( 0 ), + iNumAudioChannels ( 0 ), + iSampleRate ( 0 ), + eAudioCodingType ( CT_NONE ), + iAudioCodingArg ( 0 ) {} - CNetworkTransportProps ( const uint32_t iNNPS, const uint16_t iNBSF, - const uint32_t iNNACH, const uint32_t iNSR, - const EAudComprType eNACT, const uint32_t iNVers, const int32_t iNACA ) : - iNetworkPacketSize ( iNNPS ), iBlockSizeFact ( iNBSF ), - iNumAudioChannels ( iNNACH ), iSampleRate ( iNSR ), - eAudioCodingType ( eNACT ), iVersion ( iNVers ), - iAudioCodingArg ( iNACA ) {} + CNetworkTransportProps ( const uint32_t iNNPS, + const uint16_t iNBSF, + const uint32_t iNNACH, + const uint32_t iNSR, + const EAudComprType eNACT, + const uint32_t iNVers, + const int32_t iNACA ) : + iNetworkPacketSize ( iNNPS ), + iBlockSizeFact ( iNBSF ), + iNumAudioChannels ( iNNACH ), + iSampleRate ( iNSR ), + eAudioCodingType ( eNACT ), + iVersion ( iNVers ), + iAudioCodingArg ( iNACA ) {} uint32_t iNetworkPacketSize; uint16_t iBlockSizeFact; @@ -451,30 +478,6 @@ public: int32_t iAudioCodingArg; }; -class CSndCrdBufferSizes -{ -public: - // we use a conservative value as default, this value does not - // give perfekt latency results but should work ok on most - // sound cards and drivers - static int GetDefaultIndex() { return 1; } - - static int GetNumOfBufferSizes() { return 4; } - static int GetBufferSizeFromIndex ( const int iIdx ) - { - if ( ( iIdx >= 0 ) && ( iIdx < 4 ) ) - { - const int pSizes[4] = { 128, 256, 512, 1024 }; - - return pSizes[iIdx]; - } - else - { - return 0; - } - } -}; - // Audio Reverbration ---------------------------------------------------------- class CAudioReverb