Skip to content
Merged
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
9 changes: 9 additions & 0 deletions docs/audio-pipeline.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,15 @@ When at least one new device appears, AetherSDR shows a selection dialog with
the current input/output highlighted, newly detected devices marked, and system
defaults available as explicit choices.

The dialog includes a "Don't ask me again" checkbox. Checking it persists
`SuppressAudioDeviceNotifications=True` in `AppSettings`; future device-add
events skip the selection dialog while preserving the existing fallback to
system default when a selected device disappears.

The same setting is exposed in Radio Setup > Audio > PC Audio Devices as
"Prompt on Audio Device Changes"; that checkbox is checked when notifications
are enabled and unchecked when the suppression setting is active.

Accepting the dialog queues `AudioEngine::setInputDevice()` and
`AudioEngine::setOutputDevice()` onto the audio worker thread. Those setters are
the only place that persists the chosen device IDs and restarts the affected
Expand Down
16 changes: 16 additions & 0 deletions src/gui/AudioDeviceChangeDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include <QAudioDevice>
#include <QColor>
#include <QCheckBox>
#include <QFrame>
#include <QFont>
#include <QHBoxLayout>
Expand Down Expand Up @@ -37,6 +38,11 @@ const char* kDialogStyle =
"QLabel#title { color: #ffffff; background: transparent; font-size: 18px; font-weight: bold; }"
"QLabel#body { color: #c8d8e8; background: transparent; }"
"QLabel#sectionLabel { color: #00b4d8; background: transparent; font-weight: bold; }"
"QCheckBox { color: #c8d8e8; spacing: 8px; }"
"QCheckBox::indicator { width: 16px; height: 16px;"
" border: 1px solid #304050; border-radius: 3px; background: #0a0a14; }"
"QCheckBox::indicator:hover { border-color: #00b4d8; }"
"QCheckBox::indicator:checked { background: #00b4d8; border-color: #00c8f0; }"
"QListWidget {"
" background: #0a0a14;"
" border: 1px solid #304050;"
Expand Down Expand Up @@ -299,6 +305,11 @@ AudioDeviceChangeDialog::AudioDeviceChangeDialog(
buttonRow->setContentsMargins(0, 4, 0, 0);
buttonRow->setSpacing(8);

m_dontAskAgainCheck = new QCheckBox(tr("Don't ask me again"), content);
m_dontAskAgainCheck->setCursor(Qt::PointingHandCursor);
buttonRow->addWidget(m_dontAskAgainCheck);
buttonRow->addStretch(1);

auto* cancel = new QPushButton(tr("Cancel"), content);
cancel->setObjectName("cancelButton");
cancel->setCursor(Qt::PointingHandCursor);
Expand Down Expand Up @@ -377,4 +388,9 @@ QAudioDevice AudioDeviceChangeDialog::selectedOutputDevice() const
return selectedDevice(m_outputList, m_outputDevices);
}

bool AudioDeviceChangeDialog::dontAskAgainChecked() const
{
return m_dontAskAgainCheck && m_dontAskAgainCheck->isChecked();
}

} // namespace AetherSDR
3 changes: 3 additions & 0 deletions src/gui/AudioDeviceChangeDialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <QList>

class QListWidget;
class QCheckBox;
class QVBoxLayout;
class QWidget;

Expand All @@ -23,6 +24,7 @@ class AudioDeviceChangeDialog : public QDialog {

QAudioDevice selectedInputDevice() const;
QAudioDevice selectedOutputDevice() const;
bool dontAskAgainChecked() const;
void setFramelessMode(bool on);

private:
Expand All @@ -33,6 +35,7 @@ class AudioDeviceChangeDialog : public QDialog {
QVBoxLayout* m_bodyLayout{nullptr};
QListWidget* m_inputList{nullptr};
QListWidget* m_outputList{nullptr};
QCheckBox* m_dontAskAgainCheck{nullptr};
QList<QAudioDevice> m_inputDevices;
QList<QAudioDevice> m_outputDevices;
};
Expand Down
20 changes: 20 additions & 0 deletions src/gui/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,8 @@ constexpr int kSwrSweepTuneStopTimeoutMs = 1800;
constexpr int kSwrSweepTgxlRestoreTimeoutMs = 3500;
constexpr int kSwrSweepMaxPoints = 260;
constexpr double kMemoryRevealTargetToleranceMhz = 0.000001;
constexpr const char* kSuppressAudioDeviceNotificationsKey =
"SuppressAudioDeviceNotifications";

QList<QByteArray> audioDeviceIds(const QList<QAudioDevice>& devices)
{
Expand Down Expand Up @@ -6456,6 +6458,18 @@ void MainWindow::handleAudioDeviceListChanged()
return;
}

const bool suppressAudioDeviceNotifications =
AppSettings::instance()
.value(kSuppressAudioDeviceNotificationsKey, "False")
.toString() == "True";
if (suppressAudioDeviceNotifications) {
if (resetInput || resetOutput)
resetMissingAudioDevicesToDefault(resetInput,
resetOutput,
reinitializePcInput);
return;
}

m_audioDeviceDialogOpen = true;
AudioDeviceChangeDialog dialog(inputDevices,
outputDevices,
Expand All @@ -6467,6 +6481,12 @@ void MainWindow::handleAudioDeviceListChanged()
const int result = dialog.exec();
m_audioDeviceDialogOpen = false;

if (dialog.dontAskAgainChecked()) {
auto& settings = AppSettings::instance();
settings.setValue(kSuppressAudioDeviceNotificationsKey, "True");
settings.save();
}

if (result == QDialog::Accepted) {
const QAudioDevice selectedInput = dialog.selectedInputDevice();
const QAudioDevice selectedOutput = dialog.selectedOutputDevice();
Expand Down
18 changes: 18 additions & 0 deletions src/gui/RadioSetupDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ static const QString kEditStyle =
"QLineEdit { background: #1a2a3a; border: 1px solid #304050; "
"border-radius: 3px; color: #c8d8e8; font-size: 12px; padding: 2px 4px; }";

static constexpr const char* kSuppressAudioDeviceNotificationsKey =
"SuppressAudioDeviceNotifications";

static QString normalizedOscillatorValue(QString value)
{
value = value.trimmed().toLower();
Expand Down Expand Up @@ -1889,6 +1892,21 @@ QWidget* RadioSetupDialog::buildAudioTab()
outRow->addWidget(outCombo, 1);
pcLayout->addLayout(outRow);

auto* promptCheck = new QCheckBox("Prompt on Audio Device Changes");
promptCheck->setStyleSheet("QCheckBox { color: #c8d8e8; font-size: 11px; }");
promptCheck->setToolTip("Show the Audio Device Detected dialog when a new PC audio device appears.");
const bool suppressAudioDeviceNotifications =
AppSettings::instance()
.value(kSuppressAudioDeviceNotificationsKey, "False")
.toString() == "True";
promptCheck->setChecked(!suppressAudioDeviceNotifications);
connect(promptCheck, &QCheckBox::toggled, this, [](bool on) {
auto& s = AppSettings::instance();
s.setValue(kSuppressAudioDeviceNotificationsKey, on ? "False" : "True");
s.save();
});
pcLayout->addWidget(promptCheck);

// Wire device changes to AudioEngine
if (m_audio) {
// Route through QueuedConnection so setInputDevice/setOutputDevice
Expand Down
Loading