Skip to content

Commit fbdd268

Browse files
committed
Qt: Populate audio devices asynchronously
Save another 40-60ms when opening the window on my system. That's a few frames at least!
1 parent edd3df8 commit fbdd268

File tree

2 files changed

+47
-37
lines changed

2 files changed

+47
-37
lines changed

src/duckstation-qt/audiosettingswidget.cpp

Lines changed: 46 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// SPDX-License-Identifier: CC-BY-NC-ND-4.0
33

44
#include "audiosettingswidget.h"
5+
#include "qthost.h"
56
#include "qtutils.h"
67
#include "settingswindow.h"
78
#include "settingwidgetbinder.h"
@@ -155,54 +156,63 @@ void AudioSettingsWidget::updateDriverNames()
155156

156157
SettingWidgetBinder::BindWidgetToStringSetting(m_dialog->getSettingsInterface(), m_ui.driver, "Audio", "Driver",
157158
std::move(names.front().first));
158-
connect(m_ui.driver, &QComboBox::currentIndexChanged, this, &AudioSettingsWidget::updateDeviceNames);
159+
connect(m_ui.driver, &QComboBox::currentIndexChanged, this, &AudioSettingsWidget::queueUpdateDeviceNames);
159160
}
160161

161-
updateDeviceNames();
162+
queueUpdateDeviceNames();
162163
}
163164

164-
void AudioSettingsWidget::updateDeviceNames()
165+
void AudioSettingsWidget::queueUpdateDeviceNames()
165166
{
166-
const AudioBackend backend = getEffectiveBackend();
167-
const std::string driver_name = m_dialog->getEffectiveStringValue("Audio", "Driver", "");
168-
const std::string current_device = m_dialog->getEffectiveStringValue("Audio", "Device", "");
169-
std::vector<AudioStream::DeviceInfo> devices = AudioStream::GetOutputDevices(backend, driver_name, SPU::SAMPLE_RATE);
170-
171167
SettingWidgetBinder::DisconnectWidget(m_ui.outputDevice);
172168
m_ui.outputDevice->clear();
169+
m_ui.outputDevice->setEnabled(false);
173170
m_output_device_latency = 0;
174171

175-
if (devices.empty())
176-
{
177-
m_ui.outputDevice->addItem(tr("Default"));
178-
m_ui.outputDevice->setEnabled(false);
179-
}
180-
else
181-
{
182-
m_ui.outputDevice->setEnabled(true);
183-
184-
bool is_known_device = false;
185-
for (const AudioStream::DeviceInfo& di : devices)
186-
{
187-
m_ui.outputDevice->addItem(QString::fromStdString(di.display_name), QString::fromStdString(di.name));
188-
if (di.name == current_device)
172+
const AudioBackend backend = getEffectiveBackend();
173+
std::string driver_name = m_dialog->getEffectiveStringValue("Audio", "Driver");
174+
QtAsyncTask::create(this, [this, driver_name = std::move(driver_name), backend]() {
175+
std::vector<AudioStream::DeviceInfo> devices =
176+
AudioStream::GetOutputDevices(backend, driver_name, SPU::SAMPLE_RATE);
177+
return [this, devices = std::move(devices), driver_name = std::move(driver_name), backend]() {
178+
// just in case we executed out of order...
179+
if (backend != getEffectiveBackend() || driver_name != m_dialog->getEffectiveStringValue("Audio", "Driver"))
180+
return;
181+
182+
if (devices.empty())
189183
{
190-
m_output_device_latency = di.minimum_latency_frames;
191-
is_known_device = true;
184+
m_ui.outputDevice->addItem(tr("Default"));
185+
}
186+
else
187+
{
188+
const std::string current_device = m_dialog->getEffectiveStringValue("Audio", "Device");
189+
190+
m_ui.outputDevice->setEnabled(true);
191+
192+
bool is_known_device = false;
193+
for (const AudioStream::DeviceInfo& di : devices)
194+
{
195+
m_ui.outputDevice->addItem(QString::fromStdString(di.display_name), QString::fromStdString(di.name));
196+
if (di.name == current_device)
197+
{
198+
m_output_device_latency = di.minimum_latency_frames;
199+
is_known_device = true;
200+
}
201+
}
202+
203+
if (!is_known_device)
204+
{
205+
m_ui.outputDevice->addItem(tr("Unknown Device \"%1\"").arg(QString::fromStdString(current_device)),
206+
QString::fromStdString(current_device));
207+
}
208+
209+
SettingWidgetBinder::BindWidgetToStringSetting(m_dialog->getSettingsInterface(), m_ui.outputDevice, "Audio",
210+
"OutputDevice", std::move(devices.front().name));
192211
}
193-
}
194-
195-
if (!is_known_device)
196-
{
197-
m_ui.outputDevice->addItem(tr("Unknown Device \"%1\"").arg(QString::fromStdString(current_device)),
198-
QString::fromStdString(current_device));
199-
}
200-
201-
SettingWidgetBinder::BindWidgetToStringSetting(m_dialog->getSettingsInterface(), m_ui.outputDevice, "Audio",
202-
"OutputDevice", std::move(devices.front().name));
203-
}
204212

205-
updateLatencyLabel();
213+
updateLatencyLabel();
214+
};
215+
});
206216
}
207217

208218
void AudioSettingsWidget::updateLatencyLabel()

src/duckstation-qt/audiosettingswidget.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class AudioSettingsWidget : public QWidget
2828
void onStretchModeChanged();
2929

3030
void updateDriverNames();
31-
void updateDeviceNames();
31+
void queueUpdateDeviceNames();
3232
void updateLatencyLabel();
3333
void updateVolumeLabel();
3434
void onMinimalOutputLatencyChecked(Qt::CheckState state);

0 commit comments

Comments
 (0)