From 57c1ca97f78bc10bac7dca27a957344778ba1ced Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Fri, 5 Aug 2022 17:50:28 +1000 Subject: [PATCH] Qt: Hook up audio driver selection --- src/core/settings.cpp | 2 ++ src/core/settings.h | 1 + src/core/system.cpp | 2 +- src/duckstation-qt/audiosettingswidget.cpp | 36 +++++++++++++++++++++- src/duckstation-qt/audiosettingswidget.h | 1 + src/frontend-common/common_host.h | 3 ++ src/frontend-common/cubeb_audio_stream.cpp | 16 +++++++--- 7 files changed, 55 insertions(+), 6 deletions(-) diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 4ef554ee1..3fda08091 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -275,6 +275,7 @@ void Settings::Load(SettingsInterface& si) audio_backend = ParseAudioBackend(si.GetStringValue("Audio", "Backend", GetAudioBackendName(DEFAULT_AUDIO_BACKEND)).c_str()) .value_or(DEFAULT_AUDIO_BACKEND); + audio_driver = si.GetStringValue("Audio", "Driver"); audio_stretch_mode = AudioStream::ParseStretchMode( si.GetStringValue("Audio", "StretchMode", AudioStream::GetStretchModeName(DEFAULT_AUDIO_STRETCH_MODE)).c_str()) @@ -477,6 +478,7 @@ void Settings::Save(SettingsInterface& si) const si.SetIntValue("CDROM", "SeekSpeedup", cdrom_seek_speedup); si.SetStringValue("Audio", "Backend", GetAudioBackendName(audio_backend)); + si.SetStringValue("Audio", "Driver", audio_driver.c_str()); si.SetStringValue("Audio", "StretchMode", AudioStream::GetStretchModeName(audio_stretch_mode)); si.SetUIntValue("Audio", "BufferMS", audio_buffer_ms); si.SetUIntValue("Audio", "OutputLatencyMS", audio_output_latency_ms); diff --git a/src/core/settings.h b/src/core/settings.h index e972cfaba..78655b2ba 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -144,6 +144,7 @@ struct Settings AudioBackend audio_backend = DEFAULT_AUDIO_BACKEND; AudioStretchMode audio_stretch_mode = DEFAULT_AUDIO_STRETCH_MODE; + std::string audio_driver; u32 audio_output_latency_ms = DEFAULT_AUDIO_OUTPUT_LATENCY_MS; u32 audio_buffer_ms = DEFAULT_AUDIO_BUFFER_MS; u32 audio_output_volume = 100; diff --git a/src/core/system.cpp b/src/core/system.cpp index ffea7d180..89ca98c9e 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -3048,7 +3048,7 @@ void System::CheckForSettingsChanges(const Settings& old_settings) UpdateOverclock(); } - if (g_settings.audio_backend != old_settings.audio_backend) + if (g_settings.audio_backend != old_settings.audio_backend || g_settings.audio_driver != old_settings.audio_driver) { if (g_settings.audio_backend != old_settings.audio_backend) { diff --git a/src/duckstation-qt/audiosettingswidget.cpp b/src/duckstation-qt/audiosettingswidget.cpp index b118a3044..bffa66a21 100644 --- a/src/duckstation-qt/audiosettingswidget.cpp +++ b/src/duckstation-qt/audiosettingswidget.cpp @@ -1,5 +1,6 @@ #include "audiosettingswidget.h" #include "core/spu.h" +#include "frontend-common/common_host.h" #include "settingsdialog.h" #include "settingwidgetbinder.h" #include "util/audio_stream.h" @@ -29,10 +30,11 @@ AudioSettingsWidget::AudioSettingsWidget(SettingsDialog* dialog, QWidget* parent Settings::DEFAULT_AUDIO_OUTPUT_LATENCY_MS); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.startDumpingOnBoot, "Audio", "DumpOnBoot", false); SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.muteCDAudio, "CDROM", "MuteCDAudio", false); + connect(m_ui.audioBackend, &QComboBox::currentIndexChanged, this, &AudioSettingsWidget::updateDriverNames); + updateDriverNames(); m_ui.outputLatencyMinimal->setChecked(m_ui.outputLatencyMS->value() == 0); m_ui.outputLatencyMS->setEnabled(m_ui.outputLatencyMinimal->isChecked()); - m_ui.driver->setEnabled(false); connect(m_ui.bufferMS, &QSlider::valueChanged, this, &AudioSettingsWidget::updateLatencyLabel); connect(m_ui.outputLatencyMS, &QSlider::valueChanged, this, &AudioSettingsWidget::updateLatencyLabel); @@ -92,6 +94,38 @@ AudioSettingsWidget::AudioSettingsWidget(SettingsDialog* dialog, QWidget* parent AudioSettingsWidget::~AudioSettingsWidget() = default; +void AudioSettingsWidget::updateDriverNames() +{ + const AudioBackend backend = + Settings::ParseAudioBackend( + m_dialog + ->getEffectiveStringValue("Audio", "Backend", Settings::GetAudioBackendName(Settings::DEFAULT_AUDIO_BACKEND)) + .c_str()) + .value_or(Settings::DEFAULT_AUDIO_BACKEND); + + std::vector names; + +#ifdef WITH_CUBEB + if (backend == AudioBackend::Cubeb) + names = CommonHost::GetCubebDriverNames(); +#endif + + m_ui.driver->disconnect(); + if (names.empty()) + { + m_ui.driver->setEnabled(false); + m_ui.driver->clear(); + return; + } + + m_ui.driver->setEnabled(true); + for (const std::string& name : names) + m_ui.driver->addItem(QString::fromStdString(name)); + + SettingWidgetBinder::BindWidgetToStringSetting(m_dialog->getSettingsInterface(), m_ui.driver, "Audio", "Driver", + std::move(names.front())); +} + void AudioSettingsWidget::updateLatencyLabel() { const u32 output_latency_ms = static_cast(m_ui.outputLatencyMS->value()); diff --git a/src/duckstation-qt/audiosettingswidget.h b/src/duckstation-qt/audiosettingswidget.h index 65c7bb77f..6d2e9cfbe 100644 --- a/src/duckstation-qt/audiosettingswidget.h +++ b/src/duckstation-qt/audiosettingswidget.h @@ -15,6 +15,7 @@ public: ~AudioSettingsWidget(); private Q_SLOTS: + void updateDriverNames(); void updateLatencyLabel(); void updateVolumeLabel(); void onMinimalOutputLatencyChecked(bool new_value); diff --git a/src/frontend-common/common_host.h b/src/frontend-common/common_host.h index 9d4a02762..41747ff8e 100644 --- a/src/frontend-common/common_host.h +++ b/src/frontend-common/common_host.h @@ -2,6 +2,8 @@ #include "core/system.h" #include #include +#include +#include class SettingsInterface; @@ -33,6 +35,7 @@ void ReleaseHostDisplayResources(); #ifdef WITH_CUBEB std::unique_ptr CreateCubebAudioStream(u32 sample_rate, u32 channels, u32 buffer_ms, u32 latency_ms, AudioStretchMode stretch); +std::vector GetCubebDriverNames(); #endif #ifdef _WIN32 std::unique_ptr CreateXAudio2Stream(u32 sample_rate, u32 channels, u32 buffer_ms, u32 latency_ms, diff --git a/src/frontend-common/cubeb_audio_stream.cpp b/src/frontend-common/cubeb_audio_stream.cpp index 1e4b35b6b..e037392ca 100644 --- a/src/frontend-common/cubeb_audio_stream.cpp +++ b/src/frontend-common/cubeb_audio_stream.cpp @@ -4,7 +4,7 @@ #include "common/string_util.h" #include "common_host.h" #include "core/host.h" -#include "core/host_settings.h" +#include "core/settings.h" #include "cubeb/cubeb.h" Log_SetChannel(CubebAudioStream); @@ -73,9 +73,8 @@ bool CubebAudioStream::Initialize(u32 latency_ms) cubeb_set_log_callback(CUBEB_LOG_NORMAL, LogCallback); - std::string backend(Host::GetStringSettingValue("Audio", "CubebBackend")); - - int rv = cubeb_init(&m_context, "DuckStation", backend.empty() ? nullptr : backend.c_str()); + int rv = + cubeb_init(&m_context, "DuckStation", g_settings.audio_driver.empty() ? nullptr : g_settings.audio_driver.c_str()); if (rv != CUBEB_OK) { Host::ReportFormattedErrorAsync("Error", "Could not initialize cubeb context: %d", rv); @@ -199,3 +198,12 @@ std::unique_ptr CommonHost::CreateCubebAudioStream(u32 sample_rate, stream.reset(); return stream; } + +std::vector CommonHost::GetCubebDriverNames() +{ + std::vector names; + const char** cubeb_names = cubeb_get_backend_names(); + for (u32 i = 0; cubeb_names[i] != nullptr; i++) + names.emplace_back(cubeb_names[i]); + return names; +}