diff --git a/mac/sound.h b/mac/sound.h index 427eaf06..cb0c1a3a 100755 --- a/mac/sound.h +++ b/mac/sound.h @@ -54,8 +54,8 @@ public: protected: void OpenCoreAudio(); void CloseCoreAudio(); - UInt32 SetBufferSize ( AudioDeviceID& audioDeviceID, const bool bIsInput, - UInt32 iPrefBufferSize ); + UInt32 SetBufferSize ( AudioDeviceID& audioDeviceID, const bool bIsInput, + UInt32 iPrefBufferSize ); // callbacks static OSStatus processInput ( void* inRefCon,AudioUnitRenderActionFlags* ioActionFlags, diff --git a/src/client.cpp b/src/client.cpp index 20ca7ea8..d81f0947 100755 --- a/src/client.cpp +++ b/src/client.cpp @@ -255,6 +255,86 @@ QString CClient::SetSndCrdDev ( const int iNewDev ) return strReturn; } +void CClient::SetSndCrdLeftInputChannel ( const int iNewChan ) +{ + // if client was running then first + // stop it and restart again after new initialization + const bool bWasRunning = Sound.IsRunning(); + if ( bWasRunning ) + { + Sound.Stop(); + } + + Sound.SetLeftInputChannel ( iNewChan ); + Init(); + + if ( bWasRunning ) + { + // restart client + Sound.Start(); + } +} + +void CClient::SetSndCrdRightInputChannel ( const int iNewChan ) +{ + // if client was running then first + // stop it and restart again after new initialization + const bool bWasRunning = Sound.IsRunning(); + if ( bWasRunning ) + { + Sound.Stop(); + } + + Sound.SetRightInputChannel ( iNewChan ); + Init(); + + if ( bWasRunning ) + { + // restart client + Sound.Start(); + } +} + +void CClient::SetSndCrdLeftOutputChannel ( const int iNewChan ) +{ + // if client was running then first + // stop it and restart again after new initialization + const bool bWasRunning = Sound.IsRunning(); + if ( bWasRunning ) + { + Sound.Stop(); + } + + Sound.SetLeftOutputChannel ( iNewChan ); + Init(); + + if ( bWasRunning ) + { + // restart client + Sound.Start(); + } +} + +void CClient::SetSndCrdRightOutputChannel ( const int iNewChan ) +{ + // if client was running then first + // stop it and restart again after new initialization + const bool bWasRunning = Sound.IsRunning(); + if ( bWasRunning ) + { + Sound.Stop(); + } + + Sound.SetRightOutputChannel ( iNewChan ); + Init(); + + if ( bWasRunning ) + { + // restart client + Sound.Start(); + } +} + void CClient::OnSndCrdReinitRequest() { // if client was running then first diff --git a/src/client.h b/src/client.h index 7d958ee4..1551d6d5 100755 --- a/src/client.h +++ b/src/client.h @@ -132,6 +132,7 @@ public: int GetUploadRateKbps() { return Channel.GetUploadRateKbps(); } + // sound card device selection int GetSndCrdNumDev() { return Sound.GetNumDev(); } QString GetSndCrdDeviceName ( const int iDiD ) { return Sound.GetDeviceName ( iDiD ); } @@ -140,6 +141,21 @@ public: int GetSndCrdDev() { return Sound.GetDev(); } void OpenSndCrdDriverSetup() { Sound.OpenDriverSetup(); } + // sound card channel selection + int GetSndCrdNumInputChannels() { return Sound.GetNumInputChannels(); } + QString GetSndCrdInputChannelName ( const int iDiD ) { return Sound.GetInputChannelName ( iDiD ); } + void SetSndCrdLeftInputChannel ( const int iNewChan ); + void SetSndCrdRightInputChannel ( const int iNewChan ); + int GetSndCrdLeftInputChannel() { return Sound.GetLeftInputChannel(); } + int GetSndCrdRightInputChannel() { return Sound.GetRightInputChannel(); } + + int GetSndCrdNumOutputChannels() { return Sound.GetNumOutputChannels(); } + QString GetSndCrdOutputChannelName ( const int iDiD ) { return Sound.GetOutputChannelName ( iDiD ); } + void SetSndCrdLeftOutputChannel ( const int iNewChan ); + void SetSndCrdRightOutputChannel ( const int iNewChan ); + int GetSndCrdLeftOutputChannel() { return Sound.GetLeftOutputChannel(); } + int GetSndCrdRightOutputChannel() { return Sound.GetRightOutputChannel(); } + void SetSndCrdPrefFrameSizeFactor ( const int iNewFactor ); int GetSndCrdPrefFrameSizeFactor() { return iSndCrdPrefFrameSizeFactor; } diff --git a/src/clientsettingsdlg.cpp b/src/clientsettingsdlg.cpp index 6001c3f7..f8f670f0 100755 --- a/src/clientsettingsdlg.cpp +++ b/src/clientsettingsdlg.cpp @@ -224,6 +224,9 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent, } cbSoundcard->setCurrentIndex ( pClient->GetSndCrdDev() ); + // init sound card channel selection frame + UpdateSoundChannelSelectionFrame(); + // "OpenChatOnNewMessage" check box if ( pClient->GetOpenChatOnNewMessage() ) { @@ -309,6 +312,18 @@ cbGUIDesignFancy->setVisible ( false ); 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() ) ); @@ -386,6 +401,54 @@ void CClientSettingsDlg::UpdateSoundCardFrame() 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::showEvent ( QShowEvent* ) { // only activate ping timer if window is actually shown @@ -432,9 +495,34 @@ void CClientSettingsDlg::OnSoundCrdSelection ( int iSndDevIdx ) // 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 ); diff --git a/src/clientsettingsdlg.h b/src/clientsettingsdlg.h index 31708f3a..6ecbef15 100755 --- a/src/clientsettingsdlg.h +++ b/src/clientsettingsdlg.h @@ -68,6 +68,7 @@ public: protected: void UpdateJitterBufferFrame(); void UpdateSoundCardFrame(); + void UpdateSoundChannelSelectionFrame(); QString GenSndCrdBufferDelayString ( const int iFrameSize, const QString strAddText = "" ); @@ -92,6 +93,10 @@ protected: void OnSndCrdBufferDelayButtonGroupClicked ( QAbstractButton* button ); void OnPingTimeResult ( int iPingTime ); void OnSoundCrdSelection ( int iSndDevIdx ); + void OnSndCrdLeftInChannelSelection ( int iChanIdx ); + void OnSndCrdRightInChannelSelection ( int iChanIdx ); + void OnSndCrdLeftOutChannelSelection ( int iChanIdx ); + void OnSndCrdRightOutChannelSelection ( int iChanIdx ); void OnDriverSetupBut(); signals: diff --git a/src/soundbase.h b/src/soundbase.h index 1b323eff..a7d35b98 100755 --- a/src/soundbase.h +++ b/src/soundbase.h @@ -47,15 +47,29 @@ public: virtual void Start(); virtual void Stop(); - // dummy implementation in base class + // dummy implementations in base class virtual int GetNumDev() { return 1; } virtual QString GetDeviceName ( const int ) { return "Default"; } virtual QString SetDev ( const int ) { return ""; } virtual int GetDev() { return 0; } - bool IsRunning() const { return bRun; } + virtual int GetNumInputChannels() { return 2; } + virtual QString GetInputChannelName ( const int ) { return "Default"; } + virtual void SetLeftInputChannel ( const int ) {} + virtual void SetRightInputChannel ( const int ) {} + virtual int GetLeftInputChannel() { return 0; } + virtual int GetRightInputChannel() { return 1; } - virtual void OpenDriverSetup() {} + virtual int GetNumOutputChannels() { return 2; } + virtual QString GetOutputChannelName ( const int ) { return "Default"; } + virtual void SetLeftOutputChannel ( const int ) {} + virtual void SetRightOutputChannel ( const int ) {} + virtual int GetLeftOutputChannel() { return 0; } + virtual int GetRightOutputChannel() { return 1; } + + virtual void OpenDriverSetup() {} + + bool IsRunning() const { return bRun; } // TODO this should be protected but since it is used // in a callback function it has to be public -> better solution diff --git a/windows/sound.h b/windows/sound.h index 63f43601..bda43781 100755 --- a/windows/sound.h +++ b/windows/sound.h @@ -70,19 +70,19 @@ public: virtual int GetDev() { return lCurDev; } // channel selection - int GetNumInputChannels() { return static_cast ( lNumInChan ); } - QString GetInputChannelName ( const int iDiD ) { return channelInfosInput[iDiD].name; } - void SetLeftInputChannel ( const int iNewChan ); - void SetRightInputChannel ( const int iNewChan ); - int GetLeftInputChannel() { return vSelectedInputChannels[0]; } - int GetRightInputChannel() { return vSelectedInputChannels[1]; } + virtual int GetNumInputChannels() { return static_cast ( lNumInChan ); } + virtual QString GetInputChannelName ( const int iDiD ) { return channelInfosInput[iDiD].name; } + virtual void SetLeftInputChannel ( const int iNewChan ); + virtual void SetRightInputChannel ( const int iNewChan ); + virtual int GetLeftInputChannel() { return vSelectedInputChannels[0]; } + virtual int GetRightInputChannel() { return vSelectedInputChannels[1]; } - int GetNumOutputChannels() { return static_cast ( lNumOutChan ); } - QString GetOutputChannelName ( const int iDiD ) { return channelInfosOutput[iDiD].name; } - void SetLeftOutputChannel ( const int iNewChan ); - void SetRightOutputChannel ( const int iNewChan ); - int GetLeftOutputChannel() { return vSelectedOutputChannels[0]; } - int GetRightOutputChannel() { return vSelectedOutputChannels[1]; } + virtual int GetNumOutputChannels() { return static_cast ( lNumOutChan ); } + virtual QString GetOutputChannelName ( const int iDiD ) { return channelInfosOutput[iDiD].name; } + virtual void SetLeftOutputChannel ( const int iNewChan ); + virtual void SetRightOutputChannel ( const int iNewChan ); + virtual int GetLeftOutputChannel() { return vSelectedOutputChannels[0]; } + virtual int GetRightOutputChannel() { return vSelectedOutputChannels[1]; } protected: QVector LoadAndInitializeFirstValidDriver();