From 2e676713afc034fe221babdc507cfc99975c2bde Mon Sep 17 00:00:00 2001 From: Hartmnt Date: Tue, 15 Oct 2024 14:01:49 +0000 Subject: [PATCH] FIX(client): Fix AudioWizard echo cancellation checkbox The echo cancellation checkbox had two separate, but similar problems: 1) It would never load in a checked state when you open up the AudioWizard 2) It would also never load the correct checked state representing the user settings when switching AudioInput or AudioOutput systems. The first problem can be traced back to commit 010437556dc81b4ed2e16baba65447c32fda61cd where the state of qcbEcho depends on the selected element of the AudioOutput dropdown menu, before it has been filled. The second problem probably goes back to 2991d2093a0fa0d9060afbe0004af9d3383f48e0 where the enabled state of the qcbEcho checkbox was changed on changing audio systems, but the checked state was not reloaded. This commit refactors the code (swaps initializing input and output) and adds a shared method to update the qcbEcho checkbox appropriately. Fixes #6544 --- src/mumble/AudioWizard.cpp | 54 ++++++++++++++++++++------------------ src/mumble/AudioWizard.h | 2 ++ 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/src/mumble/AudioWizard.cpp b/src/mumble/AudioWizard.cpp index e8d9d9f0a2b..b8b56c576c6 100644 --- a/src/mumble/AudioWizard.cpp +++ b/src/mumble/AudioWizard.cpp @@ -44,26 +44,8 @@ AudioWizard::AudioWizard(QWidget *p) : QWizard(p) { qcbUsage->setChecked(Global::get().s.bUsage); // Device - if (AudioInputRegistrar::qmNew) { - foreach (AudioInputRegistrar *air, *AudioInputRegistrar::qmNew) { - qcbInput->addItem(air->name); - if (air->name == AudioInputRegistrar::current) { - qcbInput->setCurrentIndex(qcbInput->count() - 1); - EchoCancelOptionID echoCancelOptionId = firstUsableEchoCancellation(air, qcbOutput->currentText()); - if (echoCancelOptionId != EchoCancelOptionID::DISABLED) { - qcbEcho->setEnabled(true); - qcbEcho->setChecked(Global::get().s.echoOption != EchoCancelOptionID::DISABLED); - } - } - QList< audioDevice > ql = air->getDeviceChoices(); - } - } - if (qcbInput->count() < 2) { - qcbInput->setEnabled(false); - } - if (AudioOutputRegistrar::qmNew) { - foreach (AudioOutputRegistrar *aor, *AudioOutputRegistrar::qmNew) { + for (AudioOutputRegistrar *aor : *AudioOutputRegistrar::qmNew) { qcbOutput->addItem(aor->name); if (aor->name == AudioOutputRegistrar::current) { qcbOutput->setCurrentIndex(qcbOutput->count() - 1); @@ -73,11 +55,24 @@ AudioWizard::AudioWizard(QWidget *p) : QWizard(p) { QList< audioDevice > ql = aor->getDeviceChoices(); } } - if (qcbOutput->count() < 2) { qcbOutput->setEnabled(false); } + if (AudioInputRegistrar::qmNew) { + for (AudioInputRegistrar *air : *AudioInputRegistrar::qmNew) { + qcbInput->addItem(air->name); + if (air->name == AudioInputRegistrar::current) { + qcbInput->setCurrentIndex(qcbInput->count() - 1); + updateEchoCheckbox(air); + } + QList< audioDevice > ql = air->getDeviceChoices(); + } + } + if (qcbInput->count() < 2) { + qcbInput->setEnabled(false); + } + qcbHighContrast->setChecked(Global::get().s.bHighContrast); on_qcbHighContrast_clicked(Global::get().s.bHighContrast); #ifdef Q_OS_WIN @@ -243,8 +238,7 @@ void AudioWizard::on_qcbInputDevice_activated(int) { air->setDeviceChoice(qcbInputDevice->itemData(idx), Global::get().s); } - EchoCancelOptionID echoCancelOptionId = firstUsableEchoCancellation(air, qcbOutput->currentText()); - qcbEcho->setEnabled(echoCancelOptionId != EchoCancelOptionID::DISABLED); + updateEchoCheckbox(air); Global::get().ai = AudioInputPtr(air->create()); Global::get().ai->start(QThread::HighestPriority); @@ -284,9 +278,7 @@ void AudioWizard::on_qcbOutputDevice_activated(int) { bDelay = aor->usesOutputDelay(); } - AudioInputRegistrar *air = AudioInputRegistrar::qmNew->value(qcbInput->currentText()); - EchoCancelOptionID echoCancelOptionId = firstUsableEchoCancellation(air, qcbOutput->currentText()); - qcbEcho->setEnabled(echoCancelOptionId != EchoCancelOptionID::DISABLED); + updateEchoCheckbox(AudioInputRegistrar::qmNew->value(qcbInput->currentText())); Global::get().ao = AudioOutputPtr(aor->create()); Global::get().ao->start(QThread::HighPriority); @@ -767,6 +759,18 @@ void AudioWizard::on_qrbQualityCustom_clicked() { restartAudio(true); } +void AudioWizard::updateEchoCheckbox(AudioInputRegistrar *air) { + bool echoCancelPossible = + firstUsableEchoCancellation(air, qcbOutput->currentText()) != EchoCancelOptionID::DISABLED; + + qcbEcho->setEnabled(echoCancelPossible); + if (echoCancelPossible) { + qcbEcho->setChecked(Global::get().s.echoOption != EchoCancelOptionID::DISABLED); + } else { + qcbEcho->setChecked(false); + } +} + EchoCancelOptionID AudioWizard::firstUsableEchoCancellation(AudioInputRegistrar *air, const QString outputSys) { for (EchoCancelOptionID ecoid : air->echoOptions) { if (air->canEcho(ecoid, outputSys)) { diff --git a/src/mumble/AudioWizard.h b/src/mumble/AudioWizard.h index 52850cefc03..c0e3ef2cfb5 100644 --- a/src/mumble/AudioWizard.h +++ b/src/mumble/AudioWizard.h @@ -20,6 +20,8 @@ class AudioWizard : public QWizard, public Ui::AudioWizard { Q_OBJECT Q_DISABLE_COPY(AudioWizard) + void updateEchoCheckbox(AudioInputRegistrar *air); + /// Which echo cancellation is usable depends on the audio backend and the device combination. /// This function will iterate through the list of available echo cancellation in the audio backend and check with /// the backend whether this echo cancellation option works for current device combination.