Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions src/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -746,7 +746,14 @@ void CClient::SetAudioChannels ( const EAudChanConf eNAudChanConf )
}
}

QString CClient::SetSndCrdDev ( const QString strNewDev )
QString CClient::SetSndCrdDev ( const QString strNewDev ) { return ChangeSndCrdDev ( strNewDev, QString(), false ); }

QString CClient::SetSndCrdInOutDev ( const QString& strNewInDev, const QString& strNewOutDev )
{
return ChangeSndCrdDev ( strNewInDev, strNewOutDev, true );
}

QString CClient::ChangeSndCrdDev ( const QString& strNewDev, const QString& strNewOutDev, const bool bSeparateInOutDev )
{
QString strError = "";

Expand All @@ -762,7 +769,8 @@ QString CClient::SetSndCrdDev ( const QString strNewDev )
// on error condition. Catch it here as exceptions must not escape from a Qt slot.
try
{
strError = Sound.SetDev ( strNewDev );
// for a separate selection the first parameter is the input device name
strError = bSeparateInOutDev ? Sound.SetInOutDev ( strNewDev, strNewOutDev ) : Sound.SetDev ( strNewDev );

// init again because the sound card actual buffer size might
// be changed on new device
Expand Down
12 changes: 11 additions & 1 deletion src/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,14 @@ class CClient : public QObject
QString GetSndCrdDev() { return Sound.GetDev(); }
void OpenSndCrdDriverSetup() { Sound.OpenDriverSetup(); }

// separate input/output device selection (only supported by some sound APIs)
bool GetSndCrdInOutDevSelectionSeparate() { return Sound.IsInOutDevSelectionSeparate(); }
QStringList GetSndCrdInputDevNames() { return Sound.GetInputDevNames(); }
QStringList GetSndCrdOutputDevNames() { return Sound.GetOutputDevNames(); }
QString GetSndCrdInputDev() { return Sound.GetInputDev(); }
QString GetSndCrdOutputDev() { return Sound.GetOutputDev(); }
QString SetSndCrdInOutDev ( const QString& strNewInDev, const QString& strNewOutDev );

// sound card channel selection
int GetSndCrdNumInputChannels() { return Sound.GetNumInputChannels(); }
QString GetSndCrdInputChannelName ( const int iDiD ) { return Sound.GetInputChannelName ( iDiD ); }
Expand Down Expand Up @@ -363,7 +371,9 @@ class CClient : public QObject
void Start();
void Stop();

void Init();
void Init();
QString ChangeSndCrdDev ( const QString& strNewDev, const QString& strNewOutDev, const bool bSeparateInOutDev );

void ProcessSndCrdAudioData ( CVector<short>& vecsStereoSndCrd );
void ProcessAudioDataIntern ( CVector<short>& vecsStereoSndCrd );

Expand Down
98 changes: 80 additions & 18 deletions src/clientsettingsdlg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,18 +142,24 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, CClientSettings* pNSet

#if !defined( WITH_JACK )
// sound card device
lblSoundcardDevice->setWhatsThis ( "<b>" + tr ( "Audio Device" ) + ":</b> " +
tr ( "Under the Windows operating system the ASIO driver (sound card) can be "
"selected using %1. If the selected ASIO driver is not valid an error "
"message is shown and the previous valid driver is selected. "
"Under macOS the input and output hardware can be selected." )
.arg ( APP_NAME ) +
"<br>" +
tr ( "If the driver is selected during an active connection, the connection "
"is stopped, the driver is changed and the connection is started again "
"automatically." ) );
const QString strAudioDevice = "<b>" + tr ( "Audio Device" ) + ":</b> " +
tr ( "Under the Windows operating system the ASIO driver (sound card) can be "
"selected using %1. If the selected ASIO driver is not valid an error "
"message is shown and the previous valid driver is selected. "
"Under macOS the input and output hardware can be selected." )
.arg ( APP_NAME ) +
"<br>" +
tr ( "If the driver is selected during an active connection, the connection "
"is stopped, the driver is changed and the connection is started again "
"automatically." );

lblSoundcardDevice->setWhatsThis ( strAudioDevice );
lblInputDevice->setWhatsThis ( strAudioDevice );
lblOutputDevice->setWhatsThis ( strAudioDevice );

cbxSoundcard->setAccessibleName ( tr ( "Sound card device selector combo box" ) );
cbxInputDevice->setAccessibleName ( tr ( "Audio input device selector combo box" ) );
cbxOutputDevice->setAccessibleName ( tr ( "Audio output device selector combo box" ) );

# if defined( _WIN32 )
// set Windows specific tool tip
Expand Down Expand Up @@ -735,6 +741,16 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, CClientSettings* pNSet
this,
&CClientSettingsDlg::OnSoundcardActivated );

QObject::connect ( cbxInputDevice,
static_cast<void ( QComboBox::* ) ( int )> ( &QComboBox::activated ),
this,
&CClientSettingsDlg::OnInputDeviceActivated );

QObject::connect ( cbxOutputDevice,
static_cast<void ( QComboBox::* ) ( int )> ( &QComboBox::activated ),
this,
&CClientSettingsDlg::OnOutputDeviceActivated );

QObject::connect ( cbxLInChan,
static_cast<void ( QComboBox::* ) ( int )> ( &QComboBox::activated ),
this,
Expand Down Expand Up @@ -1126,18 +1142,44 @@ void CClientSettingsDlg::UpdateSoundCardFrame()
}
}

