66#include < vector>
77
88#include " control/controlproxy.h"
9+ #include " defs_urls.h"
910#include " engine/enginebuffer.h"
1011#include " engine/enginemixer.h"
1112#include " mixer/playermanager.h"
1213#include " moc_dlgprefsound.cpp"
1314#include " preferences/dialog/dlgprefsounditem.h"
15+ #include " soundio/sounddevice.h"
1416#include " soundio/soundmanager.h"
17+ #include " soundio/soundmanagerutil.h"
1518#include " util/rlimit.h"
1619#include " util/scopedoverridecursor.h"
1720
@@ -94,6 +97,21 @@ DlgPrefSound::DlgPrefSound(QWidget* pParent,
9497 this ,
9598 &DlgPrefSound::refreshDevices);
9699
100+ connect (m_pSoundManager.get (),
101+ &SoundManager::deviceAdded,
102+ this ,
103+ &DlgPrefSound::addDevice);
104+
105+ connect (m_pSoundManager.get (),
106+ &SoundManager::deviceRemoved,
107+ this ,
108+ &DlgPrefSound::removeDevice);
109+
110+ connect (m_pSoundManager.get (),
111+ &SoundManager::deviceChannelsUpdated,
112+ this ,
113+ &DlgPrefSound::updateDeviceChannels);
114+
97115 apiComboBox->clear ();
98116 apiComboBox->addItem (SoundManagerConfig::kEmptyComboBox ,
99117 SoundManagerConfig::kDefaultAPI );
@@ -108,16 +126,8 @@ DlgPrefSound::DlgPrefSound(QWidget* pParent,
108126 QStringLiteral (" (?)" ),
109127 MIXXX_MANUAL_SOUND_API_URL ));
110128
111- sampleRateComboBox->clear ();
112129 const auto sampleRates = m_pSoundManager->getSampleRates ();
113- for (const auto & sampleRate : sampleRates) {
114- if (sampleRate.isValid ()) {
115- // no ridiculous sample rate values. prohibiting zero means
116- // avoiding a potential div-by-0 error in ::updateLatencies
117- sampleRateComboBox->addItem (tr (" %1 Hz" ).arg (sampleRate.value ()),
118- QVariant::fromValue (sampleRate));
119- }
120- }
130+ updateSampleRates (sampleRates);
121131 connect (sampleRateComboBox,
122132 QOverload<int >::of (&QComboBox::currentIndexChanged),
123133 this ,
@@ -508,14 +518,23 @@ void DlgPrefSound::connectSoundItem(DlgPrefSoundItem* pItem) {
508518 connect (this , &DlgPrefSound::writePaths, pItem, &DlgPrefSoundItem::writePath);
509519 if (pItem->isInput ()) {
510520 connect (this , &DlgPrefSound::refreshInputDevices, pItem, &DlgPrefSoundItem::refreshDevices);
521+ connect (this , &DlgPrefSound::addInputDevice, pItem, &DlgPrefSoundItem::addDevice);
522+ connect (this , &DlgPrefSound::removeInputDevice, pItem, &DlgPrefSoundItem::removeDevice);
511523 } else {
512524 connect (this ,
513525 &DlgPrefSound::refreshOutputDevices,
514526 pItem,
515527 &DlgPrefSoundItem::refreshDevices);
528+ connect (this , &DlgPrefSound::addOutputDevice, pItem, &DlgPrefSoundItem::addDevice);
529+ connect (this , &DlgPrefSound::removeOutputDevice, pItem, &DlgPrefSoundItem::removeDevice);
516530 }
517531 connect (this , &DlgPrefSound::updatingAPI, pItem, &DlgPrefSoundItem::save);
518532 connect (this , &DlgPrefSound::updatedAPI, pItem, &DlgPrefSoundItem::reload);
533+ connect (this ,
534+ &DlgPrefSound::deviceChannelsUpdated,
535+ pItem,
536+ &DlgPrefSoundItem::updateDeviceChannels);
537+ connect (this , &DlgPrefSound::deviceRouteUpdated, pItem, &DlgPrefSoundItem::updateDeviceRoute);
519538}
520539
521540void DlgPrefSound::insertItem (DlgPrefSoundItem *pItem, QVBoxLayout *pLayout) {
@@ -797,6 +816,62 @@ void DlgPrefSound::refreshDevices() {
797816 emit refreshInputDevices (m_inputDevices);
798817}
799818
819+ void DlgPrefSound::addDevice (SoundDevicePointer pDevice) {
820+ const bool hasInputs = pDevice->getNumInputChannels ().isValid ();
821+ const bool hasOutputs = pDevice->getNumOutputChannels ().isValid ();
822+
823+ if (hasInputs) {
824+ m_inputDevices.append (pDevice);
825+ emit addInputDevice (pDevice);
826+ }
827+ if (hasOutputs) {
828+ m_outputDevices.append (pDevice);
829+ emit addOutputDevice (pDevice);
830+ }
831+ }
832+
833+ void DlgPrefSound::removeDevice (SoundDevicePointer pDevice) {
834+ const bool hasInputs = pDevice->getNumInputChannels ().isValid ();
835+ const bool hasOutputs = pDevice->getNumOutputChannels ().isValid ();
836+
837+ if (hasInputs && m_inputDevices.removeOne (pDevice)) {
838+ emit removeInputDevice (pDevice);
839+ }
840+
841+ if (hasOutputs && m_outputDevices.removeOne (pDevice)) {
842+ emit removeOutputDevice (pDevice);
843+ }
844+ }
845+
846+ void DlgPrefSound::updateDeviceChannels (SoundDevicePointer pDevice) {
847+ const bool hasInputs = pDevice->getNumInputChannels ().isValid ();
848+ const bool hasOutputs = pDevice->getNumOutputChannels ().isValid ();
849+ const bool hadInputs = m_inputDevices.contains (pDevice);
850+ const bool hadOutputs = m_outputDevices.contains (pDevice);
851+ const bool listsModified = (hasInputs ^ hadInputs) || (hasOutputs ^ hadOutputs);
852+
853+ if (!listsModified) {
854+ emit deviceChannelsUpdated (pDevice);
855+ return ;
856+ }
857+
858+ if (hadInputs && !hasInputs) {
859+ m_inputDevices.removeOne (pDevice);
860+ emit removeInputDevice (pDevice);
861+ } else if (!hadInputs && hasInputs) {
862+ m_inputDevices.append (pDevice);
863+ emit addInputDevice (pDevice);
864+ }
865+
866+ if (hadOutputs && !hasOutputs) {
867+ m_outputDevices.removeOne (pDevice);
868+ emit removeOutputDevice (pDevice);
869+ } else if (!hadOutputs && hasOutputs) {
870+ m_outputDevices.append (pDevice);
871+ emit addOutputDevice (pDevice);
872+ }
873+ }
874+
800875// / Called when any of the combo boxes in this dialog are changed. Enables the
801876// / apply button and marks that settings have been changed so that
802877// / DlgPrefSound::slotApply knows to apply them.
@@ -1099,3 +1174,15 @@ void DlgPrefSound::checkLatencyCompensation() {
10991174bool DlgPrefSound::okayToClose () const {
11001175 return m_configValid;
11011176}
1177+
1178+ void DlgPrefSound::updateSampleRates (const QList<mixxx::audio::SampleRate>& sampleRates) {
1179+ sampleRateComboBox->clear ();
1180+ for (const auto & sampleRate : sampleRates) {
1181+ if (sampleRate.isValid ()) {
1182+ // no ridiculous sample rate values. prohibiting zero means
1183+ // avoiding a potential div-by-0 error in ::updateLatencies
1184+ sampleRateComboBox->addItem (tr (" %1 Hz" ).arg (sampleRate.value ()),
1185+ QVariant::fromValue (sampleRate));
1186+ }
1187+ }
1188+ }
0 commit comments