From 38fb4144de9ae5a1c52c664ced5a399e943db499 Mon Sep 17 00:00:00 2001 From: pgScorpio Date: Sun, 8 Sep 2024 11:48:03 +0200 Subject: [PATCH 1/7] Fix connection status issue (#2519) This is a manual port of https://github.com/jamulussoftware/jamulus/pull/2550 by @pgScorpio Co-authored-by: ann0see <20726856+ann0see@users.noreply.github.com> --- src/channel.cpp | 31 ++++++- src/channel.h | 3 +- src/client.cpp | 173 +++++++++++++++++++++----------------- src/client.h | 16 ++-- src/clientdlg.cpp | 137 +++++++++--------------------- src/clientdlg.h | 14 ++- src/clientsettingsdlg.cpp | 22 ++--- src/connectdlg.cpp | 0 src/main.cpp | 32 ++++--- 9 files changed, 208 insertions(+), 220 deletions(-) mode change 100755 => 100644 src/connectdlg.cpp diff --git a/src/channel.cpp b/src/channel.cpp index 53f91766a8..c2ff6ef5b2 100644 --- a/src/channel.cpp +++ b/src/channel.cpp @@ -37,6 +37,7 @@ CChannel::CChannel ( const bool bNIsServer ) : bIsEnabled ( false ), bIsServer ( bNIsServer ), bIsIdentified ( false ), + bDisconnectAndDisable ( false ), iAudioFrameSizeSamples ( DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES ), SignalLevelMeter ( false, 0.5 ) // server mode with mono out and faster smoothing { @@ -125,7 +126,8 @@ void CChannel::SetEnable ( const bool bNEnStat ) QMutexLocker locker ( &Mutex ); // set internal parameter - bIsEnabled = bNEnStat; + bIsEnabled = bNEnStat; + bDisconnectAndDisable = false; // The support for the packet sequence number must be reset if the client // disconnects from a server since we do not yet know if the next server we @@ -506,11 +508,24 @@ void CChannel::Disconnect() // we only have to disconnect the channel if it is actually connected if ( IsConnected() ) { + // for a Client, block further audio data and disable the channel as soon as Disconnect() is called + // TODO: Add reasoning from #2550 + + bDisconnectAndDisable = !bIsServer; + // set time out counter to a small value > 0 so that the next time a // received audio block is queried, the disconnection is performed // (assuming that no audio packet is received in the meantime) iConTimeOut = 1; // a small number > 0 } + else if ( !bIsServer ) + { + // For clients (?) set defaults + + bDisconnectAndDisable = false; + bIsEnabled = false; + iConTimeOut = 0; + } } void CChannel::PutProtocolData ( const int iRecCounter, const int iRecID, const CVector& vecbyMesBodyData, const CHostAddress& RecHostAddr ) @@ -534,7 +549,7 @@ EPutDataStat CChannel::PutAudioData ( const CVector& vecbyData, const i // Only process audio data if: // - for client only: the packet comes from the server we want to talk to // - the channel is enabled - if ( ( bIsServer || ( GetAddress() == RecHostAddr ) ) && IsEnabled() ) + if ( ( bIsServer || ( GetAddress() == RecHostAddr ) ) && IsEnabled() && !bDisconnectAndDisable ) { MutexSocketBuf.lock(); { @@ -622,6 +637,11 @@ EGetDataStat CChannel::GetData ( CVector& vecbyData, const int iNumByte eGetStatus = GS_CHAN_NOW_DISCONNECTED; iConTimeOut = 0; // make sure we do not have negative values + if ( bDisconnectAndDisable ) + { + bDisconnectAndDisable = false; + bIsEnabled = false; + } // reset network transport properties ResetNetworkTransportProperties(); } @@ -643,6 +663,13 @@ EGetDataStat CChannel::GetData ( CVector& vecbyData, const int iNumByte { // channel is disconnected eGetStatus = GS_CHAN_NOT_CONNECTED; + + if ( bDisconnectAndDisable ) + { + bDisconnectAndDisable = false; + bIsEnabled = false; + iConTimeOut = 0; + } } } MutexSocketBuf.unlock(); diff --git a/src/channel.h b/src/channel.h index 9f70bfee6f..360b2aba1c 100644 --- a/src/channel.h +++ b/src/channel.h @@ -76,7 +76,7 @@ class CChannel : public QObject void PrepAndSendPacket ( CHighPrioSocket* pSocket, const CVector& vecbyNPacket, const int iNPacketLen ); - void ResetTimeOutCounter() { iConTimeOut = iConTimeOutStartVal; } + void ResetTimeOutCounter() { iConTimeOut = bDisconnectAndDisable ? 1 : iConTimeOutStartVal; } bool IsConnected() const { return iConTimeOut > 0; } void Disconnect(); @@ -216,6 +216,7 @@ class CChannel : public QObject bool bIsEnabled; bool bIsServer; bool bIsIdentified; + bool bDisconnectAndDisable; int iNetwFrameSizeFact; int iNetwFrameSize; diff --git a/src/client.cpp b/src/client.cpp index d3d2c51c9a..be686978bf 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -27,7 +27,6 @@ /* Implementation *************************************************************/ CClient::CClient ( const quint16 iPortNumber, const quint16 iQosNumber, - const QString& strConnOnStartupAddress, const QString& strMIDISetup, const bool bNoAutoJackConnect, const QString& strNClientName, @@ -184,13 +183,6 @@ CClient::CClient ( const quint16 iPortNumber, // start the socket (it is important to start the socket after all // initializations and connections) Socket.Start(); - - // do an immediate start if a server address is given - if ( !strConnOnStartupAddress.isEmpty() ) - { - SetServerAddr ( strConnOnStartupAddress ); - Start(); - } } CClient::~CClient() @@ -337,7 +329,7 @@ void CClient::CreateServerJitterBufferMessage() void CClient::OnCLPingReceived ( CHostAddress InetAddr, int iMs ) { // make sure we are running and the server address is correct - if ( IsRunning() && ( InetAddr == Channel.GetAddress() ) ) + if ( Channel.IsEnabled() && ( InetAddr == Channel.GetAddress() ) ) { // take care of wrap arounds (if wrapping, do not use result) const int iCurDiff = EvaluatePingMessage ( iMs ); @@ -474,26 +466,6 @@ void CClient::StartDelayTimer() } } -bool CClient::SetServerAddr ( QString strNAddr ) -{ - CHostAddress HostAddress; -#ifdef CLIENT_NO_SRV_CONNECT - if ( NetworkUtil().ParseNetworkAddress ( strNAddr, HostAddress, bEnableIPv6 ) ) -#else - if ( NetworkUtil().ParseNetworkAddressWithSrvDiscovery ( strNAddr, HostAddress, bEnableIPv6 ) ) -#endif - { - // apply address to the channel - Channel.SetAddress ( HostAddress ); - - return true; - } - else - { - return false; // invalid address - } -} - bool CClient::GetAndResetbJitterBufferOKFlag() { // get the socket buffer put status flag and reset it @@ -626,12 +598,16 @@ QString CClient::SetSndCrdDev ( const QString strNewDev ) Sound.Start(); } - // in case of an error inform the GUI about it if ( !strError.isEmpty() ) { - emit SoundDeviceChanged ( strError ); + // due to error, disconnect + Disconnect(); } + // in case of an error, this will inform the GUI about it + + emit SoundDeviceChanged(); + return strError; } @@ -758,8 +734,18 @@ void CClient::OnSndCrdReinitRequest ( int iSndCrdResetType ) } MutexDriverReinit.unlock(); + if ( !strError.isEmpty() ) + { +#ifndef HEADLESS + QMessageBox::critical ( 0, APP_NAME, strError, tr ( "Ok" ) ); +#else + qCritical() << qUtf8Printable ( strError ); + exit ( 1 ); +#endif + } + // inform GUI about the sound card device change - emit SoundDeviceChanged ( strError ); + emit SoundDeviceChanged(); } void CClient::OnHandledSignal ( int sigNum ) @@ -773,11 +759,8 @@ void CClient::OnHandledSignal ( int sigNum ) { case SIGINT: case SIGTERM: - // if connected, terminate connection (needed for headless mode) - if ( IsRunning() ) - { - Stop(); - } + // if connected, terminate connection + Disconnect(); // this should trigger OnAboutToQuit QCoreApplication::instance()->exit(); @@ -862,50 +845,88 @@ void CClient::OnClientIDReceived ( int iChanID ) emit ClientIDReceived ( iChanID ); } -void CClient::Start() +bool CClient::Connect ( QString strServerAddress, QString strServerName ) { - // init object - Init(); + if ( !Channel.IsEnabled() ) + { + CHostAddress HostAddress; + + if ( NetworkUtil().ParseNetworkAddress ( strServerAddress, HostAddress, bEnableIPv6 ) ) + { + // init object + Init(); + // apply address to the channel + Channel.SetAddress ( HostAddress ); - // enable channel - Channel.SetEnable ( true ); + // enable channel + Channel.SetEnable ( true ); - // start audio interface - Sound.Start(); + // start audio interface + Sound.Start(); + + // Notify ClientDlg + emit Connecting ( strServerName ); + + return true; + } + } + + return false; } -void CClient::Stop() +bool CClient::Disconnect() { - // stop audio interface - Sound.Stop(); - - // disable channel - Channel.SetEnable ( false ); - - // wait for approx. 100 ms to make sure no audio packet is still in the - // network queue causing the channel to be reconnected right after having - // received the disconnect message (seems not to gain much, disconnect is - // still not working reliably) - QTime DieTime = QTime::currentTime().addMSecs ( 100 ); - while ( QTime::currentTime() < DieTime ) - { - // exclude user input events because if we use AllEvents, it happens - // that if the user initiates a connection and disconnection quickly - // (e.g. quickly pressing enter five times), the software can get into - // an unknown state - QCoreApplication::processEvents ( QEventLoop::ExcludeUserInputEvents, 100 ); - } - - // Send disconnect message to server (Since we disable our protocol - // receive mechanism with the next command, we do not evaluate any - // respond from the server, therefore we just hope that the message - // gets its way to the server, if not, the old behaviour time-out - // disconnects the connection anyway). - ConnLessProtocol.CreateCLDisconnection ( Channel.GetAddress() ); - - // reset current signal level and LEDs - bJitterBufferOK = true; - SignalLevelMeter.Reset(); + if ( Channel.IsEnabled() ) + { + // start disconnection + Channel.Disconnect(); + + // Channel.Disconnect() should automatically disable Channel as soon as disconnected. + // Note that this only works if Sound is Active ! + + QTime DieTime = QTime::currentTime().addMSecs ( 500 ); + while ( ( QTime::currentTime() < DieTime ) && Channel.IsEnabled() ) + { + // exclude user input events because if we use AllEvents, it happens + // that if the user initiates a connection and disconnection quickly + // (e.g. quickly pressing enter five times), the software can get into + // an unknown state + QCoreApplication::processEvents ( QEventLoop::ExcludeUserInputEvents, 100 ); + } + + // Now stop the audio interface + Sound.Stop(); + + // in case we timed out, log warning and make sure Channel is disabled + if ( Channel.IsEnabled() ) + { + Channel.SetEnable ( false ); + } + + // Send disconnect message to server (Since we disable our protocol + // receive mechanism with the next command, we do not evaluate any + // respond from the server, therefore we just hope that the message + // gets its way to the server, if not, the old behaviour time-out + // disconnects the connection anyway). + ConnLessProtocol.CreateCLDisconnection ( Channel.GetAddress() ); + + // reset current signal level and LEDs + bJitterBufferOK = true; + SignalLevelMeter.Reset(); + + emit Disconnected(); + + return true; + } + else + { + // make sure sound is stopped too + Sound.Stop(); + + emit Disconnected(); + + return false; + } } void CClient::Init() @@ -921,7 +942,7 @@ void CClient::Init() bFraSiFactSafeSupported = true; #else bFraSiFactPrefSupported = ( Sound.Init ( iFraSizePreffered ) == iFraSizePreffered ); - bFraSiFactDefSupported = ( Sound.Init ( iFraSizeDefault ) == iFraSizeDefault ); + bFraSiFactDefSupported = ( Sound.Init ( iFraSizeDefault ) == iFraSizeDefault ); bFraSiFactSafeSupported = ( Sound.Init ( iFraSizeSafe ) == iFraSizeSafe ); #endif diff --git a/src/client.h b/src/client.h index 1fc33d8430..e467623f52 100644 --- a/src/client.h +++ b/src/client.h @@ -110,7 +110,6 @@ class CClient : public QObject public: CClient ( const quint16 iPortNumber, const quint16 iQosNumber, - const QString& strConnOnStartupAddress, const QString& strMIDISetup, const bool bNoAutoJackConnect, const QString& strNClientName, @@ -119,19 +118,17 @@ class CClient : public QObject virtual ~CClient(); - void Start(); - void Stop(); - bool IsRunning() { return Sound.IsRunning(); } - bool IsCallbackEntered() const { return Sound.IsCallbackEntered(); } - bool SetServerAddr ( QString strNAddr ); + bool Connect ( QString strServerAddress, QString strServerName ); + bool Disconnect(); + + bool SoundIsRunning() const { return Sound.IsCallbackEntered(); } // For OnTimerCheckAudioDeviceOk only + bool IsConnected() { return Channel.IsConnected(); } double GetLevelForMeterdBLeft() { return SignalLevelMeter.GetLevelForMeterdBLeftOrMono(); } double GetLevelForMeterdBRight() { return SignalLevelMeter.GetLevelForMeterdBRight(); } bool GetAndResetbJitterBufferOKFlag(); - bool IsConnected() { return Channel.IsConnected(); } - EGUIDesign GetGUIDesign() const { return eGUIDesign; } void SetGUIDesign ( const EGUIDesign eNGD ) { eGUIDesign = eNGD; } @@ -427,8 +424,9 @@ protected slots: void CLChannelLevelListReceived ( CHostAddress InetAddr, CVector vecLevelList ); + void Connecting ( QString strServerName ); void Disconnected(); - void SoundDeviceChanged ( QString strError ); + void SoundDeviceChanged(); void ControllerInFaderLevel ( int iChannelIdx, int iValue ); void ControllerInPanValue ( int iChannelIdx, int iValue ); void ControllerInFaderIsSolo ( int iChannelIdx, bool bIsSolo ); diff --git a/src/clientdlg.cpp b/src/clientdlg.cpp index 99b9fa6433..811e83b427 100644 --- a/src/clientdlg.cpp +++ b/src/clientdlg.cpp @@ -27,7 +27,6 @@ /* Implementation *************************************************************/ CClientDlg::CClientDlg ( CClient* pNCliP, CClientSettings* pNSetP, - const QString& strConnOnStartupAddress, const QString& strMIDISetup, const bool bNewShowComplRegConnList, const bool bShowAnalyzerConsole, @@ -272,14 +271,6 @@ CClientDlg::CClientDlg ( CClient* pNCliP, TimerCheckAudioDeviceOk.setSingleShot ( true ); // only check once after connection TimerDetectFeedback.setSingleShot ( true ); - // Connect on startup ------------------------------------------------------ - if ( !strConnOnStartupAddress.isEmpty() ) - { - // initiate connection (always show the address in the mixer board - // (no alias)) - Connect ( strConnOnStartupAddress, strConnOnStartupAddress ); - } - // File menu -------------------------------------------------------------- QMenu* pFileMenu = new QMenu ( tr ( "&File" ), this ); @@ -473,7 +464,9 @@ CClientDlg::CClientDlg ( CClient* pNCliP, // other QObject::connect ( pClient, &CClient::ConClientListMesReceived, this, &CClientDlg::OnConClientListMesReceived ); - QObject::connect ( pClient, &CClient::Disconnected, this, &CClientDlg::OnDisconnected ); + QObject::connect ( pClient, &CClient::Connecting, this, &CClientDlg::OnConnect ); + + QObject::connect ( pClient, &CClient::Disconnected, this, &CClientDlg::OnDisconnect ); QObject::connect ( pClient, &CClient::ChatTextReceived, this, &CClientDlg::OnChatTextReceived ); @@ -608,11 +601,7 @@ void CClientDlg::closeEvent ( QCloseEvent* Event ) ConnectDlg.close(); AnalyzerConsole.close(); - // if connected, terminate connection - if ( pClient->IsRunning() ) - { - pClient->Stop(); - } + pClient->Disconnect(); // make sure all current fader settings are applied to the settings struct MainMixerBoard->StoreAllFaderSettings(); @@ -730,15 +719,12 @@ void CClientDlg::OnConnectDlgAccepted() } } - // first check if we are already connected, if this is the case we have to - // disconnect the old server first - if ( pClient->IsRunning() ) + // initiate connection + if ( pClient->Connect ( strSelectedAddress, strMixerBoardLabel ) ) { - Disconnect(); + OnConnect ( strMixerBoardLabel ); } - - // initiate connection - Connect ( strSelectedAddress, strMixerBoardLabel ); + // TODO: investigate and add error handling on failed Connect() call. // reset flag bConnectDlgWasShown = false; @@ -748,10 +734,10 @@ void CClientDlg::OnConnectDlgAccepted() void CClientDlg::OnConnectDisconBut() { // the connect/disconnect button implements a toggle functionality - if ( pClient->IsRunning() ) + if ( pClient->Disconnect() ) { - Disconnect(); - SetMixerBoardDeco ( RS_UNDEFINED, pClient->GetGUIDesign() ); + // Client was Connected, now disconnected + // TODO: Refactor this with !pClient->Disconnect() } else { @@ -841,7 +827,7 @@ void CClientDlg::OnChatTextReceived ( QString strChatText ) // always when a new message arrives since this is annoying. ShowChatWindow ( ( strChatText.indexOf ( WELCOME_MESSAGE_PREFIX ) == 0 ) ); - UpdateDisplay(); + UpdateSettingsAndChatButtons(); } void CClientDlg::OnLicenceRequired ( ELicenceType eLicenceType ) @@ -859,7 +845,7 @@ void CClientDlg::OnLicenceRequired ( ELicenceType eLicenceType ) // disconnect from that server. if ( !LicenceDlg.exec() ) { - Disconnect(); + pClient->Disconnect(); } // unmute the client output stream if local mute button is not pressed @@ -996,7 +982,7 @@ void CClientDlg::ShowChatWindow ( const bool bForceRaise ) ChatDlg.activateWindow(); } - UpdateDisplay(); + UpdateSettingsAndChatButtons(); } void CClientDlg::ShowAnalyzerConsole() @@ -1146,7 +1132,7 @@ void CClientDlg::OnTimerCheckAudioDeviceOk() // timeout to check if a valid device is selected and if we do not have // fundamental settings errors (in which case the GUI would only show that // it is trying to connect the server which does not help to solve the problem (#129)) - if ( !pClient->IsCallbackEntered() ) + if ( !pClient->SoundIsRunning() ) { QMessageBox::warning ( this, APP_NAME, @@ -1157,20 +1143,8 @@ void CClientDlg::OnTimerCheckAudioDeviceOk() void CClientDlg::OnTimerDetectFeedback() { bDetectFeedback = false; } -void CClientDlg::OnSoundDeviceChanged ( QString strError ) +void CClientDlg::OnSoundDeviceChanged() { - if ( !strError.isEmpty() ) - { - // the sound device setup has a problem, disconnect any active connection - if ( pClient->IsRunning() ) - { - Disconnect(); - } - - // show the error message of the device setup - QMessageBox::critical ( this, APP_NAME, strError, tr ( "Ok" ), nullptr ); - } - // if the check audio device timer is running, it must be restarted on a device change if ( TimerCheckAudioDeviceOk.isActive() ) { @@ -1193,65 +1167,36 @@ void CClientDlg::OnCLPingTimeWithNumClientsReceived ( CHostAddress InetAddr, int ConnectDlg.SetPingTimeAndNumClientsResult ( InetAddr, iPingTime, iNumClients ); } -void CClientDlg::Connect ( const QString& strSelectedAddress, const QString& strMixerBoardLabel ) +void CClientDlg::OnConnect ( QString strServerName ) { - // set address and check if address is valid - if ( pClient->SetServerAddr ( strSelectedAddress ) ) - { - // try to start client, if error occurred, do not go in - // running state but show error message - try - { - if ( !pClient->IsRunning() ) - { - pClient->Start(); - } - } - catch ( const CGenErr& generr ) - { - // show error message and return the function - QMessageBox::critical ( this, APP_NAME, generr.GetErrorText(), "Close", nullptr ); - return; - } + // hide label connect to server + lblConnectToServer->hide(); + lbrInputLevelL->setEnabled ( true ); + lbrInputLevelR->setEnabled ( true ); - // hide label connect to server - lblConnectToServer->hide(); - lbrInputLevelL->setEnabled ( true ); - lbrInputLevelR->setEnabled ( true ); + // change connect button text to "disconnect" + butConnect->setText ( tr ( "&Disconnect" ) ); - // change connect button text to "disconnect" - butConnect->setText ( tr ( "&Disconnect" ) ); + // set server name in audio mixer group box title + MainMixerBoard->SetServerName ( strServerName ); - // set server name in audio mixer group box title - MainMixerBoard->SetServerName ( strMixerBoardLabel ); + // start timer for level meter bar and ping time measurement + TimerSigMet.start ( LEVELMETER_UPDATE_TIME_MS ); + TimerBuffersLED.start ( BUFFER_LED_UPDATE_TIME_MS ); + TimerPing.start ( PING_UPDATE_TIME_MS ); + TimerCheckAudioDeviceOk.start ( CHECK_AUDIO_DEV_OK_TIME_MS ); // is single shot timer - // start timer for level meter bar and ping time measurement - TimerSigMet.start ( LEVELMETER_UPDATE_TIME_MS ); - TimerBuffersLED.start ( BUFFER_LED_UPDATE_TIME_MS ); - TimerPing.start ( PING_UPDATE_TIME_MS ); - TimerCheckAudioDeviceOk.start ( CHECK_AUDIO_DEV_OK_TIME_MS ); // is single shot timer - - // audio feedback detection - if ( pSettings->bEnableFeedbackDetection ) - { - TimerDetectFeedback.start ( DETECT_FEEDBACK_TIME_MS ); // single shot timer - bDetectFeedback = true; - } + // audio feedback detection + if ( pSettings->bEnableFeedbackDetection ) + { + TimerDetectFeedback.start ( DETECT_FEEDBACK_TIME_MS ); // single shot timer + bDetectFeedback = true; } } -void CClientDlg::Disconnect() +void CClientDlg::OnDisconnect() { - // only stop client if currently running, in case we received - // the stopped message, the client is already stopped but the - // connect/disconnect button and other GUI controls must be - // updated - if ( pClient->IsRunning() ) - { - pClient->Stop(); - } - // change connect button text to "connect" butConnect->setText ( tr ( "C&onnect" ) ); @@ -1275,11 +1220,7 @@ void CClientDlg::Disconnect() TimerDetectFeedback.stop(); bDetectFeedback = false; - //### TODO: BEGIN ###// - // is this still required??? - // immediately update status bar - OnTimerStatus(); - //### TODO: END ###// + UpdateSettingsAndChatButtons(); // reset LEDs ledBuffers->Reset(); @@ -1293,9 +1234,11 @@ void CClientDlg::Disconnect() // clear mixer board (remove all faders) MainMixerBoard->HideAll(); + + SetMixerBoardDeco ( RS_UNDEFINED, pClient->GetGUIDesign() ); } -void CClientDlg::UpdateDisplay() +void CClientDlg::UpdateSettingsAndChatButtons() { // update settings/chat buttons (do not fire signals since it is an update) if ( chbSettings->isChecked() && !ClientSettingsDlg.isVisible() ) diff --git a/src/clientdlg.h b/src/clientdlg.h index 9737bcd2ca..12c65f7289 100644 --- a/src/clientdlg.h +++ b/src/clientdlg.h @@ -76,7 +76,6 @@ class CClientDlg : public CBaseDlg, private Ui_CClientDlgBase public: CClientDlg ( CClient* pNCliP, CClientSettings* pNSetP, - const QString& strConnOnStartupAddress, const QString& strMIDISetup, const bool bNewShowComplRegConnList, const bool bShowAnalyzerConsole, @@ -93,10 +92,8 @@ class CClientDlg : public CBaseDlg, private Ui_CClientDlgBase void ShowChatWindow ( const bool bForceRaise = true ); void ShowAnalyzerConsole(); void UpdateAudioFaderSlider(); - void UpdateRevSelection(); - void Connect ( const QString& strSelectedAddress, const QString& strMixerBoardLabel ); - void Disconnect(); void ManageDragNDrop ( QDropEvent* Event, const bool bCheckAccept ); + void UpdateRevSelection(); void SetPingTime ( const int iPingTime, const int iOverallDelayMs, const CMultiColorLED::ELightColor eOverallDelayLEDColor ); CClient* pClient; @@ -119,7 +116,7 @@ class CClientDlg : public CBaseDlg, private Ui_CClientDlgBase virtual void closeEvent ( QCloseEvent* Event ); virtual void dragEnterEvent ( QDragEnterEvent* Event ) { ManageDragNDrop ( Event, true ); } virtual void dropEvent ( QDropEvent* Event ) { ManageDragNDrop ( Event, false ); } - void UpdateDisplay(); + void UpdateSettingsAndChatButtons(); CClientSettingsDlg ClientSettingsDlg; CChatDlg ChatDlg; @@ -127,13 +124,15 @@ class CClientDlg : public CBaseDlg, private Ui_CClientDlgBase CAnalyzerConsole AnalyzerConsole; public slots: + void OnConnect ( QString strServerName ); + void OnDisconnect(); void OnConnectDisconBut(); void OnTimerSigMet(); void OnTimerBuffersLED(); void OnTimerCheckAudioDeviceOk(); void OnTimerDetectFeedback(); - void OnTimerStatus() { UpdateDisplay(); } + void OnTimerStatus() { UpdateSettingsAndChatButtons(); } void OnTimerPing(); void OnPingTimeResult ( int iPingTime ); @@ -191,7 +190,7 @@ public slots: void OnConClientListMesReceived ( CVector vecChanInfo ); void OnChatTextReceived ( QString strChatText ); void OnLicenceRequired ( ELicenceType eLicenceType ); - void OnSoundDeviceChanged ( QString strError ); + void OnSoundDeviceChanged(); void OnChangeChanGain ( int iId, float fGain, bool bIsMyOwnFader ) { pClient->SetRemoteChanGain ( iId, fGain, bIsMyOwnFader ); } @@ -232,7 +231,6 @@ public slots: } void OnConnectDlgAccepted(); - void OnDisconnected() { Disconnect(); } void OnGUIDesignChanged(); void OnMeterStyleChanged(); void OnRecorderStateReceived ( ERecorderState eRecorderState ); diff --git a/src/clientsettingsdlg.cpp b/src/clientsettingsdlg.cpp index 58d51701a7..2a5b5522e9 100644 --- a/src/clientsettingsdlg.cpp +++ b/src/clientsettingsdlg.cpp @@ -1066,22 +1066,24 @@ void CClientSettingsDlg::OnSndCrdBufferDelayButtonGroupClicked ( QAbstractButton void CClientSettingsDlg::UpdateUploadRate() { // update upstream rate information label - lblUpstreamValue->setText ( QString().setNum ( pClient->GetUploadRateKbps() ) ); - lblUpstreamUnit->setText ( "kbps" ); + if ( pClient->IsConnected() ) + { + lblUpstreamValue->setText ( QString().setNum ( pClient->GetUploadRateKbps() ) ); + lblUpstreamUnit->setText ( "kbps" ); + } + else + { + lblUpstreamValue->setText ( "---" ); + lblUpstreamUnit->setText ( "" ); + } } void CClientSettingsDlg::UpdateDisplay() { - // update slider controls (settings might have been changed) + // update slider controls (settings might have been changed) and upstream rate information label UpdateJitterBufferFrame(); UpdateSoundCardFrame(); - - if ( !pClient->IsRunning() ) - { - // clear text labels with client parameters - lblUpstreamValue->setText ( "---" ); - lblUpstreamUnit->setText ( "" ); - } + UpdateUploadRate(); } void CClientSettingsDlg::UpdateDirectoryComboBox() diff --git a/src/connectdlg.cpp b/src/connectdlg.cpp old mode 100755 new mode 100644 diff --git a/src/main.cpp b/src/main.cpp index 42d17a8dea..5dc16ed57e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -919,14 +919,7 @@ int main ( int argc, char** argv ) { // Client: // actual client object - CClient Client ( iPortNumber, - iQosNumber, - strConnOnStartupAddress, - strMIDISetup, - bNoAutoJackConnect, - strClientName, - bEnableIPv6, - bMuteMeInPersonalMix ); + CClient Client ( iPortNumber, iQosNumber, strMIDISetup, bNoAutoJackConnect, strClientName, bEnableIPv6, bMuteMeInPersonalMix ); // load settings from init-file (command line options override) CClientSettings Settings ( &Client, strIniFileName ); @@ -950,19 +943,18 @@ int main ( int argc, char** argv ) } // GUI object - CClientDlg ClientDlg ( &Client, - &Settings, - strConnOnStartupAddress, - strMIDISetup, - bShowComplRegConnList, - bShowAnalyzerConsole, - bMuteStream, - bEnableIPv6, - nullptr ); + CClientDlg + ClientDlg ( &Client, &Settings, strMIDISetup, bShowComplRegConnList, bShowAnalyzerConsole, bMuteStream, bEnableIPv6, nullptr ); // show dialog ClientDlg.show(); + // Connect on startup + if ( !strConnOnStartupAddress.isEmpty() ) + { + Client.Connect ( strConnOnStartupAddress, strConnOnStartupAddress ); + } + pApp->exec(); } else @@ -971,6 +963,12 @@ int main ( int argc, char** argv ) // only start application without using the GUI qInfo() << qUtf8Printable ( GetVersionAndNameStr ( false ) ); + // Connect on startup + if ( !strConnOnStartupAddress.isEmpty() ) + { + Client.Connect ( strConnOnStartupAddress, strConnOnStartupAddress ); + } + pApp->exec(); } } From a5af8ccd478e405e0ccbc760315c366f12c97367 Mon Sep 17 00:00:00 2001 From: ann0see <20726856+ann0see@users.noreply.github.com> Date: Sun, 8 Sep 2024 17:13:56 +0200 Subject: [PATCH 2/7] Revert some changes for now --- src/client.cpp | 2 +- src/client.h | 6 ++++-- src/clientdlg.cpp | 10 +++++----- src/clientdlg.h | 6 +++--- src/main.cpp | 18 +++++++++++++++--- 5 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/client.cpp b/src/client.cpp index be686978bf..6557ef1156 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -942,7 +942,7 @@ void CClient::Init() bFraSiFactSafeSupported = true; #else bFraSiFactPrefSupported = ( Sound.Init ( iFraSizePreffered ) == iFraSizePreffered ); - bFraSiFactDefSupported = ( Sound.Init ( iFraSizeDefault ) == iFraSizeDefault ); + bFraSiFactDefSupported = ( Sound.Init ( iFraSizeDefault ) == iFraSizeDefault ); bFraSiFactSafeSupported = ( Sound.Init ( iFraSizeSafe ) == iFraSizeSafe ); #endif diff --git a/src/client.h b/src/client.h index e467623f52..6f7514fecd 100644 --- a/src/client.h +++ b/src/client.h @@ -121,13 +121,15 @@ class CClient : public QObject bool Connect ( QString strServerAddress, QString strServerName ); bool Disconnect(); - bool SoundIsRunning() const { return Sound.IsCallbackEntered(); } // For OnTimerCheckAudioDeviceOk only - bool IsConnected() { return Channel.IsConnected(); } + bool IsRunning() { return Sound.IsRunning(); } + bool IsCallbackEntered() const { return Sound.IsCallbackEntered(); } // For OnTimerCheckAudioDeviceOk only double GetLevelForMeterdBLeft() { return SignalLevelMeter.GetLevelForMeterdBLeftOrMono(); } double GetLevelForMeterdBRight() { return SignalLevelMeter.GetLevelForMeterdBRight(); } bool GetAndResetbJitterBufferOKFlag(); + + bool IsConnected() { return Channel.IsConnected(); } EGUIDesign GetGUIDesign() const { return eGUIDesign; } void SetGUIDesign ( const EGUIDesign eNGD ) { eGUIDesign = eNGD; } diff --git a/src/clientdlg.cpp b/src/clientdlg.cpp index 811e83b427..08c6e8656b 100644 --- a/src/clientdlg.cpp +++ b/src/clientdlg.cpp @@ -827,7 +827,7 @@ void CClientDlg::OnChatTextReceived ( QString strChatText ) // always when a new message arrives since this is annoying. ShowChatWindow ( ( strChatText.indexOf ( WELCOME_MESSAGE_PREFIX ) == 0 ) ); - UpdateSettingsAndChatButtons(); + UpdateDisplay(); } void CClientDlg::OnLicenceRequired ( ELicenceType eLicenceType ) @@ -982,7 +982,7 @@ void CClientDlg::ShowChatWindow ( const bool bForceRaise ) ChatDlg.activateWindow(); } - UpdateSettingsAndChatButtons(); + UpdateDisplay(); } void CClientDlg::ShowAnalyzerConsole() @@ -1132,7 +1132,7 @@ void CClientDlg::OnTimerCheckAudioDeviceOk() // timeout to check if a valid device is selected and if we do not have // fundamental settings errors (in which case the GUI would only show that // it is trying to connect the server which does not help to solve the problem (#129)) - if ( !pClient->SoundIsRunning() ) + if ( !pClient->IsCallbackEntered() ) { QMessageBox::warning ( this, APP_NAME, @@ -1220,7 +1220,7 @@ void CClientDlg::OnDisconnect() TimerDetectFeedback.stop(); bDetectFeedback = false; - UpdateSettingsAndChatButtons(); + UpdateDisplay(); // reset LEDs ledBuffers->Reset(); @@ -1238,7 +1238,7 @@ void CClientDlg::OnDisconnect() SetMixerBoardDeco ( RS_UNDEFINED, pClient->GetGUIDesign() ); } -void CClientDlg::UpdateSettingsAndChatButtons() +void CClientDlg::UpdateDisplay() { // update settings/chat buttons (do not fire signals since it is an update) if ( chbSettings->isChecked() && !ClientSettingsDlg.isVisible() ) diff --git a/src/clientdlg.h b/src/clientdlg.h index 12c65f7289..0e1166331c 100644 --- a/src/clientdlg.h +++ b/src/clientdlg.h @@ -92,8 +92,8 @@ class CClientDlg : public CBaseDlg, private Ui_CClientDlgBase void ShowChatWindow ( const bool bForceRaise = true ); void ShowAnalyzerConsole(); void UpdateAudioFaderSlider(); - void ManageDragNDrop ( QDropEvent* Event, const bool bCheckAccept ); void UpdateRevSelection(); + void ManageDragNDrop ( QDropEvent* Event, const bool bCheckAccept ); void SetPingTime ( const int iPingTime, const int iOverallDelayMs, const CMultiColorLED::ELightColor eOverallDelayLEDColor ); CClient* pClient; @@ -116,7 +116,7 @@ class CClientDlg : public CBaseDlg, private Ui_CClientDlgBase virtual void closeEvent ( QCloseEvent* Event ); virtual void dragEnterEvent ( QDragEnterEvent* Event ) { ManageDragNDrop ( Event, true ); } virtual void dropEvent ( QDropEvent* Event ) { ManageDragNDrop ( Event, false ); } - void UpdateSettingsAndChatButtons(); + void UpdateDisplay(); CClientSettingsDlg ClientSettingsDlg; CChatDlg ChatDlg; @@ -132,7 +132,7 @@ public slots: void OnTimerCheckAudioDeviceOk(); void OnTimerDetectFeedback(); - void OnTimerStatus() { UpdateSettingsAndChatButtons(); } + void OnTimerStatus() { UpdateDisplay(); } void OnTimerPing(); void OnPingTimeResult ( int iPingTime ); diff --git a/src/main.cpp b/src/main.cpp index 5dc16ed57e..d8386e6b55 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -919,7 +919,13 @@ int main ( int argc, char** argv ) { // Client: // actual client object - CClient Client ( iPortNumber, iQosNumber, strMIDISetup, bNoAutoJackConnect, strClientName, bEnableIPv6, bMuteMeInPersonalMix ); + CClient Client ( iPortNumber, + iQosNumber, + strMIDISetup, + bNoAutoJackConnect, + strClientName, + bEnableIPv6, + bMuteMeInPersonalMix ); // load settings from init-file (command line options override) CClientSettings Settings ( &Client, strIniFileName ); @@ -943,8 +949,14 @@ int main ( int argc, char** argv ) } // GUI object - CClientDlg - ClientDlg ( &Client, &Settings, strMIDISetup, bShowComplRegConnList, bShowAnalyzerConsole, bMuteStream, bEnableIPv6, nullptr ); + CClientDlg ClientDlg ( &Client, + &Settings, + strMIDISetup, + bShowComplRegConnList, + bShowAnalyzerConsole, + bMuteStream, + bEnableIPv6, + nullptr ); // show dialog ClientDlg.show(); From 535f781eece9a2a20598dcdf40df6a44d1c1148f Mon Sep 17 00:00:00 2001 From: ann0see <20726856+ann0see@users.noreply.github.com> Date: Sun, 8 Sep 2024 17:53:07 +0200 Subject: [PATCH 3/7] Refactor Connect() and Disconnect() into two methods --- src/client.cpp | 127 ++++++++++++++++++++++++++++++------------------- src/client.h | 5 +- 2 files changed, 82 insertions(+), 50 deletions(-) diff --git a/src/client.cpp b/src/client.cpp index 6557ef1156..cdbb6ec105 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -466,6 +466,26 @@ void CClient::StartDelayTimer() } } +bool CClient::SetServerAddr ( QString strNAddr ) +{ + CHostAddress HostAddress; +#ifdef CLIENT_NO_SRV_CONNECT + if ( NetworkUtil().ParseNetworkAddress ( strNAddr, HostAddress, bEnableIPv6 ) ) +#else + if ( NetworkUtil().ParseNetworkAddressWithSrvDiscovery ( strNAddr, HostAddress, bEnableIPv6 ) ) +#endif + { + // apply address to the channel + Channel.SetAddress ( HostAddress ); + + return true; + } + else + { + return false; // invalid address + } +} + bool CClient::GetAndResetbJitterBufferOKFlag() { // get the socket buffer put status flag and reset it @@ -845,26 +865,69 @@ void CClient::OnClientIDReceived ( int iChanID ) emit ClientIDReceived ( iChanID ); } -bool CClient::Connect ( QString strServerAddress, QString strServerName ) +void CClient::Start() { - if ( !Channel.IsEnabled() ) + // init object + Init(); + + // enable channel + Channel.SetEnable ( true ); + + // start audio interface + Sound.Start(); +} + +void CClient::Stop() +{ + // start disconnection + // Channel.Disconnect() should automatically disable Channel as soon as disconnected. + // Note that this only works if sound is active! + Channel.Disconnect(); + + QTime DieTime = QTime::currentTime().addMSecs ( 500 ); + while ( ( QTime::currentTime() < DieTime ) && Channel.IsEnabled() ) { - CHostAddress HostAddress; + // exclude user input events because if we use AllEvents, it happens + // that if the user initiates a connection and disconnection quickly + // (e.g. quickly pressing enter five times), the software can get into + // an unknown state + QCoreApplication::processEvents ( QEventLoop::ExcludeUserInputEvents, 100 ); + } - if ( NetworkUtil().ParseNetworkAddress ( strServerAddress, HostAddress, bEnableIPv6 ) ) - { - // init object - Init(); - // apply address to the channel - Channel.SetAddress ( HostAddress ); + // Now stop the audio interface + Sound.Stop(); - // enable channel - Channel.SetEnable ( true ); + // in case we timed out, log warning and make sure Channel is disabled + if ( Channel.IsEnabled() ) + { + //### TODO: BEGIN ###// + // Add error logging + //### TODO: END ###// - // start audio interface - Sound.Start(); + Channel.SetEnable ( false ); + } + + // Send disconnect message to server (Since we disable our protocol + // receive mechanism with the next command, we do not evaluate any + // respond from the server, therefore we just hope that the message + // gets its way to the server, if not, the old behaviour time-out + // disconnects the connection anyway). + ConnLessProtocol.CreateCLDisconnection ( Channel.GetAddress() ); + + // reset current signal level and LEDs + bJitterBufferOK = true; + SignalLevelMeter.Reset(); +} + +bool CClient::Connect ( QString strServerAddress, QString strServerName ) +{ + if ( !Channel.IsEnabled() ) + { + // Set server address and connect if valid address was supplied + if ( SetServerAddr ( strServerAddress ) ) { + + Start(); - // Notify ClientDlg emit Connecting ( strServerName ); return true; @@ -878,41 +941,7 @@ bool CClient::Disconnect() { if ( Channel.IsEnabled() ) { - // start disconnection - Channel.Disconnect(); - - // Channel.Disconnect() should automatically disable Channel as soon as disconnected. - // Note that this only works if Sound is Active ! - - QTime DieTime = QTime::currentTime().addMSecs ( 500 ); - while ( ( QTime::currentTime() < DieTime ) && Channel.IsEnabled() ) - { - // exclude user input events because if we use AllEvents, it happens - // that if the user initiates a connection and disconnection quickly - // (e.g. quickly pressing enter five times), the software can get into - // an unknown state - QCoreApplication::processEvents ( QEventLoop::ExcludeUserInputEvents, 100 ); - } - - // Now stop the audio interface - Sound.Stop(); - - // in case we timed out, log warning and make sure Channel is disabled - if ( Channel.IsEnabled() ) - { - Channel.SetEnable ( false ); - } - - // Send disconnect message to server (Since we disable our protocol - // receive mechanism with the next command, we do not evaluate any - // respond from the server, therefore we just hope that the message - // gets its way to the server, if not, the old behaviour time-out - // disconnects the connection anyway). - ConnLessProtocol.CreateCLDisconnection ( Channel.GetAddress() ); - - // reset current signal level and LEDs - bJitterBufferOK = true; - SignalLevelMeter.Reset(); + Stop(); emit Disconnected(); diff --git a/src/client.h b/src/client.h index 6f7514fecd..7c1fd81b7f 100644 --- a/src/client.h +++ b/src/client.h @@ -118,17 +118,20 @@ class CClient : public QObject virtual ~CClient(); + void Start(); + void Stop(); bool Connect ( QString strServerAddress, QString strServerName ); bool Disconnect(); bool IsRunning() { return Sound.IsRunning(); } bool IsCallbackEntered() const { return Sound.IsCallbackEntered(); } // For OnTimerCheckAudioDeviceOk only + bool SetServerAddr ( QString strNAddr ); double GetLevelForMeterdBLeft() { return SignalLevelMeter.GetLevelForMeterdBLeftOrMono(); } double GetLevelForMeterdBRight() { return SignalLevelMeter.GetLevelForMeterdBRight(); } bool GetAndResetbJitterBufferOKFlag(); - + bool IsConnected() { return Channel.IsConnected(); } EGUIDesign GetGUIDesign() const { return eGUIDesign; } From 21815c1a0708979fe0414c30e0294feaa7632be3 Mon Sep 17 00:00:00 2001 From: ann0see <20726856+ann0see@users.noreply.github.com> Date: Sun, 8 Sep 2024 19:25:41 +0200 Subject: [PATCH 4/7] Ensure client only changes --- src/channel.cpp | 33 +++++++++++++++++++-------------- src/channel.h | 2 +- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/channel.cpp b/src/channel.cpp index c2ff6ef5b2..d927213f45 100644 --- a/src/channel.cpp +++ b/src/channel.cpp @@ -508,23 +508,28 @@ void CChannel::Disconnect() // we only have to disconnect the channel if it is actually connected if ( IsConnected() ) { - // for a Client, block further audio data and disable the channel as soon as Disconnect() is called - // TODO: Add reasoning from #2550 - - bDisconnectAndDisable = !bIsServer; - // set time out counter to a small value > 0 so that the next time a // received audio block is queried, the disconnection is performed // (assuming that no audio packet is received in the meantime) iConTimeOut = 1; // a small number > 0 } - else if ( !bIsServer ) + + if ( !bIsServer ) { - // For clients (?) set defaults + if ( IsConnected() ) + { + // for a Client, block further audio data and disable the channel as soon as Disconnect() is called + // TODO: Add reasoning from #2550 + bDisconnectAndDisable = true; + } + else + { + // For disconnected clients set defaults - bDisconnectAndDisable = false; - bIsEnabled = false; - iConTimeOut = 0; + bDisconnectAndDisable = false; + bIsEnabled = false; + iConTimeOut = 0; + } } } @@ -547,9 +552,9 @@ EPutDataStat CChannel::PutAudioData ( const CVector& vecbyData, const i EPutDataStat eRet = PS_GEN_ERROR; // Only process audio data if: - // - for client only: the packet comes from the server we want to talk to + // - for client only: the packet comes from the server we want to talk to and we aren't disconnecting // - the channel is enabled - if ( ( bIsServer || ( GetAddress() == RecHostAddr ) ) && IsEnabled() && !bDisconnectAndDisable ) + if ( ( bIsServer || ( !bIsServer && GetAddress() == RecHostAddr && !bDisconnectAndDisable ) ) && IsEnabled() ) { MutexSocketBuf.lock(); { @@ -637,7 +642,7 @@ EGetDataStat CChannel::GetData ( CVector& vecbyData, const int iNumByte eGetStatus = GS_CHAN_NOW_DISCONNECTED; iConTimeOut = 0; // make sure we do not have negative values - if ( bDisconnectAndDisable ) + if ( bDisconnectAndDisable && !bIsServer ) { bDisconnectAndDisable = false; bIsEnabled = false; @@ -664,7 +669,7 @@ EGetDataStat CChannel::GetData ( CVector& vecbyData, const int iNumByte // channel is disconnected eGetStatus = GS_CHAN_NOT_CONNECTED; - if ( bDisconnectAndDisable ) + if ( bDisconnectAndDisable && !bIsServer ) { bDisconnectAndDisable = false; bIsEnabled = false; diff --git a/src/channel.h b/src/channel.h index 360b2aba1c..2d3a9fda5f 100644 --- a/src/channel.h +++ b/src/channel.h @@ -76,7 +76,7 @@ class CChannel : public QObject void PrepAndSendPacket ( CHighPrioSocket* pSocket, const CVector& vecbyNPacket, const int iNPacketLen ); - void ResetTimeOutCounter() { iConTimeOut = bDisconnectAndDisable ? 1 : iConTimeOutStartVal; } + void ResetTimeOutCounter() { iConTimeOut = (bDisconnectAndDisable && !bIsServer) ? 1 : iConTimeOutStartVal; } bool IsConnected() const { return iConTimeOut > 0; } void Disconnect(); From d7b4b8be532c876b6e7ddad2aea7057911a44232 Mon Sep 17 00:00:00 2001 From: ann0see <20726856+ann0see@users.noreply.github.com> Date: Fri, 13 Sep 2024 21:06:49 +0200 Subject: [PATCH 5/7] Revert renaming of strMixerBoardLabel --- src/clientdlg.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/clientdlg.cpp b/src/clientdlg.cpp index 08c6e8656b..abb5152514 100644 --- a/src/clientdlg.cpp +++ b/src/clientdlg.cpp @@ -1167,7 +1167,7 @@ void CClientDlg::OnCLPingTimeWithNumClientsReceived ( CHostAddress InetAddr, int ConnectDlg.SetPingTimeAndNumClientsResult ( InetAddr, iPingTime, iNumClients ); } -void CClientDlg::OnConnect ( QString strServerName ) +void CClientDlg::OnConnect ( QString strMixerBoardLabel ) { // hide label connect to server @@ -1179,7 +1179,7 @@ void CClientDlg::OnConnect ( QString strServerName ) butConnect->setText ( tr ( "&Disconnect" ) ); // set server name in audio mixer group box title - MainMixerBoard->SetServerName ( strServerName ); + MainMixerBoard->SetServerName ( strMixerBoardLabel ); // start timer for level meter bar and ping time measurement TimerSigMet.start ( LEVELMETER_UPDATE_TIME_MS ); From 66edab5cab1f36860e9182fc267a4c86feda2f66 Mon Sep 17 00:00:00 2001 From: ann0see <20726856+ann0see@users.noreply.github.com> Date: Fri, 13 Sep 2024 21:31:36 +0200 Subject: [PATCH 6/7] Revert strError handling --- src/channel.cpp | 2 +- src/channel.h | 2 +- src/client.cpp | 23 +++++------------------ src/client.h | 2 +- src/clientdlg.cpp | 14 +++++++++++++- src/clientdlg.h | 2 +- 6 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/channel.cpp b/src/channel.cpp index d927213f45..04febb9e49 100644 --- a/src/channel.cpp +++ b/src/channel.cpp @@ -513,7 +513,7 @@ void CChannel::Disconnect() // (assuming that no audio packet is received in the meantime) iConTimeOut = 1; // a small number > 0 } - + if ( !bIsServer ) { if ( IsConnected() ) diff --git a/src/channel.h b/src/channel.h index 2d3a9fda5f..90bd95f244 100644 --- a/src/channel.h +++ b/src/channel.h @@ -76,7 +76,7 @@ class CChannel : public QObject void PrepAndSendPacket ( CHighPrioSocket* pSocket, const CVector& vecbyNPacket, const int iNPacketLen ); - void ResetTimeOutCounter() { iConTimeOut = (bDisconnectAndDisable && !bIsServer) ? 1 : iConTimeOutStartVal; } + void ResetTimeOutCounter() { iConTimeOut = ( bDisconnectAndDisable && !bIsServer ) ? 1 : iConTimeOutStartVal; } bool IsConnected() const { return iConTimeOut > 0; } void Disconnect(); diff --git a/src/client.cpp b/src/client.cpp index cdbb6ec105..6addfe5cbd 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -618,16 +618,12 @@ QString CClient::SetSndCrdDev ( const QString strNewDev ) Sound.Start(); } + // in case of an error inform the GUI about it if ( !strError.isEmpty() ) { - // due to error, disconnect - Disconnect(); + emit SoundDeviceChanged ( strError ); } - // in case of an error, this will inform the GUI about it - - emit SoundDeviceChanged(); - return strError; } @@ -754,18 +750,8 @@ void CClient::OnSndCrdReinitRequest ( int iSndCrdResetType ) } MutexDriverReinit.unlock(); - if ( !strError.isEmpty() ) - { -#ifndef HEADLESS - QMessageBox::critical ( 0, APP_NAME, strError, tr ( "Ok" ) ); -#else - qCritical() << qUtf8Printable ( strError ); - exit ( 1 ); -#endif - } - // inform GUI about the sound card device change - emit SoundDeviceChanged(); + emit SoundDeviceChanged ( strError ); } void CClient::OnHandledSignal ( int sigNum ) @@ -924,7 +910,8 @@ bool CClient::Connect ( QString strServerAddress, QString strServerName ) if ( !Channel.IsEnabled() ) { // Set server address and connect if valid address was supplied - if ( SetServerAddr ( strServerAddress ) ) { + if ( SetServerAddr ( strServerAddress ) ) + { Start(); diff --git a/src/client.h b/src/client.h index 7c1fd81b7f..38626cf2e7 100644 --- a/src/client.h +++ b/src/client.h @@ -431,7 +431,7 @@ protected slots: void Connecting ( QString strServerName ); void Disconnected(); - void SoundDeviceChanged(); + void SoundDeviceChanged ( QString strError ); void ControllerInFaderLevel ( int iChannelIdx, int iValue ); void ControllerInPanValue ( int iChannelIdx, int iValue ); void ControllerInFaderIsSolo ( int iChannelIdx, bool bIsSolo ); diff --git a/src/clientdlg.cpp b/src/clientdlg.cpp index abb5152514..d09984e478 100644 --- a/src/clientdlg.cpp +++ b/src/clientdlg.cpp @@ -1143,8 +1143,20 @@ void CClientDlg::OnTimerCheckAudioDeviceOk() void CClientDlg::OnTimerDetectFeedback() { bDetectFeedback = false; } -void CClientDlg::OnSoundDeviceChanged() +void CClientDlg::OnSoundDeviceChanged ( QString strError ) { + if ( !strError.isEmpty() ) + { + // the sound device setup has a problem, disconnect any active connection + if ( pClient->IsRunning() ) + { + pClient->Disconnect(); + } + + // show the error message of the device setup + QMessageBox::critical ( this, APP_NAME, strError, tr ( "Ok" ), nullptr ); + } + // if the check audio device timer is running, it must be restarted on a device change if ( TimerCheckAudioDeviceOk.isActive() ) { diff --git a/src/clientdlg.h b/src/clientdlg.h index 0e1166331c..593038eeb3 100644 --- a/src/clientdlg.h +++ b/src/clientdlg.h @@ -190,7 +190,7 @@ public slots: void OnConClientListMesReceived ( CVector vecChanInfo ); void OnChatTextReceived ( QString strChatText ); void OnLicenceRequired ( ELicenceType eLicenceType ); - void OnSoundDeviceChanged(); + void OnSoundDeviceChanged ( QString strError ); void OnChangeChanGain ( int iId, float fGain, bool bIsMyOwnFader ) { pClient->SetRemoteChanGain ( iId, fGain, bIsMyOwnFader ); } From 49402c299c2e9e4ec2b36d1efdf19d784d7074fe Mon Sep 17 00:00:00 2001 From: ann0see <20726856+ann0see@users.noreply.github.com> Date: Fri, 13 Sep 2024 21:40:41 +0200 Subject: [PATCH 7/7] Revert refactoring of UpdateDisplay() Factored out into https://github.com/jamulussoftware/jamulus/pull/3369 --- src/clientsettingsdlg.cpp | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/clientsettingsdlg.cpp b/src/clientsettingsdlg.cpp index 2a5b5522e9..58d51701a7 100644 --- a/src/clientsettingsdlg.cpp +++ b/src/clientsettingsdlg.cpp @@ -1066,24 +1066,22 @@ void CClientSettingsDlg::OnSndCrdBufferDelayButtonGroupClicked ( QAbstractButton void CClientSettingsDlg::UpdateUploadRate() { // update upstream rate information label - if ( pClient->IsConnected() ) - { - lblUpstreamValue->setText ( QString().setNum ( pClient->GetUploadRateKbps() ) ); - lblUpstreamUnit->setText ( "kbps" ); - } - else - { - lblUpstreamValue->setText ( "---" ); - lblUpstreamUnit->setText ( "" ); - } + lblUpstreamValue->setText ( QString().setNum ( pClient->GetUploadRateKbps() ) ); + lblUpstreamUnit->setText ( "kbps" ); } void CClientSettingsDlg::UpdateDisplay() { - // update slider controls (settings might have been changed) and upstream rate information label + // update slider controls (settings might have been changed) UpdateJitterBufferFrame(); UpdateSoundCardFrame(); - UpdateUploadRate(); + + if ( !pClient->IsRunning() ) + { + // clear text labels with client parameters + lblUpstreamValue->setText ( "---" ); + lblUpstreamUnit->setText ( "" ); + } } void CClientSettingsDlg::UpdateDirectoryComboBox()