From d3b9f90f45013b7b5ec8bd1f07062d99eb9aa3ef Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Mon, 2 May 2011 19:48:36 +0000 Subject: [PATCH] added central server setting --- src/client.cpp | 42 +- src/client.h | 16 +- src/clientsettingsdlg.cpp | 1409 ++++++++++++++++++---------------- src/clientsettingsdlg.h | 3 + src/clientsettingsdlgbase.ui | 51 +- src/connectdlg.cpp | 14 +- src/connectdlg.h | 6 +- src/connectdlgbase.ui | 9 + src/llconclientdlg.cpp | 22 +- src/llconclientdlg.h | 1 - src/llconserverdlg.cpp | 9 +- src/settings.cpp | 18 + 12 files changed, 885 insertions(+), 715 deletions(-) diff --git a/src/client.cpp b/src/client.cpp index d78968fe..3f067b70 100755 --- a/src/client.cpp +++ b/src/client.cpp @@ -27,27 +27,29 @@ /* Implementation *************************************************************/ CClient::CClient ( const quint16 iPortNumber ) : - vstrIPAddress ( MAX_NUM_SERVER_ADDR_ITEMS, "" ), - strName ( "" ), - Channel ( false ), /* we need a client channel -> "false" */ - bDoAutoSockBufSize ( true ), - iCeltNumCodedBytes ( CELT_NUM_BYTES_MONO_NORMAL_QUALITY ), - bCeltDoHighQuality ( false ), - bUseStereo ( false ), - Socket ( &Channel, &ConnLessProtocol, iPortNumber ), - Sound ( AudioCallback, this ), - iAudioInFader ( AUD_FADER_IN_MIDDLE ), - bReverbOnLeftChan ( false ), - iReverbLevel ( 0 ), - iSndCrdPrefFrameSizeFactor ( FRAME_SIZE_FACTOR_PREFERRED ), - iSndCrdFrameSizeFactor ( FRAME_SIZE_FACTOR_PREFERRED ), - bSndCrdConversionBufferRequired ( false ), + vstrIPAddress ( MAX_NUM_SERVER_ADDR_ITEMS, "" ), + strName ( "" ), + Channel ( false ), /* we need a client channel -> "false" */ + bDoAutoSockBufSize ( true ), + iCeltNumCodedBytes ( CELT_NUM_BYTES_MONO_NORMAL_QUALITY ), + bCeltDoHighQuality ( false ), + bUseStereo ( false ), + Socket ( &Channel, &ConnLessProtocol, iPortNumber ), + Sound ( AudioCallback, this ), + iAudioInFader ( AUD_FADER_IN_MIDDLE ), + bReverbOnLeftChan ( false ), + iReverbLevel ( 0 ), + iSndCrdPrefFrameSizeFactor ( FRAME_SIZE_FACTOR_PREFERRED ), + iSndCrdFrameSizeFactor ( FRAME_SIZE_FACTOR_PREFERRED ), + bSndCrdConversionBufferRequired ( false ), iSndCardMonoBlockSizeSamConvBuff ( 0 ), - bFraSiFactPrefSupported ( false ), - bFraSiFactDefSupported ( false ), - bFraSiFactSafeSupported ( false ), - bOpenChatOnNewMessage ( true ), - eGUIDesign ( GD_ORIGINAL ) + bFraSiFactPrefSupported ( false ), + bFraSiFactDefSupported ( false ), + bFraSiFactSafeSupported ( false ), + bOpenChatOnNewMessage ( true ), + eGUIDesign ( GD_ORIGINAL ), + strCentralServerAddress ( "" ), + bUseDefaultCentralServerAddress ( true ) { // init audio encoder/decoder (mono) CeltModeMono = celt_mode_create ( diff --git a/src/client.h b/src/client.h index 64d65549..4f94acc1 100755 --- a/src/client.h +++ b/src/client.h @@ -106,6 +106,18 @@ public: bool GetUseStereo() const { return bUseStereo; } void SetUseStereo ( const bool bNUseStereo ); + void SetServerListCentralServerAddress ( const QString& sNCentServAddr ) + { strCentralServerAddress = sNCentServAddr; } + + QString GetServerListCentralServerAddress() + { return strCentralServerAddress; } + + void SetUseDefaultCentralServerAddress ( const bool bNUDCSeAddr ) + { bUseDefaultCentralServerAddress = bNUDCSeAddr; } + + bool GetUseDefaultCentralServerAddress() + { return bUseDefaultCentralServerAddress; } + int GetAudioInFader() const { return iAudioInFader; } void SetAudioInFader ( const int iNV ) { iAudioInFader = iNV; } @@ -290,6 +302,9 @@ protected: bool bOpenChatOnNewMessage; EGUIDesign eGUIDesign; + QString strCentralServerAddress; + bool bUseDefaultCentralServerAddress; + CVector vecsAudioSndCrdMono; CVector vecdAudioStereo; CVector vecsNetwork; @@ -323,7 +338,6 @@ signals: int iPingTime, int iNumClients ); void Disconnected(); - void Stopped(); }; #endif /* !defined ( CLIENT_HOIHGE76GEKJH98_3_43445KJIUHF1912__INCLUDED_ ) */ diff --git a/src/clientsettingsdlg.cpp b/src/clientsettingsdlg.cpp index dee65ddf..7f5aed10 100755 --- a/src/clientsettingsdlg.cpp +++ b/src/clientsettingsdlg.cpp @@ -1,665 +1,744 @@ -/******************************************************************************\ - * Copyright (c) 2004-2011 - * - * Author(s): - * Volker Fischer - * - ****************************************************************************** - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * -\******************************************************************************/ - -#include "clientsettingsdlg.h" - - -/* Implementation *************************************************************/ -CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent, - Qt::WindowFlags f ) : QDialog ( parent, f ), pClient ( pNCliP ) -{ - setupUi ( this ); - - - // Add help text to controls ----------------------------------------------- - // jitter buffer - QString strJitterBufferSize = tr ( "Jitter Buffer Size: The jitter " - "buffer compensates for network and sound card timing jitters. The " - "size of this jitter buffer has therefore influence on the quality of " - "the audio stream (how many dropouts occur) and the overall delay " - "(the longer the buffer, the higher the delay).
" - "Dropouts in the audio stream are indicated by the light on the bottom " - "of the jitter buffer size fader. If the light turns to red, a buffer " - "overrun/underrun took place and the audio stream is interrupted.
" - "The jitter buffer setting is therefore a trade-off between audio " - "quality and overall delay.
" - "An auto setting of the jitter buffer size setting is available. If " - "the check Auto is enabled, the jitter buffer is set automatically " - "based on measurements of the network and sound card timing jitter. If " - "the Auto check is enabled, the jitter buffer size fader is disabled " - "(it cannot be moved by the mouse)." ); - - QString strJitterBufferSizeTT = tr ( "In case the Auto setting of the " - "jitter buffer is enabled, the network buffer is set to a conservative " - "value to minimize the audio dropout probability. To tweak the " - "audio delay/latency it is recommended to disable the Auto " - "functionality and to lower the jitter buffer size manually by " - "using the slider until your personal acceptable limit of the amount " - "of dropouts is reached. The LED indicator will visualize the audio " - "dropouts by a red light" ) + TOOLTIP_COM_END_TEXT; - - TextNetBuf->setWhatsThis ( strJitterBufferSize ); - TextNetBuf->setToolTip ( strJitterBufferSizeTT ); - GroupBoxJitterBuffer->setWhatsThis ( strJitterBufferSize ); - GroupBoxJitterBuffer->setToolTip ( strJitterBufferSizeTT ); - SliderNetBuf->setWhatsThis ( strJitterBufferSize ); - SliderNetBuf->setAccessibleName ( tr ( "Jitter buffer slider control" ) ); - SliderNetBuf->setToolTip ( strJitterBufferSizeTT ); - cbAutoJitBuf->setAccessibleName ( tr ( "Auto jitter buffer switch" ) ); - cbAutoJitBuf->setToolTip ( strJitterBufferSizeTT ); - CLEDNetw->setAccessibleName ( tr ( "Jitter buffer status LED indicator" ) ); - CLEDNetw->setToolTip ( strJitterBufferSizeTT ); - - // sound card device - cbSoundcard->setWhatsThis ( tr ( "Sound Card Device: The ASIO " - "driver (sound card) can be selected using llcon under the Windows " - "operating system. Under Linux, no sound card selection is possible " - "(always wave mapper is shown and cannot be changed). If the selected " - "ASIO driver is not valid an error message is shown and the previous " - "valid driver is selected.
" - "If the driver is selected during an active connection, the connection " - "is stopped, the driver is changed and the connection is started again " - "automatically." ) ); - - cbSoundcard->setAccessibleName ( tr ( "Sound card device selector combo box" ) ); - - cbSoundcard->setToolTip ( tr ( "In case the ASIO4ALL driver is used, " - "please note that this driver usually introduces approx. 10-30 ms of " - "additional audio delay. Using a sound card with a native ASIO driver " - "is therefore recommended.
If you are using the kX ASIO " - "driver, make sure to connect the ASIO inputs in the kX DSP settings " - "panel." ) + TOOLTIP_COM_END_TEXT ); - - // sound card input/output channel mapping - QString strSndCrdChanMapp = tr ( "Sound Card Channel Mapping: " - "In case the selected sound card device offers more than one " - "input or output channel, the Input Channel Mapping and Ouptut " - "Channel Mapping settings are visible.
" - "For each " ) + APP_NAME + tr ( " input/output channel (Left and " - "Right channel) a different actual sound card channel can be " - "selected." ); - - lbInChannelMapping->setWhatsThis ( strSndCrdChanMapp ); - lbOutChannelMapping->setWhatsThis ( strSndCrdChanMapp ); - cbLInChan->setWhatsThis ( strSndCrdChanMapp ); - cbLInChan->setAccessibleName ( tr ( "Left input channel selection combo box" ) ); - cbRInChan->setWhatsThis ( strSndCrdChanMapp ); - cbRInChan->setAccessibleName ( tr ( "Right input channel selection combo box" ) ); - cbLOutChan->setWhatsThis ( strSndCrdChanMapp ); - cbLOutChan->setAccessibleName ( tr ( "Left output channel selection combo box" ) ); - cbROutChan->setWhatsThis ( strSndCrdChanMapp ); - cbROutChan->setAccessibleName ( tr ( "Right output channel selection combo box" ) ); - - // sound card buffer delay - QString strSndCrdBufDelay = tr ( "Sound Card Buffer Delay: The " - "buffer delay setting is a fundamental setting of the llcon software. " - "This setting has influence on many connection properties.
" - "Three buffer sizes are supported:" - "
    " - "
  • 128 samples: This is the preferred setting since it gives lowest " - "latency but does not work with all sound cards.
  • " - "
  • 256 samples: This is the default setting and should work on most " - "of the available sound cards.
  • " - "
  • 512 samples: This setting should only be used if only a very slow " - "computer or a slow internet connection is available.
  • " - "
" - "Some sound card driver do not allow the buffer delay to be changed " - "from within the llcon software. In this case the buffer delay setting " - "is disabled. To change the actual buffer delay, this " - "setting has to be changed in the sound card driver. On Windows, press " - "the ASIO Setup button to open the driver settings panel. On Linux, " - "use the Jack configuration tool to change the buffer size.
" - "If no buffer size is selected and all settings are disabled, an " - "unsupported buffer size is used by the driver. The llcon software " - "will still work with this setting but with restricted performannce.
" - "The actual buffer delay has influence on the connection status, the " - "current upload rate and the overall delay. The lower the buffer size, " - "the higher the probability of red light in the status indicator (drop " - "outs) and the higher the upload rate and the lower the overall " - "delay.
" - "The jitter buffer setting is therefore a trade-off between audio " - "quality and overall delay." ); - - QString strSndCrdBufDelayTT = tr ( "If the buffer delay settings are " - "disabled, it is prohibited by the audio driver to modify this " - "setting from within the llcon software. On Windows, press " - "the ASIO Setup button to open the driver settings panel. On Linux, " - "use the Jack configuration tool to change the buffer size." ) + - TOOLTIP_COM_END_TEXT; - - rButBufferDelayPreferred->setWhatsThis ( strSndCrdBufDelay ); - rButBufferDelayPreferred->setAccessibleName ( tr ( "128 samples setting radio button" ) ); - rButBufferDelayPreferred->setToolTip ( strSndCrdBufDelayTT ); - rButBufferDelayDefault->setWhatsThis ( strSndCrdBufDelay ); - rButBufferDelayDefault->setAccessibleName ( tr ( "256 samples setting radio button" ) ); - rButBufferDelayDefault->setToolTip ( strSndCrdBufDelayTT ); - rButBufferDelaySafe->setWhatsThis ( strSndCrdBufDelay ); - rButBufferDelaySafe->setAccessibleName ( tr ( "512 samples setting radio button" ) ); - rButBufferDelaySafe->setToolTip ( strSndCrdBufDelayTT ); - ButtonDriverSetup->setWhatsThis ( strSndCrdBufDelay ); - ButtonDriverSetup->setAccessibleName ( tr ( "ASIO setup push button" ) ); - ButtonDriverSetup->setToolTip ( strSndCrdBufDelayTT ); - - // open chat on new message - cbOpenChatOnNewMessage->setWhatsThis ( tr ( "Open Chat on New " - "Message: If this checkbox is enabled, the chat window will " - "open on any incoming chat text if it not already opened." ) ); - - cbOpenChatOnNewMessage->setAccessibleName ( tr ( "Open chat on new " - "message check box" ) ); - - cbOpenChatOnNewMessage->setToolTip ( tr ( "If Open Chat on New Message " - "is disabled, a LED in the main window turns green when a " - "new message has arrived." ) + TOOLTIP_COM_END_TEXT ); - - // use high quality audio - cbUseHighQualityAudio->setWhatsThis ( tr ( "Use High Quality Audio " - "Enabling ""Use High Quality Audio"" will improve the audio quality " - "by increasing the stream data rate. Make sure that the current " - "upload rate does not exceed the available bandwidth of your " - "internet connection." ) ); - - cbUseHighQualityAudio->setAccessibleName ( tr ( "Use high quality audio " - "check box" ) ); - - // use stereo - cbUseStereo->setWhatsThis ( tr ( "Stereo Streaming " - "Enables the stereo streaming mode. If not checked, a mono streaming " - "mode is used. Enabling the stereo streaming mode will increase the " - "stream data rate. Make sure that the current upload rate does not " - "exceed the available bandwidth of your internet connection.
" - "In case of the stereo streaming mode, no audio channel selection " - "for the reverberation effect will be available on the main window " - "since the effect is applied on both channels in this case." ) ); - - cbUseStereo->setAccessibleName ( tr ( "Stereo check box" ) ); - - // current connection status parameter - QString strConnStats = tr ( "Current Connection Status " - "Parameter: The ping time is the time required for the audio " - "stream to travel from the client to the server and backwards. This " - "delay is introduced by the network. This delay should be as low as " - "20-30 ms. If this delay is higher (e.g., 50-60 ms), your distance to " - "the server is too large or your internet connection is not " - "sufficient.
" - "The overall delay is calculated from the current ping time and the " - "delay which is introduced by the current buffer settings.
" - "The upstream rate depends on the current audio packet size and the " - "audio compression setting. Make sure that the upstream rate is not " - "higher than the available rate (check the upstream capabilities of " - "your internet connection by, e.g., using speedtest.net)." ); - - TextPingTime->setWhatsThis ( strConnStats ); - TextLabelPingTime->setWhatsThis ( strConnStats ); - TextOverallDelay->setWhatsThis ( strConnStats ); - TextLabelOverallDelay->setWhatsThis ( strConnStats ); - TextUpstream->setWhatsThis ( strConnStats ); - TextUpstreamValue->setWhatsThis ( strConnStats ); - CLEDOverallDelay->setWhatsThis ( strConnStats ); - CLEDOverallDelay->setToolTip ( tr ( "If this LED indicator turns red, " - "you will not have much fun using the llcon software." ) + - TOOLTIP_COM_END_TEXT ); - - - // init driver button -#ifdef _WIN32 - ButtonDriverSetup->setText ( "ASIO Setup" ); -#else - // no use for this button for Linux right now, maybe later used - // for Jack - ButtonDriverSetup->hide(); - - // for Jack interface, we cannot choose the audio hardware from - // within the llcon software, hide the combo box - TextSoundcardDevice->hide(); - cbSoundcard->hide(); -#endif - - // init delay and other information controls - CLEDOverallDelay->SetUpdateTime ( 2 * PING_UPDATE_TIME_MS ); - CLEDOverallDelay->Reset(); - TextLabelPingTime->setText ( "" ); - TextLabelOverallDelay->setText ( "" ); - TextUpstreamValue->setText ( "" ); - - - // init slider controls --- - // network buffer - SliderNetBuf->setRange ( MIN_NET_BUF_SIZE_NUM_BL, MAX_NET_BUF_SIZE_NUM_BL ); - UpdateJitterBufferFrame(); - - // init combo box containing all available sound cards in the system - cbSoundcard->clear(); - for ( int iSndDevIdx = 0; iSndDevIdx < pClient->GetSndCrdNumDev(); iSndDevIdx++ ) - { - cbSoundcard->addItem ( pClient->GetSndCrdDeviceName ( iSndDevIdx ) ); - } - cbSoundcard->setCurrentIndex ( pClient->GetSndCrdDev() ); - - // init sound card channel selection frame - UpdateSoundChannelSelectionFrame(); - - // "OpenChatOnNewMessage" check box - if ( pClient->GetOpenChatOnNewMessage() ) - { - cbOpenChatOnNewMessage->setCheckState ( Qt::Checked ); - } - else - { - cbOpenChatOnNewMessage->setCheckState ( Qt::Unchecked ); - } - - // fancy GUI design check box - if ( pClient->GetGUIDesign() == GD_STANDARD ) - { - cbGUIDesignFancy->setCheckState ( Qt::Unchecked ); - } - else - { - cbGUIDesignFancy->setCheckState ( Qt::Checked ); - } - - // "High Quality Audio" check box - if ( pClient->GetCELTHighQuality() ) - { - cbUseHighQualityAudio->setCheckState ( Qt::Checked ); - } - else - { - cbUseHighQualityAudio->setCheckState ( Qt::Unchecked ); - } - - // "Stereo" check box - if ( pClient->GetUseStereo() ) - { - cbUseStereo->setCheckState ( Qt::Checked ); - } - else - { - cbUseStereo->setCheckState ( Qt::Unchecked ); - } - - // set text for sound card buffer delay radio buttons - rButBufferDelayPreferred->setText ( GenSndCrdBufferDelayString ( - FRAME_SIZE_FACTOR_PREFERRED * SYSTEM_FRAME_SIZE_SAMPLES, - ", preferred" ) ); - - rButBufferDelayDefault->setText ( GenSndCrdBufferDelayString ( - FRAME_SIZE_FACTOR_DEFAULT * SYSTEM_FRAME_SIZE_SAMPLES, - ", default" ) ); - - rButBufferDelaySafe->setText ( GenSndCrdBufferDelayString ( - FRAME_SIZE_FACTOR_SAFE * SYSTEM_FRAME_SIZE_SAMPLES ) ); - - // sound card buffer delay inits - SndCrdBufferDelayButtonGroup.addButton ( rButBufferDelayPreferred ); - SndCrdBufferDelayButtonGroup.addButton ( rButBufferDelayDefault ); - SndCrdBufferDelayButtonGroup.addButton ( rButBufferDelaySafe ); - - UpdateSoundCardFrame(); - - - // Connections ------------------------------------------------------------- - // timers - QObject::connect ( &TimerStatus, SIGNAL ( timeout() ), - this, SLOT ( OnTimerStatus() ) ); - - // slider controls - QObject::connect ( SliderNetBuf, SIGNAL ( valueChanged ( int ) ), - this, SLOT ( OnSliderNetBuf ( int ) ) ); - - // check boxes - QObject::connect ( cbOpenChatOnNewMessage, SIGNAL ( stateChanged ( int ) ), - this, SLOT ( OnOpenChatOnNewMessageStateChanged ( int ) ) ); - - QObject::connect ( cbGUIDesignFancy, SIGNAL ( stateChanged ( int ) ), - this, SLOT ( OnGUIDesignFancyStateChanged ( int ) ) ); - - QObject::connect ( cbUseHighQualityAudio, SIGNAL ( stateChanged ( int ) ), - this, SLOT ( OnUseHighQualityAudioStateChanged ( int ) ) ); - - QObject::connect ( cbUseStereo, SIGNAL ( stateChanged ( int ) ), - this, SLOT ( OnUseStereoStateChanged ( int ) ) ); - - QObject::connect ( cbAutoJitBuf, SIGNAL ( stateChanged ( int ) ), - this, SLOT ( OnAutoJitBuf ( int ) ) ); - - // combo boxes - QObject::connect ( cbSoundcard, SIGNAL ( activated ( int ) ), - this, SLOT ( OnSoundCrdSelection ( int ) ) ); - - QObject::connect ( cbLInChan, SIGNAL ( activated ( int ) ), - this, SLOT ( OnSndCrdLeftInChannelSelection ( int ) ) ); - - QObject::connect ( cbRInChan, SIGNAL ( activated ( int ) ), - this, SLOT ( OnSndCrdRightInChannelSelection ( int ) ) ); - - QObject::connect ( cbLOutChan, SIGNAL ( activated ( int ) ), - this, SLOT ( OnSndCrdLeftOutChannelSelection ( int ) ) ); - - QObject::connect ( cbROutChan, SIGNAL ( activated ( int ) ), - this, SLOT ( OnSndCrdRightOutChannelSelection ( int ) ) ); - - // buttons - QObject::connect ( ButtonDriverSetup, SIGNAL ( clicked() ), - this, SLOT ( OnDriverSetupBut() ) ); - - // misc - QObject::connect ( &SndCrdBufferDelayButtonGroup, - SIGNAL ( buttonClicked ( QAbstractButton* ) ), this, - SLOT ( OnSndCrdBufferDelayButtonGroupClicked ( QAbstractButton* ) ) ); - - - // Timers ------------------------------------------------------------------ - // start timer for status bar - TimerStatus.start ( DISPLAY_UPDATE_TIME ); -} - -void CClientSettingsDlg::UpdateJitterBufferFrame() -{ - // update slider value and text - const int iCurNumNetBuf = pClient->GetSockBufNumFrames(); - SliderNetBuf->setValue ( iCurNumNetBuf ); - TextNetBuf->setText ( "Size: " + QString().setNum ( iCurNumNetBuf ) ); - - // if auto setting is enabled, disable slider control - cbAutoJitBuf->setChecked ( pClient->GetDoAutoSockBufSize() ); - SliderNetBuf->setEnabled ( !pClient->GetDoAutoSockBufSize() ); - 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_HZ, 'f', 2 ) + " ms (" + - QString().setNum ( iFrameSize ) + strAddText + ")"; -} - -void CClientSettingsDlg::UpdateSoundCardFrame() -{ - // get current actual buffer size value - const int iCurActualBufSize = - pClient->GetSndCrdActualMonoBlSize(); - - // Set radio buttons according to current value (To make it possible - // to have all radio buttons unchecked, we have to disable the - // exclusive check for the radio button group. We require all radio - // buttons to be unchecked in the case when the sound card does not - // support any of the buffer sizes and therefore all radio buttons - // are disabeld and unchecked.). - SndCrdBufferDelayButtonGroup.setExclusive ( false ); - - rButBufferDelayPreferred->setChecked ( iCurActualBufSize == - SYSTEM_FRAME_SIZE_SAMPLES * FRAME_SIZE_FACTOR_PREFERRED ); - - rButBufferDelayDefault->setChecked ( iCurActualBufSize == - SYSTEM_FRAME_SIZE_SAMPLES * FRAME_SIZE_FACTOR_DEFAULT ); - - rButBufferDelaySafe->setChecked ( iCurActualBufSize == - SYSTEM_FRAME_SIZE_SAMPLES * FRAME_SIZE_FACTOR_SAFE ); - - SndCrdBufferDelayButtonGroup.setExclusive ( true ); - - // disable radio buttons which are not supported by audio interface - rButBufferDelayPreferred->setEnabled ( - pClient->GetFraSiFactPrefSupported() ); - - rButBufferDelayDefault->setEnabled ( - pClient->GetFraSiFactDefSupported() ); - - rButBufferDelaySafe->setEnabled ( - pClient->GetFraSiFactSafeSupported() ); -} - -void CClientSettingsDlg::UpdateSoundChannelSelectionFrame() -{ -#ifdef _WIN32 - int iSndChanIdx; - - // Definition: The channel selection frame shall only be visible, - // if more than two input or output channels are available - const int iNumInChannels = pClient->GetSndCrdNumInputChannels(); - const int iNumOutChannels = pClient->GetSndCrdNumOutputChannels(); - - if ( ( iNumInChannels <= 2 ) && ( iNumOutChannels <= 2 ) ) - { - // as defined, make settings invisible - FrameSoundcardChannelSelection->setVisible ( false ); - } - else - { - // update combo boxes - FrameSoundcardChannelSelection->setVisible ( true ); - - // input - cbLInChan->clear(); - cbRInChan->clear(); - for ( iSndChanIdx = 0; iSndChanIdx < pClient->GetSndCrdNumInputChannels(); iSndChanIdx++ ) - { - cbLInChan->addItem ( pClient->GetSndCrdInputChannelName ( iSndChanIdx ) ); - cbRInChan->addItem ( pClient->GetSndCrdInputChannelName ( iSndChanIdx ) ); - } - cbLInChan->setCurrentIndex ( pClient->GetSndCrdLeftInputChannel() ); - cbRInChan->setCurrentIndex ( pClient->GetSndCrdRightInputChannel() ); - - // output - cbLOutChan->clear(); - cbROutChan->clear(); - for ( iSndChanIdx = 0; iSndChanIdx < pClient->GetSndCrdNumOutputChannels(); iSndChanIdx++ ) - { - cbLOutChan->addItem ( pClient->GetSndCrdOutputChannelName ( iSndChanIdx ) ); - cbROutChan->addItem ( pClient->GetSndCrdOutputChannelName ( iSndChanIdx ) ); - } - cbLOutChan->setCurrentIndex ( pClient->GetSndCrdLeftOutputChannel() ); - cbROutChan->setCurrentIndex ( pClient->GetSndCrdRightOutputChannel() ); - } -#else - // for other OS, no sound card channel selection is supported - FrameSoundcardChannelSelection->setVisible ( false ); -#endif -} - -void CClientSettingsDlg::OnDriverSetupBut() -{ - pClient->OpenSndCrdDriverSetup(); -} - -void CClientSettingsDlg::OnSliderNetBuf ( int value ) -{ - pClient->SetSockBufNumFrames ( value ); - UpdateJitterBufferFrame(); -} - -void CClientSettingsDlg::OnSliderSndCrdBufferDelay ( int value ) -{ - pClient->SetSndCrdPrefFrameSizeFactor ( value ); - UpdateDisplay(); -} - -void CClientSettingsDlg::OnSoundCrdSelection ( int iSndDevIdx ) -{ - const QString strError = pClient->SetSndCrdDev ( iSndDevIdx ); - - if ( !strError.isEmpty() ) - { - QMessageBox::critical ( this, APP_NAME, - QString ( tr ( "The selected audio device could not be used " - "because of the following error: " ) ) + strError + - QString ( tr ( " The previous driver will be selected." ) ), - "Ok", 0 ); - - // recover old selection - cbSoundcard->setCurrentIndex ( pClient->GetSndCrdDev() ); - } - UpdateSoundChannelSelectionFrame(); - UpdateDisplay(); -} - -void CClientSettingsDlg::OnSndCrdLeftInChannelSelection ( int iChanIdx ) -{ - pClient->SetSndCrdLeftInputChannel ( iChanIdx ); - UpdateSoundChannelSelectionFrame(); -} - -void CClientSettingsDlg::OnSndCrdRightInChannelSelection ( int iChanIdx ) -{ - pClient->SetSndCrdRightInputChannel ( iChanIdx ); - UpdateSoundChannelSelectionFrame(); -} - -void CClientSettingsDlg::OnSndCrdLeftOutChannelSelection ( int iChanIdx ) -{ - pClient->SetSndCrdLeftOutputChannel ( iChanIdx ); - UpdateSoundChannelSelectionFrame(); -} - -void CClientSettingsDlg::OnSndCrdRightOutChannelSelection ( int iChanIdx ) -{ - pClient->SetSndCrdRightOutputChannel ( iChanIdx ); - UpdateSoundChannelSelectionFrame(); -} - -void CClientSettingsDlg::OnAutoJitBuf ( int value ) -{ - pClient->SetDoAutoSockBufSize ( value == Qt::Checked ); - UpdateJitterBufferFrame(); -} - -void CClientSettingsDlg::OnOpenChatOnNewMessageStateChanged ( int value ) -{ - pClient->SetOpenChatOnNewMessage ( value == Qt::Checked ); - UpdateDisplay(); -} - -void CClientSettingsDlg::OnGUIDesignFancyStateChanged ( int value ) -{ - if ( value == Qt::Unchecked ) - { - pClient->SetGUIDesign ( GD_STANDARD ); - } - else - { - pClient->SetGUIDesign ( GD_ORIGINAL ); - } - emit GUIDesignChanged(); - UpdateDisplay(); -} - -void CClientSettingsDlg::OnUseHighQualityAudioStateChanged ( int value ) -{ - pClient->SetCELTHighQuality ( value == Qt::Checked ); - UpdateDisplay(); // upload rate will be changed -} - -void CClientSettingsDlg::OnUseStereoStateChanged ( int value ) -{ - pClient->SetUseStereo ( value == Qt::Checked ); - emit StereoCheckBoxChanged(); - UpdateDisplay(); // upload rate will be changed -} - -void CClientSettingsDlg::OnSndCrdBufferDelayButtonGroupClicked ( QAbstractButton* button ) -{ - if ( button == rButBufferDelayPreferred ) - { - pClient->SetSndCrdPrefFrameSizeFactor ( FRAME_SIZE_FACTOR_PREFERRED ); - } - - if ( button == rButBufferDelayDefault ) - { - pClient->SetSndCrdPrefFrameSizeFactor ( FRAME_SIZE_FACTOR_DEFAULT ); - } - - if ( button == rButBufferDelaySafe ) - { - pClient->SetSndCrdPrefFrameSizeFactor ( FRAME_SIZE_FACTOR_SAFE ); - } - - UpdateDisplay(); -} - -void CClientSettingsDlg::SetPingTimeResult ( const int iPingTime, - const int iOverallDelayMs, - const int iOverallDelayLEDColor ) -{ - // apply values to GUI labels, take special care if ping time exceeds - // a certain value - if ( iPingTime > 500 ) - { - const QString sErrorText = - ">500 ms"; - - TextLabelPingTime->setText ( sErrorText ); - TextLabelOverallDelay->setText ( sErrorText ); - } - else - { - TextLabelPingTime->setText ( QString().setNum ( iPingTime ) + " ms" ); - TextLabelOverallDelay->setText ( - QString().setNum ( iOverallDelayMs ) + " ms" ); - } - - // set current LED status - CLEDOverallDelay->SetLight ( iOverallDelayLEDColor ); -} - -void CClientSettingsDlg::UpdateDisplay() -{ - // update slider controls (settings might have been changed) - UpdateJitterBufferFrame(); - UpdateSoundCardFrame(); - - if ( !pClient->IsRunning() ) - { - // clear text labels with client parameters - TextLabelPingTime->setText ( "" ); - TextLabelOverallDelay->setText ( "" ); - TextUpstreamValue->setText ( "" ); - } - else - { - // update upstream rate information label (only if client is running) - TextUpstreamValue->setText ( - QString().setNum ( pClient->GetUploadRateKbps() ) + " kbps" ); - } -} - -void CClientSettingsDlg::SetStatus ( const int iMessType, const int iStatus ) -{ - switch ( iMessType ) - { - case MS_JIT_BUF_PUT: - case MS_JIT_BUF_GET: - // network LED shows combined status of put and get - CLEDNetw->SetLight ( iStatus ); - break; - - case MS_RESET_ALL: - CLEDNetw->Reset(); - break; - } -} +/******************************************************************************\ + * Copyright (c) 2004-2011 + * + * Author(s): + * Volker Fischer + * + ****************************************************************************** + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +\******************************************************************************/ + +#include "clientsettingsdlg.h" + + +/* Implementation *************************************************************/ +CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent, + Qt::WindowFlags f ) : QDialog ( parent, f ), pClient ( pNCliP ) +{ + setupUi ( this ); + + + // Add help text to controls ----------------------------------------------- + // jitter buffer + QString strJitterBufferSize = tr ( "Jitter Buffer Size: The jitter " + "buffer compensates for network and sound card timing jitters. The " + "size of this jitter buffer has therefore influence on the quality of " + "the audio stream (how many dropouts occur) and the overall delay " + "(the longer the buffer, the higher the delay).
" + "Dropouts in the audio stream are indicated by the light on the bottom " + "of the jitter buffer size fader. If the light turns to red, a buffer " + "overrun/underrun took place and the audio stream is interrupted.
" + "The jitter buffer setting is therefore a trade-off between audio " + "quality and overall delay.
" + "An auto setting of the jitter buffer size setting is available. If " + "the check Auto is enabled, the jitter buffer is set automatically " + "based on measurements of the network and sound card timing jitter. If " + "the Auto check is enabled, the jitter buffer size fader is disabled " + "(it cannot be moved by the mouse)." ); + + QString strJitterBufferSizeTT = tr ( "In case the Auto setting of the " + "jitter buffer is enabled, the network buffer is set to a conservative " + "value to minimize the audio dropout probability. To tweak the " + "audio delay/latency it is recommended to disable the Auto " + "functionality and to lower the jitter buffer size manually by " + "using the slider until your personal acceptable limit of the amount " + "of dropouts is reached. The LED indicator will visualize the audio " + "dropouts by a red light" ) + TOOLTIP_COM_END_TEXT; + + TextNetBuf->setWhatsThis ( strJitterBufferSize ); + TextNetBuf->setToolTip ( strJitterBufferSizeTT ); + GroupBoxJitterBuffer->setWhatsThis ( strJitterBufferSize ); + GroupBoxJitterBuffer->setToolTip ( strJitterBufferSizeTT ); + SliderNetBuf->setWhatsThis ( strJitterBufferSize ); + SliderNetBuf->setAccessibleName ( tr ( "Jitter buffer slider control" ) ); + SliderNetBuf->setToolTip ( strJitterBufferSizeTT ); + cbAutoJitBuf->setAccessibleName ( tr ( "Auto jitter buffer switch" ) ); + cbAutoJitBuf->setToolTip ( strJitterBufferSizeTT ); + CLEDNetw->setAccessibleName ( tr ( "Jitter buffer status LED indicator" ) ); + CLEDNetw->setToolTip ( strJitterBufferSizeTT ); + + // sound card device + cbSoundcard->setWhatsThis ( tr ( "Sound Card Device: The ASIO " + "driver (sound card) can be selected using llcon under the Windows " + "operating system. Under Linux, no sound card selection is possible " + "(always wave mapper is shown and cannot be changed). If the selected " + "ASIO driver is not valid an error message is shown and the previous " + "valid driver is selected.
" + "If the driver is selected during an active connection, the connection " + "is stopped, the driver is changed and the connection is started again " + "automatically." ) ); + + cbSoundcard->setAccessibleName ( tr ( "Sound card device selector combo box" ) ); + + cbSoundcard->setToolTip ( tr ( "In case the ASIO4ALL driver is used, " + "please note that this driver usually introduces approx. 10-30 ms of " + "additional audio delay. Using a sound card with a native ASIO driver " + "is therefore recommended.
If you are using the kX ASIO " + "driver, make sure to connect the ASIO inputs in the kX DSP settings " + "panel." ) + TOOLTIP_COM_END_TEXT ); + + // sound card input/output channel mapping + QString strSndCrdChanMapp = tr ( "Sound Card Channel Mapping: " + "In case the selected sound card device offers more than one " + "input or output channel, the Input Channel Mapping and Ouptut " + "Channel Mapping settings are visible.
" + "For each " ) + APP_NAME + tr ( " input/output channel (Left and " + "Right channel) a different actual sound card channel can be " + "selected." ); + + lbInChannelMapping->setWhatsThis ( strSndCrdChanMapp ); + lbOutChannelMapping->setWhatsThis ( strSndCrdChanMapp ); + cbLInChan->setWhatsThis ( strSndCrdChanMapp ); + cbLInChan->setAccessibleName ( tr ( "Left input channel selection combo box" ) ); + cbRInChan->setWhatsThis ( strSndCrdChanMapp ); + cbRInChan->setAccessibleName ( tr ( "Right input channel selection combo box" ) ); + cbLOutChan->setWhatsThis ( strSndCrdChanMapp ); + cbLOutChan->setAccessibleName ( tr ( "Left output channel selection combo box" ) ); + cbROutChan->setWhatsThis ( strSndCrdChanMapp ); + cbROutChan->setAccessibleName ( tr ( "Right output channel selection combo box" ) ); + + // sound card buffer delay + QString strSndCrdBufDelay = tr ( "Sound Card Buffer Delay: The " + "buffer delay setting is a fundamental setting of the llcon software. " + "This setting has influence on many connection properties.
" + "Three buffer sizes are supported:" + "
    " + "
  • 128 samples: This is the preferred setting since it gives lowest " + "latency but does not work with all sound cards.
  • " + "
  • 256 samples: This is the default setting and should work on most " + "of the available sound cards.
  • " + "
  • 512 samples: This setting should only be used if only a very slow " + "computer or a slow internet connection is available.
  • " + "
" + "Some sound card driver do not allow the buffer delay to be changed " + "from within the llcon software. In this case the buffer delay setting " + "is disabled. To change the actual buffer delay, this " + "setting has to be changed in the sound card driver. On Windows, press " + "the ASIO Setup button to open the driver settings panel. On Linux, " + "use the Jack configuration tool to change the buffer size.
" + "If no buffer size is selected and all settings are disabled, an " + "unsupported buffer size is used by the driver. The llcon software " + "will still work with this setting but with restricted performannce.
" + "The actual buffer delay has influence on the connection status, the " + "current upload rate and the overall delay. The lower the buffer size, " + "the higher the probability of red light in the status indicator (drop " + "outs) and the higher the upload rate and the lower the overall " + "delay.
" + "The jitter buffer setting is therefore a trade-off between audio " + "quality and overall delay." ); + + QString strSndCrdBufDelayTT = tr ( "If the buffer delay settings are " + "disabled, it is prohibited by the audio driver to modify this " + "setting from within the llcon software. On Windows, press " + "the ASIO Setup button to open the driver settings panel. On Linux, " + "use the Jack configuration tool to change the buffer size." ) + + TOOLTIP_COM_END_TEXT; + + rButBufferDelayPreferred->setWhatsThis ( strSndCrdBufDelay ); + rButBufferDelayPreferred->setAccessibleName ( tr ( "128 samples setting radio button" ) ); + rButBufferDelayPreferred->setToolTip ( strSndCrdBufDelayTT ); + rButBufferDelayDefault->setWhatsThis ( strSndCrdBufDelay ); + rButBufferDelayDefault->setAccessibleName ( tr ( "256 samples setting radio button" ) ); + rButBufferDelayDefault->setToolTip ( strSndCrdBufDelayTT ); + rButBufferDelaySafe->setWhatsThis ( strSndCrdBufDelay ); + rButBufferDelaySafe->setAccessibleName ( tr ( "512 samples setting radio button" ) ); + rButBufferDelaySafe->setToolTip ( strSndCrdBufDelayTT ); + ButtonDriverSetup->setWhatsThis ( strSndCrdBufDelay ); + ButtonDriverSetup->setAccessibleName ( tr ( "ASIO setup push button" ) ); + ButtonDriverSetup->setToolTip ( strSndCrdBufDelayTT ); + + // open chat on new message + cbOpenChatOnNewMessage->setWhatsThis ( tr ( "Open Chat on New " + "Message: If this checkbox is enabled, the chat window will " + "open on any incoming chat text if it not already opened." ) ); + + cbOpenChatOnNewMessage->setAccessibleName ( tr ( "Open chat on new " + "message check box" ) ); + + cbOpenChatOnNewMessage->setToolTip ( tr ( "If Open Chat on New Message " + "is disabled, a LED in the main window turns green when a " + "new message has arrived." ) + TOOLTIP_COM_END_TEXT ); + + // use high quality audio + cbUseHighQualityAudio->setWhatsThis ( tr ( "Use High Quality Audio " + "Enabling ""Use High Quality Audio"" will improve the audio quality " + "by increasing the stream data rate. Make sure that the current " + "upload rate does not exceed the available bandwidth of your " + "internet connection." ) ); + + cbUseHighQualityAudio->setAccessibleName ( tr ( "Use high quality audio " + "check box" ) ); + + // use stereo + cbUseStereo->setWhatsThis ( tr ( "Stereo Streaming " + "Enables the stereo streaming mode. If not checked, a mono streaming " + "mode is used. Enabling the stereo streaming mode will increase the " + "stream data rate. Make sure that the current upload rate does not " + "exceed the available bandwidth of your internet connection.
" + "In case of the stereo streaming mode, no audio channel selection " + "for the reverberation effect will be available on the main window " + "since the effect is applied on both channels in this case." ) ); + + cbUseStereo->setAccessibleName ( tr ( "Stereo check box" ) ); + + // central server address + QString strCentrServAddr = tr ( "Central Server Address: The " + "Central server address is the IP address or URL of the central server " + "at which the server list of the connection dialog is managed. If the " + "Default check box is checked, the default central server address is " + "shown read-only." ); + + LabelCentralServerAddress->setWhatsThis ( strCentrServAddr ); + cbDefaultCentralServer->setWhatsThis ( strCentrServAddr ); + LineEditCentralServerAddress->setWhatsThis ( strCentrServAddr ); + + cbDefaultCentralServer->setAccessibleName ( + tr ( "Default central server check box" ) ); + + LineEditCentralServerAddress->setAccessibleName ( + tr ( "Central server address line edit" ) ); + + // current connection status parameter + QString strConnStats = tr ( "Current Connection Status " + "Parameter: The ping time is the time required for the audio " + "stream to travel from the client to the server and backwards. This " + "delay is introduced by the network. This delay should be as low as " + "20-30 ms. If this delay is higher (e.g., 50-60 ms), your distance to " + "the server is too large or your internet connection is not " + "sufficient.
" + "The overall delay is calculated from the current ping time and the " + "delay which is introduced by the current buffer settings.
" + "The upstream rate depends on the current audio packet size and the " + "audio compression setting. Make sure that the upstream rate is not " + "higher than the available rate (check the upstream capabilities of " + "your internet connection by, e.g., using speedtest.net)." ); + + TextPingTime->setWhatsThis ( strConnStats ); + TextLabelPingTime->setWhatsThis ( strConnStats ); + TextOverallDelay->setWhatsThis ( strConnStats ); + TextLabelOverallDelay->setWhatsThis ( strConnStats ); + TextUpstream->setWhatsThis ( strConnStats ); + TextUpstreamValue->setWhatsThis ( strConnStats ); + CLEDOverallDelay->setWhatsThis ( strConnStats ); + CLEDOverallDelay->setToolTip ( tr ( "If this LED indicator turns red, " + "you will not have much fun using the llcon software." ) + + TOOLTIP_COM_END_TEXT ); + + + // init driver button +#ifdef _WIN32 + ButtonDriverSetup->setText ( "ASIO Setup" ); +#else + // no use for this button for Linux right now, maybe later used + // for Jack + ButtonDriverSetup->hide(); + + // for Jack interface, we cannot choose the audio hardware from + // within the llcon software, hide the combo box + TextSoundcardDevice->hide(); + cbSoundcard->hide(); +#endif + + // init delay and other information controls + CLEDOverallDelay->SetUpdateTime ( 2 * PING_UPDATE_TIME_MS ); + CLEDOverallDelay->Reset(); + TextLabelPingTime->setText ( "" ); + TextLabelOverallDelay->setText ( "" ); + TextUpstreamValue->setText ( "" ); + + + // init slider controls --- + // network buffer + SliderNetBuf->setRange ( MIN_NET_BUF_SIZE_NUM_BL, MAX_NET_BUF_SIZE_NUM_BL ); + UpdateJitterBufferFrame(); + + // init combo box containing all available sound cards in the system + cbSoundcard->clear(); + for ( int iSndDevIdx = 0; iSndDevIdx < pClient->GetSndCrdNumDev(); iSndDevIdx++ ) + { + cbSoundcard->addItem ( pClient->GetSndCrdDeviceName ( iSndDevIdx ) ); + } + cbSoundcard->setCurrentIndex ( pClient->GetSndCrdDev() ); + + // init sound card channel selection frame + UpdateSoundChannelSelectionFrame(); + + // "OpenChatOnNewMessage" check box + if ( pClient->GetOpenChatOnNewMessage() ) + { + cbOpenChatOnNewMessage->setCheckState ( Qt::Checked ); + } + else + { + cbOpenChatOnNewMessage->setCheckState ( Qt::Unchecked ); + } + + // fancy GUI design check box + if ( pClient->GetGUIDesign() == GD_STANDARD ) + { + cbGUIDesignFancy->setCheckState ( Qt::Unchecked ); + } + else + { + cbGUIDesignFancy->setCheckState ( Qt::Checked ); + } + + // "High Quality Audio" check box + if ( pClient->GetCELTHighQuality() ) + { + cbUseHighQualityAudio->setCheckState ( Qt::Checked ); + } + else + { + cbUseHighQualityAudio->setCheckState ( Qt::Unchecked ); + } + + // "Stereo" check box + if ( pClient->GetUseStereo() ) + { + cbUseStereo->setCheckState ( Qt::Checked ); + } + else + { + cbUseStereo->setCheckState ( Qt::Unchecked ); + } + + // update default central server address check box + if ( pClient->GetUseDefaultCentralServerAddress() ) + { + cbDefaultCentralServer->setCheckState ( Qt::Checked ); + } + else + { + cbDefaultCentralServer->setCheckState ( Qt::Unchecked ); + } + UpdateCentralServerDependency(); + + // set text for sound card buffer delay radio buttons + rButBufferDelayPreferred->setText ( GenSndCrdBufferDelayString ( + FRAME_SIZE_FACTOR_PREFERRED * SYSTEM_FRAME_SIZE_SAMPLES, + ", preferred" ) ); + + rButBufferDelayDefault->setText ( GenSndCrdBufferDelayString ( + FRAME_SIZE_FACTOR_DEFAULT * SYSTEM_FRAME_SIZE_SAMPLES, + ", default" ) ); + + rButBufferDelaySafe->setText ( GenSndCrdBufferDelayString ( + FRAME_SIZE_FACTOR_SAFE * SYSTEM_FRAME_SIZE_SAMPLES ) ); + + // sound card buffer delay inits + SndCrdBufferDelayButtonGroup.addButton ( rButBufferDelayPreferred ); + SndCrdBufferDelayButtonGroup.addButton ( rButBufferDelayDefault ); + SndCrdBufferDelayButtonGroup.addButton ( rButBufferDelaySafe ); + + UpdateSoundCardFrame(); + + + // Connections ------------------------------------------------------------- + // timers + QObject::connect ( &TimerStatus, SIGNAL ( timeout() ), + this, SLOT ( OnTimerStatus() ) ); + + // slider controls + QObject::connect ( SliderNetBuf, SIGNAL ( valueChanged ( int ) ), + this, SLOT ( OnSliderNetBuf ( int ) ) ); + + // check boxes + QObject::connect ( cbOpenChatOnNewMessage, SIGNAL ( stateChanged ( int ) ), + this, SLOT ( OnOpenChatOnNewMessageStateChanged ( int ) ) ); + + QObject::connect ( cbGUIDesignFancy, SIGNAL ( stateChanged ( int ) ), + this, SLOT ( OnGUIDesignFancyStateChanged ( int ) ) ); + + QObject::connect ( cbUseHighQualityAudio, SIGNAL ( stateChanged ( int ) ), + this, SLOT ( OnUseHighQualityAudioStateChanged ( int ) ) ); + + QObject::connect ( cbUseStereo, SIGNAL ( stateChanged ( int ) ), + this, SLOT ( OnUseStereoStateChanged ( int ) ) ); + + QObject::connect ( cbAutoJitBuf, SIGNAL ( stateChanged ( int ) ), + this, SLOT ( OnAutoJitBuf ( int ) ) ); + + QObject::connect ( cbDefaultCentralServer, SIGNAL ( stateChanged ( int ) ), + this, SLOT ( OnDefaultCentralServerStateChanged ( int ) ) ); + + // line edits + QObject::connect ( LineEditCentralServerAddress, + SIGNAL ( editingFinished() ), + this, SLOT ( OnLineEditCentralServerAddressEditingFinished() ) ); + + // combo boxes + QObject::connect ( cbSoundcard, SIGNAL ( activated ( int ) ), + this, SLOT ( OnSoundCrdSelection ( int ) ) ); + + QObject::connect ( cbLInChan, SIGNAL ( activated ( int ) ), + this, SLOT ( OnSndCrdLeftInChannelSelection ( int ) ) ); + + QObject::connect ( cbRInChan, SIGNAL ( activated ( int ) ), + this, SLOT ( OnSndCrdRightInChannelSelection ( int ) ) ); + + QObject::connect ( cbLOutChan, SIGNAL ( activated ( int ) ), + this, SLOT ( OnSndCrdLeftOutChannelSelection ( int ) ) ); + + QObject::connect ( cbROutChan, SIGNAL ( activated ( int ) ), + this, SLOT ( OnSndCrdRightOutChannelSelection ( int ) ) ); + + // buttons + QObject::connect ( ButtonDriverSetup, SIGNAL ( clicked() ), + this, SLOT ( OnDriverSetupBut() ) ); + + // misc + QObject::connect ( &SndCrdBufferDelayButtonGroup, + SIGNAL ( buttonClicked ( QAbstractButton* ) ), this, + SLOT ( OnSndCrdBufferDelayButtonGroupClicked ( QAbstractButton* ) ) ); + + + // Timers ------------------------------------------------------------------ + // start timer for status bar + TimerStatus.start ( DISPLAY_UPDATE_TIME ); +} + +void CClientSettingsDlg::UpdateJitterBufferFrame() +{ + // update slider value and text + const int iCurNumNetBuf = pClient->GetSockBufNumFrames(); + SliderNetBuf->setValue ( iCurNumNetBuf ); + TextNetBuf->setText ( "Size: " + QString().setNum ( iCurNumNetBuf ) ); + + // if auto setting is enabled, disable slider control + cbAutoJitBuf->setChecked ( pClient->GetDoAutoSockBufSize() ); + SliderNetBuf->setEnabled ( !pClient->GetDoAutoSockBufSize() ); + 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_HZ, 'f', 2 ) + " ms (" + + QString().setNum ( iFrameSize ) + strAddText + ")"; +} + +void CClientSettingsDlg::UpdateSoundCardFrame() +{ + // get current actual buffer size value + const int iCurActualBufSize = + pClient->GetSndCrdActualMonoBlSize(); + + // Set radio buttons according to current value (To make it possible + // to have all radio buttons unchecked, we have to disable the + // exclusive check for the radio button group. We require all radio + // buttons to be unchecked in the case when the sound card does not + // support any of the buffer sizes and therefore all radio buttons + // are disabeld and unchecked.). + SndCrdBufferDelayButtonGroup.setExclusive ( false ); + + rButBufferDelayPreferred->setChecked ( iCurActualBufSize == + SYSTEM_FRAME_SIZE_SAMPLES * FRAME_SIZE_FACTOR_PREFERRED ); + + rButBufferDelayDefault->setChecked ( iCurActualBufSize == + SYSTEM_FRAME_SIZE_SAMPLES * FRAME_SIZE_FACTOR_DEFAULT ); + + rButBufferDelaySafe->setChecked ( iCurActualBufSize == + SYSTEM_FRAME_SIZE_SAMPLES * FRAME_SIZE_FACTOR_SAFE ); + + SndCrdBufferDelayButtonGroup.setExclusive ( true ); + + // disable radio buttons which are not supported by audio interface + rButBufferDelayPreferred->setEnabled ( + pClient->GetFraSiFactPrefSupported() ); + + rButBufferDelayDefault->setEnabled ( + pClient->GetFraSiFactDefSupported() ); + + rButBufferDelaySafe->setEnabled ( + pClient->GetFraSiFactSafeSupported() ); +} + +void CClientSettingsDlg::UpdateSoundChannelSelectionFrame() +{ +#ifdef _WIN32 + int iSndChanIdx; + + // Definition: The channel selection frame shall only be visible, + // if more than two input or output channels are available + const int iNumInChannels = pClient->GetSndCrdNumInputChannels(); + const int iNumOutChannels = pClient->GetSndCrdNumOutputChannels(); + + if ( ( iNumInChannels <= 2 ) && ( iNumOutChannels <= 2 ) ) + { + // as defined, make settings invisible + FrameSoundcardChannelSelection->setVisible ( false ); + } + else + { + // update combo boxes + FrameSoundcardChannelSelection->setVisible ( true ); + + // input + cbLInChan->clear(); + cbRInChan->clear(); + for ( iSndChanIdx = 0; iSndChanIdx < pClient->GetSndCrdNumInputChannels(); iSndChanIdx++ ) + { + cbLInChan->addItem ( pClient->GetSndCrdInputChannelName ( iSndChanIdx ) ); + cbRInChan->addItem ( pClient->GetSndCrdInputChannelName ( iSndChanIdx ) ); + } + cbLInChan->setCurrentIndex ( pClient->GetSndCrdLeftInputChannel() ); + cbRInChan->setCurrentIndex ( pClient->GetSndCrdRightInputChannel() ); + + // output + cbLOutChan->clear(); + cbROutChan->clear(); + for ( iSndChanIdx = 0; iSndChanIdx < pClient->GetSndCrdNumOutputChannels(); iSndChanIdx++ ) + { + cbLOutChan->addItem ( pClient->GetSndCrdOutputChannelName ( iSndChanIdx ) ); + cbROutChan->addItem ( pClient->GetSndCrdOutputChannelName ( iSndChanIdx ) ); + } + cbLOutChan->setCurrentIndex ( pClient->GetSndCrdLeftOutputChannel() ); + cbROutChan->setCurrentIndex ( pClient->GetSndCrdRightOutputChannel() ); + } +#else + // for other OS, no sound card channel selection is supported + FrameSoundcardChannelSelection->setVisible ( false ); +#endif +} + +void CClientSettingsDlg::UpdateCentralServerDependency() +{ + const bool bCurUseDefCentServAddr = + pClient->GetUseDefaultCentralServerAddress(); + + // If the default central server address is enabled, the line edit shows + // the default server and is not editable. Make sure the line edit does not + // fire signals when we update the text. + LineEditCentralServerAddress->blockSignals ( true ); + { + if ( bCurUseDefCentServAddr ) + { + LineEditCentralServerAddress->setText ( DEFAULT_SERVER_ADDRESS ); + } + else + { + LineEditCentralServerAddress->setText ( + pClient->GetServerListCentralServerAddress() ); + } + } + LineEditCentralServerAddress->blockSignals ( false ); + + // the line edit of the central server address is only enabled, if not the + // default address is used + LineEditCentralServerAddress->setEnabled ( !bCurUseDefCentServAddr ); +} + +void CClientSettingsDlg::OnDriverSetupBut() +{ + pClient->OpenSndCrdDriverSetup(); +} + +void CClientSettingsDlg::OnSliderNetBuf ( int value ) +{ + pClient->SetSockBufNumFrames ( value ); + UpdateJitterBufferFrame(); +} + +void CClientSettingsDlg::OnSliderSndCrdBufferDelay ( int value ) +{ + pClient->SetSndCrdPrefFrameSizeFactor ( value ); + UpdateDisplay(); +} + +void CClientSettingsDlg::OnSoundCrdSelection ( int iSndDevIdx ) +{ + const QString strError = pClient->SetSndCrdDev ( iSndDevIdx ); + + if ( !strError.isEmpty() ) + { + QMessageBox::critical ( this, APP_NAME, + QString ( tr ( "The selected audio device could not be used " + "because of the following error: " ) ) + strError + + QString ( tr ( " The previous driver will be selected." ) ), + "Ok", 0 ); + + // recover old selection + cbSoundcard->setCurrentIndex ( pClient->GetSndCrdDev() ); + } + UpdateSoundChannelSelectionFrame(); + UpdateDisplay(); +} + +void CClientSettingsDlg::OnSndCrdLeftInChannelSelection ( int iChanIdx ) +{ + pClient->SetSndCrdLeftInputChannel ( iChanIdx ); + UpdateSoundChannelSelectionFrame(); +} + +void CClientSettingsDlg::OnSndCrdRightInChannelSelection ( int iChanIdx ) +{ + pClient->SetSndCrdRightInputChannel ( iChanIdx ); + UpdateSoundChannelSelectionFrame(); +} + +void CClientSettingsDlg::OnSndCrdLeftOutChannelSelection ( int iChanIdx ) +{ + pClient->SetSndCrdLeftOutputChannel ( iChanIdx ); + UpdateSoundChannelSelectionFrame(); +} + +void CClientSettingsDlg::OnSndCrdRightOutChannelSelection ( int iChanIdx ) +{ + pClient->SetSndCrdRightOutputChannel ( iChanIdx ); + UpdateSoundChannelSelectionFrame(); +} + +void CClientSettingsDlg::OnAutoJitBuf ( int value ) +{ + pClient->SetDoAutoSockBufSize ( value == Qt::Checked ); + UpdateJitterBufferFrame(); +} + +void CClientSettingsDlg::OnOpenChatOnNewMessageStateChanged ( int value ) +{ + pClient->SetOpenChatOnNewMessage ( value == Qt::Checked ); + UpdateDisplay(); +} + +void CClientSettingsDlg::OnGUIDesignFancyStateChanged ( int value ) +{ + if ( value == Qt::Unchecked ) + { + pClient->SetGUIDesign ( GD_STANDARD ); + } + else + { + pClient->SetGUIDesign ( GD_ORIGINAL ); + } + emit GUIDesignChanged(); + UpdateDisplay(); +} + +void CClientSettingsDlg::OnUseHighQualityAudioStateChanged ( int value ) +{ + pClient->SetCELTHighQuality ( value == Qt::Checked ); + UpdateDisplay(); // upload rate will be changed +} + +void CClientSettingsDlg::OnUseStereoStateChanged ( int value ) +{ + pClient->SetUseStereo ( value == Qt::Checked ); + emit StereoCheckBoxChanged(); + UpdateDisplay(); // upload rate will be changed +} + +void CClientSettingsDlg::OnDefaultCentralServerStateChanged ( int value ) +{ + // apply new setting to the client + pClient->SetUseDefaultCentralServerAddress ( value == Qt::Checked ); + + // update GUI dependencies + UpdateCentralServerDependency(); +} + +void CClientSettingsDlg::OnLineEditCentralServerAddressEditingFinished() +{ + // store new setting in the client + pClient->SetServerListCentralServerAddress ( + LineEditCentralServerAddress->text() ); +} + +void CClientSettingsDlg::OnSndCrdBufferDelayButtonGroupClicked ( QAbstractButton* button ) +{ + if ( button == rButBufferDelayPreferred ) + { + pClient->SetSndCrdPrefFrameSizeFactor ( FRAME_SIZE_FACTOR_PREFERRED ); + } + + if ( button == rButBufferDelayDefault ) + { + pClient->SetSndCrdPrefFrameSizeFactor ( FRAME_SIZE_FACTOR_DEFAULT ); + } + + if ( button == rButBufferDelaySafe ) + { + pClient->SetSndCrdPrefFrameSizeFactor ( FRAME_SIZE_FACTOR_SAFE ); + } + + UpdateDisplay(); +} + +void CClientSettingsDlg::SetPingTimeResult ( const int iPingTime, + const int iOverallDelayMs, + const int iOverallDelayLEDColor ) +{ + // apply values to GUI labels, take special care if ping time exceeds + // a certain value + if ( iPingTime > 500 ) + { + const QString sErrorText = + ">500 ms"; + + TextLabelPingTime->setText ( sErrorText ); + TextLabelOverallDelay->setText ( sErrorText ); + } + else + { + TextLabelPingTime->setText ( QString().setNum ( iPingTime ) + " ms" ); + TextLabelOverallDelay->setText ( + QString().setNum ( iOverallDelayMs ) + " ms" ); + } + + // set current LED status + CLEDOverallDelay->SetLight ( iOverallDelayLEDColor ); +} + +void CClientSettingsDlg::UpdateDisplay() +{ + // update slider controls (settings might have been changed) + UpdateJitterBufferFrame(); + UpdateSoundCardFrame(); + + if ( !pClient->IsRunning() ) + { + // clear text labels with client parameters + TextLabelPingTime->setText ( "" ); + TextLabelOverallDelay->setText ( "" ); + TextUpstreamValue->setText ( "" ); + } + else + { + // update upstream rate information label (only if client is running) + TextUpstreamValue->setText ( + QString().setNum ( pClient->GetUploadRateKbps() ) + " kbps" ); + } +} + +void CClientSettingsDlg::SetStatus ( const int iMessType, const int iStatus ) +{ + switch ( iMessType ) + { + case MS_JIT_BUF_PUT: + case MS_JIT_BUF_GET: + // network LED shows combined status of put and get + CLEDNetw->SetLight ( iStatus ); + break; + + case MS_RESET_ALL: + CLEDNetw->Reset(); + break; + } +} diff --git a/src/clientsettingsdlg.h b/src/clientsettingsdlg.h index 1ced87af..0167fdda 100755 --- a/src/clientsettingsdlg.h +++ b/src/clientsettingsdlg.h @@ -71,6 +71,7 @@ protected: void UpdateJitterBufferFrame(); void UpdateSoundCardFrame(); void UpdateSoundChannelSelectionFrame(); + void UpdateCentralServerDependency(); QString GenSndCrdBufferDelayString ( const int iFrameSize, const QString strAddText = "" ); @@ -90,6 +91,8 @@ protected: void OnGUIDesignFancyStateChanged ( int value ); void OnUseHighQualityAudioStateChanged ( int value ); void OnUseStereoStateChanged ( int value ); + void OnDefaultCentralServerStateChanged ( int value ); + void OnLineEditCentralServerAddressEditingFinished(); void OnSndCrdBufferDelayButtonGroupClicked ( QAbstractButton* button ); void OnSoundCrdSelection ( int iSndDevIdx ); void OnSndCrdLeftInChannelSelection ( int iChanIdx ); diff --git a/src/clientsettingsdlgbase.ui b/src/clientsettingsdlgbase.ui index 92d44869..ccd42fa4 100755 --- a/src/clientsettingsdlgbase.ui +++ b/src/clientsettingsdlgbase.ui @@ -192,7 +192,7 @@ - + 0 0 @@ -442,6 +442,34 @@ + + + + + + Central Server Address: + + + + + + + Default + + + + + + + + + + 0 + 0 + + + + @@ -450,7 +478,7 @@ 201 - 81 + 21 @@ -610,6 +638,25 @@
multicolorled.h
+ + cbAutoJitBuf + SliderNetBuf + cbSoundcard + cbLInChan + cbRInChan + cbLOutChan + cbROutChan + rButBufferDelayPreferred + rButBufferDelayDefault + rButBufferDelaySafe + ButtonDriverSetup + cbOpenChatOnNewMessage + cbGUIDesignFancy + cbUseHighQualityAudio + cbUseStereo + cbDefaultCentralServer + LineEditCentralServerAddress + diff --git a/src/connectdlg.cpp b/src/connectdlg.cpp index 882240fb..76dd7b03 100755 --- a/src/connectdlg.cpp +++ b/src/connectdlg.cpp @@ -28,6 +28,7 @@ /* Implementation *************************************************************/ CConnectDlg::CConnectDlg ( QWidget* parent, Qt::WindowFlags f ) : QDialog ( parent, f ), + strCentralServerAddress ( "" ), strSelectedAddress ( "" ), bServerListReceived ( false ), bStateOK ( false ), @@ -93,8 +94,12 @@ CConnectDlg::CConnectDlg ( QWidget* parent, Qt::WindowFlags f ) this, SLOT ( OnTimerReRequestServList() ) ); } -void CConnectDlg::LoadStoredServers ( const CVector& vstrIPAddresses ) +void CConnectDlg::Init ( const QString strNewCentralServerAddr, + const CVector& vstrIPAddresses ) { + // take central server address string + strCentralServerAddress = strNewCentralServerAddr; + // load stored IP addresses in combo box LineEditServerAddr->clear(); for ( int iLEIdx = 0; iLEIdx < MAX_NUM_SERVER_ADDR_ITEMS; iLEIdx++ ) @@ -120,15 +125,10 @@ void CConnectDlg::showEvent ( QShowEvent* ) // clear server list view ListViewServers->clear(); - -// TEST -QString strNAddr = "llcon.dyndns.org:22122"; - - // get the IP address of the central server (using the ParseNetworAddress // function) when the connect dialog is opened, this seems to be the correct // time to do it - if ( LlconNetwUtil().ParseNetworkAddress ( strNAddr, + if ( LlconNetwUtil().ParseNetworkAddress ( strCentralServerAddress, CentralServerAddress ) ) { // send the request for the server list diff --git a/src/connectdlg.h b/src/connectdlg.h index 4459bb76..5bcff3d6 100755 --- a/src/connectdlg.h +++ b/src/connectdlg.h @@ -56,11 +56,12 @@ class CConnectDlg : public QDialog, private Ui_CConnectDlgBase public: CConnectDlg ( QWidget* parent = 0, Qt::WindowFlags f = 0 ); + void Init ( const QString strNewCentralServerAddr, + const CVector& vstrIPAddresses ); + void SetServerList ( const CHostAddress& InetAddr, const CVector& vecServerInfo ); - void LoadStoredServers ( const CVector& vstrNewIPAddresses ); - void SetPingTimeAndNumClientsResult ( CHostAddress& InetAddr, const int iPingTime, const int iPingTimeLEDColor, @@ -76,6 +77,7 @@ protected: QTimer TimerPing; QTimer TimerReRequestServList; + QString strCentralServerAddress; CHostAddress CentralServerAddress; CVector vstrIPAddresses; QString strSelectedAddress; diff --git a/src/connectdlgbase.ui b/src/connectdlgbase.ui index f24f8a53..12c0a2e6 100755 --- a/src/connectdlgbase.ui +++ b/src/connectdlgbase.ui @@ -24,9 +24,18 @@ + + QAbstractItemView::NoEditTriggers + + + true + false + + false + Server Name diff --git a/src/llconclientdlg.cpp b/src/llconclientdlg.cpp index 04eeec05..733f50b8 100755 --- a/src/llconclientdlg.cpp +++ b/src/llconclientdlg.cpp @@ -375,10 +375,6 @@ CLlconClientDlg::CLlconClientDlg ( CClient* pNCliP, SIGNAL ( Disconnected() ), this, SLOT ( OnDisconnected() ) ); - QObject::connect ( pClient, - SIGNAL ( Stopped() ), - this, SLOT ( OnStopped() ) ); - QObject::connect ( pClient, SIGNAL ( ChatTextReceived ( QString ) ), this, SLOT ( OnChatTextReceived ( QString ) ) ); @@ -510,11 +506,6 @@ void CLlconClientDlg::OnConnectDisconBut() ConnectDisconnect ( !pClient->IsRunning() ); } -void CLlconClientDlg::OnStopped() -{ - ConnectDisconnect ( false ); -} - void CLlconClientDlg::OnOpenGeneralSettings() { // open general settings dialog @@ -734,8 +725,19 @@ void CLlconClientDlg::ConnectDisconnect ( const bool bDoStart ) // start/stop client, set button text if ( bDoStart ) { + // get the central server address string + QString strCurCentServAddr; + if ( pClient->GetUseDefaultCentralServerAddress() ) + { + strCurCentServAddr = DEFAULT_SERVER_ADDRESS; + } + else + { + strCurCentServAddr = pClient->GetServerListCentralServerAddress(); + } + // init the connect dialog and execute it (modal dialog) - ConnectDlg.LoadStoredServers ( pClient->vstrIPAddress ); + ConnectDlg.Init ( strCurCentServAddr, pClient->vstrIPAddress ); ConnectDlg.exec(); // check if state is OK (e.g., no Cancel was pressed) diff --git a/src/llconclientdlg.h b/src/llconclientdlg.h index b5b239f6..0420afbe 100755 --- a/src/llconclientdlg.h +++ b/src/llconclientdlg.h @@ -155,7 +155,6 @@ public slots: { ConnectDlg.SetServerList ( InetAddr, vecServerInfo ); } void OnDisconnected(); - void OnStopped(); void OnGUIDesignChanged() { SetGUIDesign ( pClient->GetGUIDesign() ); } diff --git a/src/llconserverdlg.cpp b/src/llconserverdlg.cpp index ffa1c6a4..59c231cd 100755 --- a/src/llconserverdlg.cpp +++ b/src/llconserverdlg.cpp @@ -121,10 +121,6 @@ CLlconServerDlg::CLlconServerDlg ( CServer* pNServP, vecpListViewItems[i]->setHidden ( true ); } - // update central server name line edit - LineEditCentralServerAddress->setText ( - pServer->GetServerListCentralServerAddress() ); - // update default central server address check box if ( pServer->GetUseDefaultCentralServerAddress() ) { @@ -348,9 +344,8 @@ void CLlconServerDlg::UpdateGUIDependencies() // if register server is not enabled, we disable all the configuration // controls for the server list - cbDefaultCentralServer->setEnabled ( bCurSerListEnabled ); - LineEditCentralServerAddress->setEnabled ( bCurSerListEnabled ); - GroupBoxServerInfo->setEnabled ( bCurSerListEnabled ); + cbDefaultCentralServer->setEnabled ( bCurSerListEnabled ); + GroupBoxServerInfo->setEnabled ( bCurSerListEnabled ); // If the default central server address is enabled, the line edit shows // the default server and is not editable. Make sure the line edit does not diff --git a/src/settings.cpp b/src/settings.cpp index 6f0fdaef..4cee262c 100755 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -188,6 +188,16 @@ void CSettings::ReadIniFile ( const QString& sFileName ) { pClient->SetUseStereo ( bValue ); } + + // central server address + pClient->SetServerListCentralServerAddress ( + GetIniSetting ( IniXMLDocument, "client", "centralservaddr" ) ); + + // use default central server address flag + if ( GetFlagIniSet ( IniXMLDocument, "client", "defcentservaddr", bValue ) ) + { + pClient->SetUseDefaultCentralServerAddress ( bValue ); + } } else { @@ -306,6 +316,14 @@ void CSettings::WriteIniFile ( const QString& sFileName ) // flag whether stereo mode is used SetFlagIniSet ( IniXMLDocument, "client", "stereoaudio", pClient->GetUseStereo() ); + + // central server address + PutIniSetting ( IniXMLDocument, "client", "centralservaddr", + pClient->GetServerListCentralServerAddress() ); + + // use default central server address flag + SetFlagIniSet ( IniXMLDocument, "client", "defcentservaddr", + pClient->GetUseDefaultCentralServerAddress() ); } else {