From cb097793f04c330b534de1571c3992fb38381d50 Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Sat, 15 Aug 2009 20:37:18 +0000 Subject: [PATCH] Added "Use High Quality Audio" check box in settings dialog (this changes the CELT bit rate actually) --- src/client.cpp | 42 ++- src/client.h | 422 +++++++++++----------- src/clientsettingsdlg.cpp | 18 + src/clientsettingsdlg.h | 181 +++++----- src/clientsettingsdlgbase.ui | 14 +- src/settings.cpp | 672 ++++++++++++++++++----------------- 6 files changed, 713 insertions(+), 636 deletions(-) diff --git a/src/client.cpp b/src/client.cpp index 573d4a0d..96e1f742 100755 --- a/src/client.cpp +++ b/src/client.cpp @@ -37,7 +37,9 @@ CClient::CClient ( const quint16 iPortNumber ) : bOpenChatOnNewMessage ( true ), bDoAutoSockBufSize ( true ), iSndCrdPrefFrameSizeFactor ( FRAME_SIZE_FACTOR_DEFAULT ), - iSndCrdFrameSizeFactor ( FRAME_SIZE_FACTOR_DEFAULT ) + iSndCrdFrameSizeFactor ( FRAME_SIZE_FACTOR_DEFAULT ), + iCeltNumCodedBytes ( CELT_NUM_BYTES_NORMAL_QUALITY ), + bCeltDoHighQuality ( false ) { // init audio endocder/decoder (mono) CeltMode = celt_mode_create ( @@ -157,7 +159,7 @@ bool CClient::SetServerAddr ( QString strNAddr ) void CClient::SetSndCrdPrefFrameSizeFactor ( const int iNewFactor ) { - // right now we simply set the internal value + // first check new input parameter if ( ( iNewFactor == FRAME_SIZE_FACTOR_PREFERRED ) || ( iNewFactor == FRAME_SIZE_FACTOR_DEFAULT ) || ( iNewFactor == FRAME_SIZE_FACTOR_SAFE ) ) @@ -183,6 +185,28 @@ void CClient::SetSndCrdPrefFrameSizeFactor ( const int iNewFactor ) } } +void CClient::SetCELTHighQuality ( const bool bNCeltHighQualityFlag ) +{ + // 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(); + } + + // set new parameter + bCeltDoHighQuality = bNCeltHighQualityFlag; + + // init with new block size index parameter + Init(); + + if ( bWasRunning ) + { + Sound.Start(); + } +} + QString CClient::SetSndCrdDev ( const int iNewDev ) { // if client was running then first @@ -289,7 +313,6 @@ void CClient::Init() iSndCrdFrameSizeFactor = iMonoBlockSizeSam / SYSTEM_FRAME_SIZE_SAMPLES; - vecsAudioSndCrdMono.Init ( iMonoBlockSizeSam ); vecsAudioSndCrdStereo.Init ( iStereoBlockSizeSam ); vecdAudioStereo.Init ( iStereoBlockSizeSam ); @@ -303,10 +326,15 @@ iSndCrdFrameSizeFactor = iMonoBlockSizeSam / SYSTEM_FRAME_SIZE_SAMPLES; // init reverberation AudioReverb.Init ( SYSTEM_SAMPLE_RATE ); - // 22: low/normal quality 150 kbsp (128) / 108 kbps (256) - // 44: high quality 216 kbps (128) / 174 kbps (256) - iCeltNumCodedBytes = 22; - + // inits for CELT coding + if ( bCeltDoHighQuality ) + { + iCeltNumCodedBytes = CELT_NUM_BYTES_HIGH_QUALITY; + } + else + { + iCeltNumCodedBytes = CELT_NUM_BYTES_NORMAL_QUALITY; + } vecCeltData.Init ( iCeltNumCodedBytes ); // init network buffers diff --git a/src/client.h b/src/client.h index a8800efe..185a72b0 100755 --- a/src/client.h +++ b/src/client.h @@ -1,206 +1,216 @@ -/******************************************************************************\ - * Copyright (c) 2004-2009 - * - * 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 - * -\******************************************************************************/ - -#if !defined ( CLIENT_HOIHGE76GEKJH98_3_43445KJIUHF1912__INCLUDED_ ) -#define CLIENT_HOIHGE76GEKJH98_3_43445KJIUHF1912__INCLUDED_ - -#include -#include -#include -#include -#include -#include -#include "celt.h" -#include "global.h" -#include "socket.h" -#include "channel.h" -#include "util.h" -#ifdef _WIN32 -# include "../windows/sound.h" -#else -# include "../linux/sound.h" -# include -# include -# include -#endif - - -/* Definitions ****************************************************************/ -// audio in fader range -#define AUD_FADER_IN_MIN 0 -#define AUD_FADER_IN_MAX 100 -#define AUD_FADER_IN_MIDDLE ( AUD_FADER_IN_MAX / 2 ) - -// audio reverberation range -#define AUD_REVERB_MAX 100 - - -/* Classes ********************************************************************/ -class CClient : public QObject -{ - Q_OBJECT - -public: - CClient ( const quint16 iPortNumber ); - virtual ~CClient() {} - - void Start(); - void Stop(); - bool IsRunning() { return Sound.IsRunning(); } - bool SetServerAddr ( QString strNAddr ); - double MicLevelL() { return SignalLevelMeter.MicLevelLeft(); } - double MicLevelR() { return SignalLevelMeter.MicLevelRight(); } - bool IsConnected() { return Channel.IsConnected(); } - - double GetTimingStdDev() { return CycleTimeVariance.GetStdDev(); } - - bool GetOpenChatOnNewMessage() { return bOpenChatOnNewMessage; } - void SetOpenChatOnNewMessage ( const bool bNV ) { bOpenChatOnNewMessage = bNV; } - - int GetAudioInFader() { return iAudioInFader; } - void SetAudioInFader ( const int iNV ) { iAudioInFader = iNV; } - - int GetReverbLevel() { return iReverbLevel; } - void SetReverbLevel ( const int iNL ) { iReverbLevel = iNL; } - - bool IsReverbOnLeftChan() { return bReverbOnLeftChan; } - void SetReverbOnLeftChan ( const bool bIL ) - { - bReverbOnLeftChan = bIL; - AudioReverb.Clear(); - } - - void SetDoAutoSockBufSize ( const bool bValue ) { bDoAutoSockBufSize = bValue; } - bool GetDoAutoSockBufSize() { return bDoAutoSockBufSize; } - void SetSockBufNumFrames ( const int iNumBlocks ) - { - // only change parameter if new parameter is different from current one - if ( Channel.GetSockBufNumFrames() != iNumBlocks ) - { - // set the new socket size (number of frames) - if ( !Channel.SetSockBufNumFrames ( iNumBlocks ) ) - { - // if setting of socket buffer size was successful, - // tell the server that size has changed - Channel.CreateJitBufMes ( iNumBlocks ); - } - } - } - int GetSockBufNumFrames() { return Channel.GetSockBufNumFrames(); } - - int GetUploadRateKbps() { return Channel.GetUploadRateKbps(); } - - int GetSndCrdNumDev() { return Sound.GetNumDev(); } - std::string GetSndCrdDeviceName ( const int iDiD ) - { return Sound.GetDeviceName ( iDiD ); } - - QString SetSndCrdDev ( const int iNewDev ); - int GetSndCrdDev() { return Sound.GetDev(); } - void OpenSndCrdDriverSetup() { Sound.OpenDriverSetup(); } - - void SetSndCrdPrefFrameSizeFactor ( const int iNewFactor ); - int GetSndCrdPrefFrameSizeFactor() - { return iSndCrdPrefFrameSizeFactor; } - int GetSndCrdActualMonoBlSize() { return iMonoBlockSizeSam; } - - void SetRemoteChanGain ( const int iId, const double dGain ) - { Channel.SetRemoteChanGain ( iId, dGain ); } - - void SetRemoteName() { Channel.SetRemoteName ( strName ); } - - void SendTextMess ( const QString& strChatText ) - { Channel.CreateChatTextMes ( strChatText ); } - - void SendPingMess() - { Channel.CreatePingMes ( PreciseTime.elapsed() ); }; - - CChannel* GetChannel() { return &Channel; } - - - // settings - CVector vstrIPAddress; - QString strName; - -protected: - // callback function must be static, otherwise it does not work - static void AudioCallback ( CVector& psData, void* arg ); - - void Init(); - void ProcessAudioData ( CVector& vecsStereoSndCrd ); - void UpdateSocketBufferSize(); - - // only one channel is needed for client application - CChannel Channel; - bool bDoAutoSockBufSize; - - // audio encoder/decoder - CELTMode* CeltMode; - CELTEncoder* CeltEncoder; - CELTDecoder* CeltDecoder; - int iCeltNumCodedBytes; - CVector vecCeltData; - - CSocket Socket; - CSound Sound; - CStereoSignalLevelMeter SignalLevelMeter; - - CVector vecbyNetwData; - - int iAudioInFader; - bool bReverbOnLeftChan; - int iReverbLevel; - CAudioReverb AudioReverb; - - int iSndCrdPrefFrameSizeFactor; - int iSndCrdFrameSizeFactor; - - int iMonoBlockSizeSam; - int iStereoBlockSizeSam; - - bool bOpenChatOnNewMessage; - - CVector vecsAudioSndCrdMono; - CVector vecsAudioSndCrdStereo; - CVector vecdAudioStereo; - CVector vecsNetwork; - - // for ping measurement - CPreciseTime PreciseTime; - - CCycleTimeVariance CycleTimeVariance; - -public slots: - void OnSendProtMessage ( CVector vecMessage ); - void OnReqJittBufSize(); - void OnNewConnection(); - void OnReceivePingMessage ( int iMs ); - void OnSndCrdReinitRequest(); - -signals: - void ConClientListMesReceived ( CVector vecChanInfo ); - void ChatTextReceived ( QString strChatText ); - void PingTimeReceived ( int iPingTime ); -}; - -#endif /* !defined ( CLIENT_HOIHGE76GEKJH98_3_43445KJIUHF1912__INCLUDED_ ) */ +/******************************************************************************\ + * Copyright (c) 2004-2009 + * + * 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 + * +\******************************************************************************/ + +#if !defined ( CLIENT_HOIHGE76GEKJH98_3_43445KJIUHF1912__INCLUDED_ ) +#define CLIENT_HOIHGE76GEKJH98_3_43445KJIUHF1912__INCLUDED_ + +#include +#include +#include +#include +#include +#include +#include "celt.h" +#include "global.h" +#include "socket.h" +#include "channel.h" +#include "util.h" +#ifdef _WIN32 +# include "../windows/sound.h" +#else +# include "../linux/sound.h" +# include +# include +# include +#endif + + +/* Definitions ****************************************************************/ +// audio in fader range +#define AUD_FADER_IN_MIN 0 +#define AUD_FADER_IN_MAX 100 +#define AUD_FADER_IN_MIDDLE ( AUD_FADER_IN_MAX / 2 ) + +// audio reverberation range +#define AUD_REVERB_MAX 100 + +// CELT number of coded bytes per audio packet +// 22: low/normal quality 150 kbsp (128) / 108 kbps (256) +// 44: high quality 216 kbps (128) / 174 kbps (256) +#define CELT_NUM_BYTES_NORMAL_QUALITY 22 +#define CELT_NUM_BYTES_HIGH_QUALITY 44 + + +/* Classes ********************************************************************/ +class CClient : public QObject +{ + Q_OBJECT + +public: + CClient ( const quint16 iPortNumber ); + virtual ~CClient() {} + + void Start(); + void Stop(); + bool IsRunning() { return Sound.IsRunning(); } + bool SetServerAddr ( QString strNAddr ); + double MicLevelL() { return SignalLevelMeter.MicLevelLeft(); } + double MicLevelR() { return SignalLevelMeter.MicLevelRight(); } + bool IsConnected() { return Channel.IsConnected(); } + + double GetTimingStdDev() { return CycleTimeVariance.GetStdDev(); } + + bool GetOpenChatOnNewMessage() { return bOpenChatOnNewMessage; } + void SetOpenChatOnNewMessage ( const bool bNV ) { bOpenChatOnNewMessage = bNV; } + + bool GetCELTHighQuality() { return bCeltDoHighQuality; } + void SetCELTHighQuality ( const bool bNCeltHighQualityFlag ); + + int GetAudioInFader() { return iAudioInFader; } + void SetAudioInFader ( const int iNV ) { iAudioInFader = iNV; } + + int GetReverbLevel() { return iReverbLevel; } + void SetReverbLevel ( const int iNL ) { iReverbLevel = iNL; } + + bool IsReverbOnLeftChan() { return bReverbOnLeftChan; } + void SetReverbOnLeftChan ( const bool bIL ) + { + bReverbOnLeftChan = bIL; + AudioReverb.Clear(); + } + + void SetDoAutoSockBufSize ( const bool bValue ) { bDoAutoSockBufSize = bValue; } + bool GetDoAutoSockBufSize() { return bDoAutoSockBufSize; } + void SetSockBufNumFrames ( const int iNumBlocks ) + { + // only change parameter if new parameter is different from current one + if ( Channel.GetSockBufNumFrames() != iNumBlocks ) + { + // set the new socket size (number of frames) + if ( !Channel.SetSockBufNumFrames ( iNumBlocks ) ) + { + // if setting of socket buffer size was successful, + // tell the server that size has changed + Channel.CreateJitBufMes ( iNumBlocks ); + } + } + } + int GetSockBufNumFrames() { return Channel.GetSockBufNumFrames(); } + + int GetUploadRateKbps() { return Channel.GetUploadRateKbps(); } + + int GetSndCrdNumDev() { return Sound.GetNumDev(); } + std::string GetSndCrdDeviceName ( const int iDiD ) + { return Sound.GetDeviceName ( iDiD ); } + + QString SetSndCrdDev ( const int iNewDev ); + int GetSndCrdDev() { return Sound.GetDev(); } + void OpenSndCrdDriverSetup() { Sound.OpenDriverSetup(); } + + void SetSndCrdPrefFrameSizeFactor ( const int iNewFactor ); + int GetSndCrdPrefFrameSizeFactor() + { return iSndCrdPrefFrameSizeFactor; } + int GetSndCrdActualMonoBlSize() { return iMonoBlockSizeSam; } + + void SetRemoteChanGain ( const int iId, const double dGain ) + { Channel.SetRemoteChanGain ( iId, dGain ); } + + void SetRemoteName() { Channel.SetRemoteName ( strName ); } + + void SendTextMess ( const QString& strChatText ) + { Channel.CreateChatTextMes ( strChatText ); } + + void SendPingMess() + { Channel.CreatePingMes ( PreciseTime.elapsed() ); }; + + CChannel* GetChannel() { return &Channel; } + + + // settings + CVector vstrIPAddress; + QString strName; + +protected: + // callback function must be static, otherwise it does not work + static void AudioCallback ( CVector& psData, void* arg ); + + void Init(); + void ProcessAudioData ( CVector& vecsStereoSndCrd ); + void UpdateSocketBufferSize(); + + // only one channel is needed for client application + CChannel Channel; + bool bDoAutoSockBufSize; + + // audio encoder/decoder + CELTMode* CeltMode; + CELTEncoder* CeltEncoder; + CELTDecoder* CeltDecoder; + int iCeltNumCodedBytes; + bool bCeltDoHighQuality; + CVector vecCeltData; + + CSocket Socket; + CSound Sound; + CStereoSignalLevelMeter SignalLevelMeter; + + CVector vecbyNetwData; + + int iAudioInFader; + bool bReverbOnLeftChan; + int iReverbLevel; + CAudioReverb AudioReverb; + + int iSndCrdPrefFrameSizeFactor; + int iSndCrdFrameSizeFactor; + + int iMonoBlockSizeSam; + int iStereoBlockSizeSam; + + bool bOpenChatOnNewMessage; + + CVector vecsAudioSndCrdMono; + CVector vecsAudioSndCrdStereo; + CVector vecdAudioStereo; + CVector vecsNetwork; + + // for ping measurement + CPreciseTime PreciseTime; + + CCycleTimeVariance CycleTimeVariance; + +public slots: + void OnSendProtMessage ( CVector vecMessage ); + void OnReqJittBufSize(); + void OnNewConnection(); + void OnReceivePingMessage ( int iMs ); + void OnSndCrdReinitRequest(); + +signals: + void ConClientListMesReceived ( CVector vecChanInfo ); + void ChatTextReceived ( QString strChatText ); + void PingTimeReceived ( int iPingTime ); +}; + +#endif /* !defined ( CLIENT_HOIHGE76GEKJH98_3_43445KJIUHF1912__INCLUDED_ ) */ diff --git a/src/clientsettingsdlg.cpp b/src/clientsettingsdlg.cpp index 66cbede2..30712304 100755 --- a/src/clientsettingsdlg.cpp +++ b/src/clientsettingsdlg.cpp @@ -83,6 +83,16 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent, cbOpenChatOnNewMessage->setCheckState ( Qt::Unchecked ); } + // "High Quality Audio" check box + if ( pClient->GetCELTHighQuality() ) + { + cbUseHighQualityAudio->setCheckState ( Qt::Checked ); + } + else + { + cbUseHighQualityAudio->setCheckState ( Qt::Unchecked ); + } + // set text for sound card buffer delay radio buttons rButBufferDelayPreferred->setText ( GenSndCrdBufferDelayString ( FRAME_SIZE_FACTOR_PREFERRED * SYSTEM_FRAME_SIZE_SAMPLES, @@ -117,6 +127,8 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent, // check boxes QObject::connect ( cbOpenChatOnNewMessage, SIGNAL ( stateChanged ( int ) ), this, SLOT ( OnOpenChatOnNewMessageStateChanged ( int ) ) ); + QObject::connect ( cbUseHighQualityAudio, SIGNAL ( stateChanged ( int ) ), + this, SLOT ( OnUseHighQualityAudioStateChanged ( int ) ) ); QObject::connect ( cbAutoJitBuf, SIGNAL ( stateChanged ( int ) ), this, SLOT ( OnAutoJitBuf ( int ) ) ); @@ -269,6 +281,12 @@ void CClientSettingsDlg::OnOpenChatOnNewMessageStateChanged ( int value ) UpdateDisplay(); } +void CClientSettingsDlg::OnUseHighQualityAudioStateChanged ( int value ) +{ + pClient->SetCELTHighQuality ( value == Qt::Checked ); + UpdateDisplay(); +} + void CClientSettingsDlg::OnSndCrdBufferDelayButtonGroupClicked ( QAbstractButton* button ) { if ( button == rButBufferDelayPreferred ) diff --git a/src/clientsettingsdlg.h b/src/clientsettingsdlg.h index fbafb75d..95310006 100755 --- a/src/clientsettingsdlg.h +++ b/src/clientsettingsdlg.h @@ -1,90 +1,91 @@ -/******************************************************************************\ - * Copyright (c) 2004-2009 - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "global.h" -#include "client.h" -#include "multicolorled.h" -#ifdef _WIN32 -# include "../windows/moc/clientsettingsdlgbase.h" -#else -# include "moc/clientsettingsdlgbase.h" -#endif - - -/* Definitions ****************************************************************/ -// update time for GUI controls -#define DISPLAY_UPDATE_TIME 1000 // ms -#define PING_UPDATE_TIME 500 // ms - - -/* Classes ********************************************************************/ -class CClientSettingsDlg : public QDialog, private Ui_CClientSettingsDlgBase -{ - Q_OBJECT - -public: - CClientSettingsDlg ( CClient* pNCliP, QWidget* parent = 0, - Qt::WindowFlags f = 0 ); - - void SetStatus ( const int iMessType, const int iStatus ); - -protected: - void UpdateJitterBufferFrame(); - void UpdateSoundCardFrame(); - QString GenSndCrdBufferDelayString ( const int iFrameSize, - const QString strAddText = "" ); - - virtual void showEvent ( QShowEvent* showEvent ); - virtual void hideEvent ( QHideEvent* hideEvent ); - - CClient* pClient; - QTimer TimerStatus; - QTimer TimerPing; - QButtonGroup SndCrdBufferDelayButtonGroup; - void UpdateDisplay(); - - public slots: - void OnTimerStatus() { UpdateDisplay(); } - void OnTimerPing(); - void OnSliderNetBuf ( int value ); - void OnSliderSndCrdBufferDelay ( int value ); - void OnAutoJitBuf ( int value ); - void OnOpenChatOnNewMessageStateChanged ( int value ); - void OnSndCrdBufferDelayButtonGroupClicked ( QAbstractButton* button ); - void OnPingTimeResult ( int iPingTime ); - void OnSoundCrdSelection ( int iSndDevIdx ); - void OnDriverSetupBut(); -}; +/******************************************************************************\ + * Copyright (c) 2004-2009 + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "global.h" +#include "client.h" +#include "multicolorled.h" +#ifdef _WIN32 +# include "../windows/moc/clientsettingsdlgbase.h" +#else +# include "moc/clientsettingsdlgbase.h" +#endif + + +/* Definitions ****************************************************************/ +// update time for GUI controls +#define DISPLAY_UPDATE_TIME 1000 // ms +#define PING_UPDATE_TIME 500 // ms + + +/* Classes ********************************************************************/ +class CClientSettingsDlg : public QDialog, private Ui_CClientSettingsDlgBase +{ + Q_OBJECT + +public: + CClientSettingsDlg ( CClient* pNCliP, QWidget* parent = 0, + Qt::WindowFlags f = 0 ); + + void SetStatus ( const int iMessType, const int iStatus ); + +protected: + void UpdateJitterBufferFrame(); + void UpdateSoundCardFrame(); + QString GenSndCrdBufferDelayString ( const int iFrameSize, + const QString strAddText = "" ); + + virtual void showEvent ( QShowEvent* showEvent ); + virtual void hideEvent ( QHideEvent* hideEvent ); + + CClient* pClient; + QTimer TimerStatus; + QTimer TimerPing; + QButtonGroup SndCrdBufferDelayButtonGroup; + void UpdateDisplay(); + + public slots: + void OnTimerStatus() { UpdateDisplay(); } + void OnTimerPing(); + void OnSliderNetBuf ( int value ); + void OnSliderSndCrdBufferDelay ( int value ); + void OnAutoJitBuf ( int value ); + void OnOpenChatOnNewMessageStateChanged ( int value ); + void OnUseHighQualityAudioStateChanged ( int value ); + 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 d9be6dff..58797307 100755 --- a/src/clientsettingsdlgbase.ui +++ b/src/clientsettingsdlgbase.ui @@ -297,7 +297,17 @@ - Open chat on new message + Open Chat on New Message + + + + + + + Qt::NonModal + + + Use High Quality Audio @@ -309,7 +319,7 @@ 201 - 16 + 41 diff --git a/src/settings.cpp b/src/settings.cpp index 2ebfbbfc..f235a0a6 100755 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1,331 +1,341 @@ -/******************************************************************************\ - * Copyright (c) 2004-2009 - * - * 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 "settings.h" - - -/* Implementation *************************************************************/ -void CSettings::ReadIniFile ( const QString& sFileName ) -{ - int iValue; - bool bValue; - QDomDocument IniXMLDocument; - - // load data from init-file - // prepare file name for loading initialization data from XML file - QString sCurFileName = sFileName; - if ( sCurFileName.isEmpty() ) - { - // if no file name is available, use default file name - sCurFileName = LLCON_INIT_FILE_NAME; - } - - // read data from file if possible - QFile file ( sCurFileName ); - if ( file.open ( QIODevice::ReadOnly ) ) - { - QTextStream in ( &file ); - IniXMLDocument.setContent ( in.readAll(), false ); - - file.close(); - } - - - // actual settings data --------------------------------------------------- - // IP addresses - for ( int iIPAddrIdx = 0; iIPAddrIdx < MAX_NUM_SERVER_ADDR_ITEMS; iIPAddrIdx++ ) - { - QString sDefaultIP = ""; - - // use default only for first entry - if ( iIPAddrIdx == 0 ) - { - sDefaultIP = DEFAULT_SERVER_ADDRESS; - } - - pClient->vstrIPAddress[iIPAddrIdx] = - GetIniSetting ( IniXMLDocument, "client", - QString ( "ipaddress%1" ).arg ( iIPAddrIdx ), sDefaultIP ); - } - - // name - pClient->strName = GetIniSetting ( IniXMLDocument, "client", "name" ); - - // audio fader - if ( GetNumericIniSet ( IniXMLDocument, "client", "audfad", - AUD_FADER_IN_MIN, AUD_FADER_IN_MAX, iValue ) ) - { - pClient->SetAudioInFader ( iValue ); - } - - // reverberation level - if ( GetNumericIniSet ( IniXMLDocument, "client", "revlev", - 0, AUD_REVERB_MAX, iValue ) ) - { - pClient->SetReverbLevel ( iValue ); - } - - // reverberation channel assignment - if ( GetFlagIniSet ( IniXMLDocument, "client", "reverblchan", bValue ) ) - { - pClient->SetReverbOnLeftChan ( bValue ); - } - - // sound card selection - // special case with this setting: the sound card initialization depends on this setting - // call, therefore, if no setting file parameter could be retrieved, the sound card is - // initialized with a default setting defined here - if ( GetNumericIniSet ( IniXMLDocument, "client", "auddevidx", - 1, MAX_NUMBER_SOUND_CARDS, iValue ) ) - { - pClient->SetSndCrdDev ( iValue ); - } - else - { - // use "INVALID_SNC_CARD_DEVICE" to tell the sound card driver that no - // device selection was done previously - pClient->SetSndCrdDev ( INVALID_SNC_CARD_DEVICE ); - } - - // sound card preferred buffer size index - if ( GetNumericIniSet ( IniXMLDocument, "client", "prefsndcrdbufidx", - FRAME_SIZE_FACTOR_PREFERRED, FRAME_SIZE_FACTOR_SAFE, 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->SetSndCrdPrefFrameSizeFactor ( iValue ); - } - } - - // automatic network jitter buffer size setting - if ( GetFlagIniSet ( IniXMLDocument, "client", "autojitbuf", bValue ) ) - { - pClient->SetDoAutoSockBufSize ( bValue ); - } - - // network jitter buffer size - if ( GetNumericIniSet ( IniXMLDocument, "client", "jitbuf", - MIN_NET_BUF_SIZE_NUM_BL, MAX_NET_BUF_SIZE_NUM_BL, iValue ) ) - { - pClient->SetSockBufNumFrames ( iValue ); - } - - // flag whether the chat window shall be opened on a new chat message - if ( GetFlagIniSet ( IniXMLDocument, "client", "openchatonnewmessage", bValue ) ) - { - pClient->SetOpenChatOnNewMessage ( bValue ); - } -} - -void CSettings::WriteIniFile ( const QString& sFileName ) -{ - // create XML document for storing initialization parameters - QDomDocument IniXMLDocument; - - - // actual settings data --------------------------------------------------- - // IP addresses - for ( int iIPAddrIdx = 0; iIPAddrIdx < MAX_NUM_SERVER_ADDR_ITEMS; iIPAddrIdx++ ) - { - PutIniSetting ( IniXMLDocument, "client", - QString ( "ipaddress%1" ).arg ( iIPAddrIdx ), - pClient->vstrIPAddress[iIPAddrIdx] ); - } - - // name - PutIniSetting ( IniXMLDocument, "client", "name", - pClient->strName ); - - // audio fader - SetNumericIniSet ( IniXMLDocument, "client", "audfad", - pClient->GetAudioInFader() ); - - // reverberation level - SetNumericIniSet ( IniXMLDocument, "client", "revlev", - pClient->GetReverbLevel() ); - - // reverberation channel assignment - SetFlagIniSet ( IniXMLDocument, "client", "reverblchan", - pClient->IsReverbOnLeftChan() ); - - // sound card selection - SetNumericIniSet ( IniXMLDocument, "client", "auddevidx", - pClient->GetSndCrdDev() ); - - // sound card preferred buffer size index - SetNumericIniSet ( IniXMLDocument, "client", "prefsndcrdbufidx", - pClient->GetSndCrdPrefFrameSizeFactor() ); - - // automatic network jitter buffer size setting - SetFlagIniSet ( IniXMLDocument, "client", "autojitbuf", - pClient->GetDoAutoSockBufSize() ); - - // network jitter buffer size - SetNumericIniSet ( IniXMLDocument, "client", "jitbuf", - pClient->GetSockBufNumFrames() ); - - // flag whether the chat window shall be opened on a new chat message - SetFlagIniSet ( IniXMLDocument, "client", "openchatonnewmessage", - pClient->GetOpenChatOnNewMessage() ); - - // prepare file name for storing initialization data in XML file - QString sCurFileName = sFileName; - if ( sCurFileName.isEmpty() ) - { - // if no file name is available, use default file name - sCurFileName = LLCON_INIT_FILE_NAME; - } - - // store XML data in file - QFile file ( sCurFileName ); - if ( file.open ( QIODevice::WriteOnly ) ) - { - QTextStream out ( &file ); - out << IniXMLDocument.toString(); - } -} - -void CSettings::SetNumericIniSet ( QDomDocument& xmlFile, const QString& strSection, - const QString& strKey, const int iValue ) -{ - // convert input parameter which is an integer to string and store - PutIniSetting ( xmlFile, strSection, strKey, QString("%1").arg(iValue) ); -} - -bool CSettings::GetNumericIniSet ( const QDomDocument& xmlFile, const QString& strSection, - const QString& strKey, const int iRangeStart, - const int iRangeStop, int& iValue ) -{ - // init return value - bool bReturn = false; - - const QString strGetIni = GetIniSetting ( xmlFile, strSection, strKey ); - - // check if it is a valid parameter - if ( !strGetIni.isEmpty() ) - { - // convert string from init file to integer - iValue = strGetIni.toInt(); - - // check range - if ( ( iValue >= iRangeStart ) && ( iValue <= iRangeStop ) ) - { - bReturn = true; - } - } - - return bReturn; -} - -void CSettings::SetFlagIniSet ( QDomDocument& xmlFile, const QString& strSection, - const QString& strKey, const bool bValue ) -{ - // we encode true -> "1" and false -> "0" - if ( bValue == true ) - { - PutIniSetting ( xmlFile, strSection, strKey, "1" ); - } - else - { - PutIniSetting ( xmlFile, strSection, strKey, "0" ); - } -} - -bool CSettings::GetFlagIniSet ( const QDomDocument& xmlFile, const QString& strSection, - const QString& strKey, bool& bValue ) -{ - // init return value - bool bReturn = false; - - const QString strGetIni = GetIniSetting ( xmlFile, strSection, strKey ); - - if ( !strGetIni.isEmpty() ) - { - if ( strGetIni.toInt() ) - { - bValue = true; - } - else - { - bValue = false; - } - - bReturn = true; - } - - return bReturn; -} - - -// Init-file routines using XML *********************************************** -QString CSettings::GetIniSetting ( const QDomDocument& xmlFile, const QString& sSection, - const QString& sKey, const QString& sDefaultVal ) -{ - // init return parameter with default value - QString sResult ( sDefaultVal ); - - // get section - QDomElement xmlSection = xmlFile.firstChildElement ( sSection ); - if ( !xmlSection.isNull() ) - { - // get key - QDomElement xmlKey = xmlSection.firstChildElement ( sKey ); - if ( !xmlKey.isNull() ) - { - // get value - sResult = xmlKey.text(); - } - } - - return sResult; -} - -void CSettings::PutIniSetting ( QDomDocument& xmlFile, const QString& sSection, - const QString& sKey, const QString& sValue ) -{ - // check if section is already there, if not then create it - QDomElement xmlSection = xmlFile.firstChildElement ( sSection ); - if ( xmlSection.isNull() ) - { - // create new root element and add to document - xmlSection = xmlFile.createElement ( sSection ); - xmlFile.appendChild ( xmlSection ); - } - - // check if key is already there, if not then create it - QDomElement xmlKey = xmlSection.firstChildElement ( sKey ); - if ( xmlKey.isNull() ) - { - xmlKey = xmlFile.createElement ( sKey ); - xmlSection.appendChild ( xmlKey ); - } - - // add actual data to the key - QDomText currentValue = xmlFile.createTextNode ( sValue ); - xmlKey.appendChild ( currentValue ); -} +/******************************************************************************\ + * Copyright (c) 2004-2009 + * + * 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 "settings.h" + + +/* Implementation *************************************************************/ +void CSettings::ReadIniFile ( const QString& sFileName ) +{ + int iValue; + bool bValue; + QDomDocument IniXMLDocument; + + // load data from init-file + // prepare file name for loading initialization data from XML file + QString sCurFileName = sFileName; + if ( sCurFileName.isEmpty() ) + { + // if no file name is available, use default file name + sCurFileName = LLCON_INIT_FILE_NAME; + } + + // read data from file if possible + QFile file ( sCurFileName ); + if ( file.open ( QIODevice::ReadOnly ) ) + { + QTextStream in ( &file ); + IniXMLDocument.setContent ( in.readAll(), false ); + + file.close(); + } + + + // actual settings data --------------------------------------------------- + // IP addresses + for ( int iIPAddrIdx = 0; iIPAddrIdx < MAX_NUM_SERVER_ADDR_ITEMS; iIPAddrIdx++ ) + { + QString sDefaultIP = ""; + + // use default only for first entry + if ( iIPAddrIdx == 0 ) + { + sDefaultIP = DEFAULT_SERVER_ADDRESS; + } + + pClient->vstrIPAddress[iIPAddrIdx] = + GetIniSetting ( IniXMLDocument, "client", + QString ( "ipaddress%1" ).arg ( iIPAddrIdx ), sDefaultIP ); + } + + // name + pClient->strName = GetIniSetting ( IniXMLDocument, "client", "name" ); + + // audio fader + if ( GetNumericIniSet ( IniXMLDocument, "client", "audfad", + AUD_FADER_IN_MIN, AUD_FADER_IN_MAX, iValue ) ) + { + pClient->SetAudioInFader ( iValue ); + } + + // reverberation level + if ( GetNumericIniSet ( IniXMLDocument, "client", "revlev", + 0, AUD_REVERB_MAX, iValue ) ) + { + pClient->SetReverbLevel ( iValue ); + } + + // reverberation channel assignment + if ( GetFlagIniSet ( IniXMLDocument, "client", "reverblchan", bValue ) ) + { + pClient->SetReverbOnLeftChan ( bValue ); + } + + // sound card selection + // special case with this setting: the sound card initialization depends on this setting + // call, therefore, if no setting file parameter could be retrieved, the sound card is + // initialized with a default setting defined here + if ( GetNumericIniSet ( IniXMLDocument, "client", "auddevidx", + 1, MAX_NUMBER_SOUND_CARDS, iValue ) ) + { + pClient->SetSndCrdDev ( iValue ); + } + else + { + // use "INVALID_SNC_CARD_DEVICE" to tell the sound card driver that no + // device selection was done previously + pClient->SetSndCrdDev ( INVALID_SNC_CARD_DEVICE ); + } + + // sound card preferred buffer size index + if ( GetNumericIniSet ( IniXMLDocument, "client", "prefsndcrdbufidx", + FRAME_SIZE_FACTOR_PREFERRED, FRAME_SIZE_FACTOR_SAFE, 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->SetSndCrdPrefFrameSizeFactor ( iValue ); + } + } + + // automatic network jitter buffer size setting + if ( GetFlagIniSet ( IniXMLDocument, "client", "autojitbuf", bValue ) ) + { + pClient->SetDoAutoSockBufSize ( bValue ); + } + + // network jitter buffer size + if ( GetNumericIniSet ( IniXMLDocument, "client", "jitbuf", + MIN_NET_BUF_SIZE_NUM_BL, MAX_NET_BUF_SIZE_NUM_BL, iValue ) ) + { + pClient->SetSockBufNumFrames ( iValue ); + } + + // flag whether the chat window shall be opened on a new chat message + if ( GetFlagIniSet ( IniXMLDocument, "client", "openchatonnewmessage", bValue ) ) + { + pClient->SetOpenChatOnNewMessage ( bValue ); + } + + // flag whether using high quality audio or not + if ( GetFlagIniSet ( IniXMLDocument, "client", "highqualityaudio", bValue ) ) + { + pClient->SetCELTHighQuality ( bValue ); + } +} + +void CSettings::WriteIniFile ( const QString& sFileName ) +{ + // create XML document for storing initialization parameters + QDomDocument IniXMLDocument; + + + // actual settings data --------------------------------------------------- + // IP addresses + for ( int iIPAddrIdx = 0; iIPAddrIdx < MAX_NUM_SERVER_ADDR_ITEMS; iIPAddrIdx++ ) + { + PutIniSetting ( IniXMLDocument, "client", + QString ( "ipaddress%1" ).arg ( iIPAddrIdx ), + pClient->vstrIPAddress[iIPAddrIdx] ); + } + + // name + PutIniSetting ( IniXMLDocument, "client", "name", + pClient->strName ); + + // audio fader + SetNumericIniSet ( IniXMLDocument, "client", "audfad", + pClient->GetAudioInFader() ); + + // reverberation level + SetNumericIniSet ( IniXMLDocument, "client", "revlev", + pClient->GetReverbLevel() ); + + // reverberation channel assignment + SetFlagIniSet ( IniXMLDocument, "client", "reverblchan", + pClient->IsReverbOnLeftChan() ); + + // sound card selection + SetNumericIniSet ( IniXMLDocument, "client", "auddevidx", + pClient->GetSndCrdDev() ); + + // sound card preferred buffer size index + SetNumericIniSet ( IniXMLDocument, "client", "prefsndcrdbufidx", + pClient->GetSndCrdPrefFrameSizeFactor() ); + + // automatic network jitter buffer size setting + SetFlagIniSet ( IniXMLDocument, "client", "autojitbuf", + pClient->GetDoAutoSockBufSize() ); + + // network jitter buffer size + SetNumericIniSet ( IniXMLDocument, "client", "jitbuf", + pClient->GetSockBufNumFrames() ); + + // flag whether the chat window shall be opened on a new chat message + SetFlagIniSet ( IniXMLDocument, "client", "openchatonnewmessage", + pClient->GetOpenChatOnNewMessage() ); + + // flag whether using high quality audio or not + SetFlagIniSet ( IniXMLDocument, "client", "highqualityaudio", + pClient->GetCELTHighQuality() ); + + // prepare file name for storing initialization data in XML file + QString sCurFileName = sFileName; + if ( sCurFileName.isEmpty() ) + { + // if no file name is available, use default file name + sCurFileName = LLCON_INIT_FILE_NAME; + } + + // store XML data in file + QFile file ( sCurFileName ); + if ( file.open ( QIODevice::WriteOnly ) ) + { + QTextStream out ( &file ); + out << IniXMLDocument.toString(); + } +} + +void CSettings::SetNumericIniSet ( QDomDocument& xmlFile, const QString& strSection, + const QString& strKey, const int iValue ) +{ + // convert input parameter which is an integer to string and store + PutIniSetting ( xmlFile, strSection, strKey, QString("%1").arg(iValue) ); +} + +bool CSettings::GetNumericIniSet ( const QDomDocument& xmlFile, const QString& strSection, + const QString& strKey, const int iRangeStart, + const int iRangeStop, int& iValue ) +{ + // init return value + bool bReturn = false; + + const QString strGetIni = GetIniSetting ( xmlFile, strSection, strKey ); + + // check if it is a valid parameter + if ( !strGetIni.isEmpty() ) + { + // convert string from init file to integer + iValue = strGetIni.toInt(); + + // check range + if ( ( iValue >= iRangeStart ) && ( iValue <= iRangeStop ) ) + { + bReturn = true; + } + } + + return bReturn; +} + +void CSettings::SetFlagIniSet ( QDomDocument& xmlFile, const QString& strSection, + const QString& strKey, const bool bValue ) +{ + // we encode true -> "1" and false -> "0" + if ( bValue == true ) + { + PutIniSetting ( xmlFile, strSection, strKey, "1" ); + } + else + { + PutIniSetting ( xmlFile, strSection, strKey, "0" ); + } +} + +bool CSettings::GetFlagIniSet ( const QDomDocument& xmlFile, const QString& strSection, + const QString& strKey, bool& bValue ) +{ + // init return value + bool bReturn = false; + + const QString strGetIni = GetIniSetting ( xmlFile, strSection, strKey ); + + if ( !strGetIni.isEmpty() ) + { + if ( strGetIni.toInt() ) + { + bValue = true; + } + else + { + bValue = false; + } + + bReturn = true; + } + + return bReturn; +} + + +// Init-file routines using XML *********************************************** +QString CSettings::GetIniSetting ( const QDomDocument& xmlFile, const QString& sSection, + const QString& sKey, const QString& sDefaultVal ) +{ + // init return parameter with default value + QString sResult ( sDefaultVal ); + + // get section + QDomElement xmlSection = xmlFile.firstChildElement ( sSection ); + if ( !xmlSection.isNull() ) + { + // get key + QDomElement xmlKey = xmlSection.firstChildElement ( sKey ); + if ( !xmlKey.isNull() ) + { + // get value + sResult = xmlKey.text(); + } + } + + return sResult; +} + +void CSettings::PutIniSetting ( QDomDocument& xmlFile, const QString& sSection, + const QString& sKey, const QString& sValue ) +{ + // check if section is already there, if not then create it + QDomElement xmlSection = xmlFile.firstChildElement ( sSection ); + if ( xmlSection.isNull() ) + { + // create new root element and add to document + xmlSection = xmlFile.createElement ( sSection ); + xmlFile.appendChild ( xmlSection ); + } + + // check if key is already there, if not then create it + QDomElement xmlKey = xmlSection.firstChildElement ( sKey ); + if ( xmlKey.isNull() ) + { + xmlKey = xmlFile.createElement ( sKey ); + xmlSection.appendChild ( xmlKey ); + } + + // add actual data to the key + QDomText currentValue = xmlFile.createTextNode ( sValue ); + xmlKey.appendChild ( currentValue ); +}