Qt: Add audio backend selection (only cubeb for now)

This commit is contained in:
Connor McLaughlin 2022-09-29 23:52:11 +10:00 committed by refractionpcsx2
parent 9170a5abc1
commit 44d969c0d2
7 changed files with 111 additions and 6 deletions

View File

@ -18,6 +18,8 @@
#include <QtWidgets/QMessageBox>
#include <algorithm>
#include "pcsx2/SPU2/Global.h"
#include "AudioSettingsWidget.h"
#include "QtHost.h"
#include "QtUtils.h"
@ -69,7 +71,10 @@ AudioSettingsWidget::AudioSettingsWidget(SettingsDialog* dialog, QWidget* parent
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.outputModule, "SPU2/Output", "OutputModule", s_output_module_entries, s_output_module_values, DEFAULT_OUTPUT_MODULE);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.latency, "SPU2/Output", "Latency", DEFAULT_OUTPUT_LATENCY);
connect(m_ui.outputModule, &QComboBox::currentIndexChanged, this, &AudioSettingsWidget::outputModuleChanged);
connect(m_ui.backend, &QComboBox::currentIndexChanged, this, &AudioSettingsWidget::outputBackendChanged);
connect(m_ui.latency, &QSlider::valueChanged, this, &AudioSettingsWidget::updateLatencyLabel);
outputModuleChanged();
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.volume, "SPU2/Mixing", "FinalVolume", DEFAULT_VOLUME);
connect(m_ui.volume, &QSlider::valueChanged, this, &AudioSettingsWidget::updateVolumeLabel);
@ -99,6 +104,59 @@ void AudioSettingsWidget::expansionModeChanged()
m_ui.dplLevel->setDisabled(!expansion51);
}
void AudioSettingsWidget::outputModuleChanged()
{
const std::string module_name(m_dialog->getEffectiveStringValue("SPU2/Output", "OutputModule", DEFAULT_OUTPUT_MODULE));
const char* const* backend_names = GetOutputModuleBackends(module_name.c_str());
const std::string backend_name(m_dialog->getEffectiveStringValue("SPU2/Output", "BackendName", ""));
QSignalBlocker sb(m_ui.backend);
m_ui.backend->clear();
if (m_dialog->isPerGameSettings())
{
const QString global_backend(QString::fromStdString(Host::GetStringSettingValue("SPU2/Output", "BackendName", "")));
m_ui.backend->addItem(tr("Use Global Setting [%1]").arg(global_backend.isEmpty() ? tr("Default") : global_backend));
}
m_ui.backend->setEnabled(backend_names != nullptr);
m_ui.backend->addItem(tr("(Default)"));
if (!backend_names || backend_name.empty())
m_ui.backend->setCurrentIndex(0);
if (backend_names)
{
for (u32 i = 0; backend_names[i] != nullptr; i++)
{
const int index = m_ui.backend->count();
m_ui.backend->addItem(QString::fromUtf8(backend_names[i]));
if (backend_name == backend_names[i])
m_ui.backend->setCurrentIndex(index);
}
}
}
void AudioSettingsWidget::outputBackendChanged()
{
int index = m_ui.backend->currentIndex();
if (m_dialog->isPerGameSettings())
{
if (index == 0)
{
m_dialog->setStringSettingValue("SPU2/Output", "BackendName", std::nullopt);
return;
}
index--;
}
if (index == 0)
m_dialog->setStringSettingValue("SPU2/Output", "BackendName", "");
else
m_dialog->setStringSettingValue("SPU2/Output", "BackendName", m_ui.backend->currentText().toUtf8().constData());
}
void AudioSettingsWidget::updateVolumeLabel()
{
m_ui.volumeLabel->setText(tr("%1%").arg(m_ui.volume->value()));

View File

@ -31,6 +31,8 @@ public:
private Q_SLOTS:
void expansionModeChanged();
void outputModuleChanged();
void outputBackendChanged();
void updateVolumeLabel();
void updateLatencyLabel();
void updateTimestretchSequenceLengthLabel();

View File

@ -130,7 +130,7 @@
</item>
</widget>
</item>
<item row="3" column="0">
<item row="3" column="0">
<widget class="QLabel" name="label_3b">
<property name="text">
<string>ProLogic Level:</string>
@ -173,16 +173,16 @@
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="outputModule" />
<widget class="QComboBox" name="outputModule"/>
</item>
<item row="1" column="0">
<item row="2" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Latency:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QSlider" name="latency">
@ -215,6 +215,16 @@
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Output Backend:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="backend"/>
</item>
</layout>
</widget>
</item>

View File

@ -64,6 +64,11 @@ public:
{
return "No Sound (Emulate SPU2 only)";
}
const char* const* GetBackendNames() const override
{
return nullptr;
}
};
static NullOutModule s_NullOut;
@ -93,6 +98,19 @@ int FindOutputModuleById(const char* omodid)
return modcnt;
}
const char* const* GetOutputModuleBackends(const char* omodid)
{
for (SndOutModule* mod : mods)
{
if (mod && std::strcmp(mod->GetIdent(), omodid) == 0)
{
return mod->GetBackendNames();
}
}
return nullptr;
}
StereoOut32* SndBuffer::m_buffer;
s32 SndBuffer::m_size;
alignas(4) volatile s32 SndBuffer::m_rpos;

View File

@ -34,6 +34,10 @@ extern int SampleRate;
extern int FindOutputModuleById(const char* omodid);
// Returns a null-terminated list of backends for the specified module.
// nullptr is returned if the specified module does not have multiple backends.
extern const char* const* GetOutputModuleBackends(const char* omodid);
// Implemented in Config.cpp
extern float VolumeAdjustFL;
extern float VolumeAdjustC;
@ -641,6 +645,9 @@ public:
// (for use in configuration screen)
virtual const char* GetLongName() const = 0;
// Returns a null-terminated list of backends, or nullptr.
virtual const char* const* GetBackendNames() const = 0;
virtual bool Init() = 0;
virtual void Close() = 0;

View File

@ -363,6 +363,11 @@ public:
return "Cubeb (Cross-platform)";
}
const char* const* GetBackendNames() const override
{
return cubeb_get_backend_names();
}
void ReadSettings()
{
#ifndef PCSX2_CORE
@ -371,12 +376,12 @@ public:
// TODO: Once the config stuff gets merged, drop the wxString here.
wxString backend;
CfgReadStr(L"Cubeb", L"BackendName", backend, L"");
CfgReadStr(L"SPU2/Output", L"BackendName", backend, L"");
m_Backend = StringUtil::wxStringToUTF8String(backend);
#else
m_SuggestedLatencyMinimal = Host::GetBoolSettingValue("Cubeb", "MinimalSuggestedLatency", false);
m_SuggestedLatencyMS = std::clamp(Host::GetIntSettingValue("Cubeb", "ManualSuggestedLatencyMS", MINIMUM_LATENCY_MS), MINIMUM_LATENCY_MS, MAXIMUM_LATENCY_MS);
m_Backend = Host::GetStringSettingValue("Cubeb", "BackendName", "");
m_Backend = Host::GetStringSettingValue("SPU2/Output", "BackendName", "");
#endif
}
};

View File

@ -380,6 +380,11 @@ public:
return "XAudio 2 (Recommended)";
}
const char* const* GetBackendNames() const override
{
return nullptr;
}
} static XA2;
SndOutModule* XAudio2Out = &XA2;