void CClientSettingsDlg::UpdateSoundDeviceChannelSelectionFrame()
void CClientSettingsDlg::UpdateSoundDeviceSelection()
{
// update combo box containing all available sound cards in the system
QStringList slSndCrdDevNames = pClient->GetSndCrdDevNames();
cbxSoundcard->clear();

foreach ( QString strDevName, slSndCrdDevNames )
// Sound APIs which handle the input and the output device independently of
// each other (i.e. CoreAudio on macOS) get one combo box per direction. All
// other APIs get the single combo box containing the available devices.
const bool bSeparateInOutDev = pClient->GetSndCrdInOutDevSelectionSeparate();

lblSoundcardDevice->setVisible ( !bSeparateInOutDev );
cbxSoundcard->setVisible ( !bSeparateInOutDev );
lblInputDevice->setVisible ( bSeparateInOutDev );
cbxInputDevice->setVisible ( bSeparateInOutDev );
lblOutputDevice->setVisible ( bSeparateInOutDev );
cbxOutputDevice->setVisible ( bSeparateInOutDev );

if ( bSeparateInOutDev )
{
// update combo boxes containing the available input and output devices
cbxInputDevice->clear();
cbxInputDevice->addItems ( pClient->GetSndCrdInputDevNames() );
cbxInputDevice->setCurrentText ( pClient->GetSndCrdInputDev() );

cbxOutputDevice->clear();
cbxOutputDevice->addItems ( pClient->GetSndCrdOutputDevNames() );
cbxOutputDevice->setCurrentText ( pClient->GetSndCrdOutputDev() );
}
else
{
cbxSoundcard->addItem ( strDevName );
// update combo box containing all available sound cards in the system
cbxSoundcard->clear();
cbxSoundcard->addItems ( pClient->GetSndCrdDevNames() );
cbxSoundcard->setCurrentText ( pClient->GetSndCrdDev() );
}
}

cbxSoundcard->setCurrentText ( pClient->GetSndCrdDev() );
void CClientSettingsDlg::UpdateSoundDeviceChannelSelectionFrame()
{
// update the sound device selection combo box(es)
UpdateSoundDeviceSelection();

// update input/output channel selection
#if defined( _WIN32 ) || defined( __APPLE__ ) || defined( __MACOSX )
Expand Down Expand Up @@ -1222,6 +1264,26 @@ void CClientSettingsDlg::OnSoundcardActivated ( int iSndDevIdx )
UpdateDisplay();
}

void CClientSettingsDlg::OnInputDeviceActivated ( int iSndDevIdx )
{
// The device of the other direction is taken from its combo box and not from
// the sound API: if no device could be initialized at all, the sound API has
// no current device and we would compose an unusable device name from it.
pClient->SetSndCrdInOutDev ( cbxInputDevice->itemText ( iSndDevIdx ), cbxOutputDevice->currentText() );

UpdateSoundDeviceChannelSelectionFrame();
UpdateDisplay();
}

void CClientSettingsDlg::OnOutputDeviceActivated ( int iSndDevIdx )
{
// the device of the other direction is taken from its combo box, see above
pClient->SetSndCrdInOutDev ( cbxInputDevice->currentText(), cbxOutputDevice->itemText ( iSndDevIdx ) );

UpdateSoundDeviceChannelSelectionFrame();
UpdateDisplay();
}

void CClientSettingsDlg::OnLInChanActivated ( int iChanIdx )
{
pClient->SetSndCrdLeftInputChannel ( iChanIdx );
Expand Down
3 changes: 3 additions & 0 deletions src/clientsettingsdlg.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class CClientSettingsDlg : public CBaseDlg, private Ui_CClientSettingsDlgBase

void UpdateUploadRate();
void UpdateDisplay();
void UpdateSoundDeviceSelection();
void UpdateSoundDeviceChannelSelectionFrame();

void SetEnableFeedbackDetection ( bool enable );
Expand Down Expand Up @@ -111,6 +112,8 @@ public slots:
void OnInputBoostChanged();
void OnSndCrdBufferDelayButtonGroupClicked ( QAbstractButton* button );
void OnSoundcardActivated ( int iSndDevIdx );
void OnInputDeviceActivated ( int iSndDevIdx );
void OnOutputDeviceActivated ( int iSndDevIdx );
void OnLInChanActivated ( int iChanIdx );
void OnRInChanActivated ( int iChanIdx );
void OnLOutChanActivated ( int iChanIdx );
Expand Down
54 changes: 54 additions & 0 deletions src/clientsettingsdlgbase.ui
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,58 @@
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblInputDevice">
<property name="text">
<string>Input Device</string>
</property>
<property name="buddy">
<cstring>cbxInputDevice</cstring>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cbxInputDevice">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblOutputDevice">
<property name="text">
<string>Output Device</string>
</property>
<property name="buddy">
<cstring>cbxOutputDevice</cstring>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cbxOutputDevice">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
Expand Down Expand Up @@ -2267,6 +2319,8 @@
<tabstop>spnMixerRows</tabstop>
<tabstop>chbAudioAlerts</tabstop>
<tabstop>cbxSoundcard</tabstop>
<tabstop>cbxInputDevice</tabstop>
<tabstop>cbxOutputDevice</tabstop>
<tabstop>butDriverSetup</tabstop>
<tabstop>cbxLInChan</tabstop>
<tabstop>cbxRInChan</tabstop>
Expand Down
7 changes: 5 additions & 2 deletions src/global.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,11 @@ LED bar: lbr
// maximum number of fader groups (must be consistent to audiomixerboard implementation)
#define MAX_NUM_FADER_GROUPS 8

// maximum number of recognized sound cards installed in the system
#define MAX_NUMBER_SOUND_CARDS 129 // e.g. 16 inputs, 8 outputs + default entry (MacOS)
// maximum number of recognized sound cards installed in the system, i.e. the
// number of available ASIO drivers on Windows. On macOS the input and the
// output devices are enumerated separately, so the limit applies to each
// direction on its own (including the system default entry)
#define MAX_NUMBER_SOUND_CARDS 129

// define the maximum number of audio channel for input/output we can store
// channel infos for (and therefore this is the maximum number of entries in
Expand Down
Loading
Loading