SPU2: Split output latency and target buffer size

This commit is contained in:
Stenzek 2022-12-30 17:39:41 +10:00 committed by refractionpcsx2
parent c274e447dd
commit 0c8beedb94
7 changed files with 363 additions and 246 deletions

View File

@ -33,7 +33,8 @@ static constexpr s32 DEFAULT_SYNCHRONIZATION_MODE = 0;
static constexpr s32 DEFAULT_EXPANSION_MODE = 0;
static constexpr s32 DEFAULT_DPL_DECODING_LEVEL = 0;
static const char* DEFAULT_OUTPUT_MODULE = "cubeb";
static constexpr s32 DEFAULT_OUTPUT_LATENCY = 100;
static constexpr s32 DEFAULT_TARGET_LATENCY = 100;
static constexpr s32 DEFAULT_OUTPUT_LATENCY = 20;
static constexpr s32 DEFAULT_VOLUME = 100;
static constexpr s32 DEFAULT_SOUNDTOUCH_SEQUENCE_LENGTH = 30;
static constexpr s32 DEFAULT_SOUNDTOUCH_SEEK_WINDOW = 20;
@ -63,15 +64,21 @@ AudioSettingsWidget::AudioSettingsWidget(SettingsDialog* dialog, QWidget* parent
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.syncMode, "SPU2/Output", "SynchMode", DEFAULT_SYNCHRONIZATION_MODE);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.expansionMode, "SPU2/Output", "SpeakerConfiguration", DEFAULT_EXPANSION_MODE);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.dplLevel, "SPU2/Output", "DplDecodingLevel", DEFAULT_DPL_DECODING_LEVEL);
connect(m_ui.syncMode, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &AudioSettingsWidget::updateTargetLatencyRange);
connect(m_ui.expansionMode, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &AudioSettingsWidget::expansionModeChanged);
updateTargetLatencyRange();
expansionModeChanged();
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);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.targetLatency, "SPU2/Output", "Latency", DEFAULT_TARGET_LATENCY);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.outputLatency, "SPU2/Output", "OutputLatency", DEFAULT_OUTPUT_LATENCY);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.outputLatencyMinimal, "SPU2/Output", "OutputLatencyMinimal", false);
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);
connect(m_ui.targetLatency, &QSlider::valueChanged, this, &AudioSettingsWidget::updateLatencyLabels);
connect(m_ui.outputLatency, &QSlider::valueChanged, this, &AudioSettingsWidget::updateLatencyLabels);
connect(m_ui.outputLatencyMinimal, &QCheckBox::stateChanged, this, &AudioSettingsWidget::updateLatencyLabels);
outputModuleChanged();
m_ui.volume->setValue(m_dialog->getEffectiveIntValue("SPU2/Mixing", "FinalVolume", DEFAULT_VOLUME));
@ -90,7 +97,8 @@ AudioSettingsWidget::AudioSettingsWidget(SettingsDialog* dialog, QWidget* parent
m_ui.dplLevel->setVisible(false);
volumeChanged(m_ui.volume->value());
updateLatencyLabel();
onMinimalOutputLatencyStateChanged();
updateLatencyLabels();
updateTimestretchSequenceLengthLabel();
updateTimestretchSeekwindowLengthLabel();
updateTimestretchOverlapLabel();
@ -105,7 +113,12 @@ AudioSettingsWidget::AudioSettingsWidget(SettingsDialog* dialog, QWidget* parent
dialog->registerWidgetHelp(m_ui.backend, tr("Output Backend"), tr("Default"), tr(""));
dialog->registerWidgetHelp(m_ui.latency, tr("Latency"), tr("100 ms"), tr(""));
dialog->registerWidgetHelp(m_ui.targetLatency, tr("Target Latency"), tr("100 ms"),
tr("Determines the buffer size which the time stretcher will try to keep filled. It effectively selects the average latency, as "
"audio will be stretched/shrunk to keep the buffer size within check."));
dialog->registerWidgetHelp(m_ui.outputLatency, tr("Output Latency"), tr("20 ms"),
tr("Determines the latency from the buffer to the host audio output. This can be set lower than the target latency to reduce audio "
"delay."));
dialog->registerWidgetHelp(m_ui.sequenceLength, tr("Sequence Length"), tr("30 ms"), tr(""));
@ -206,9 +219,42 @@ void AudioSettingsWidget::volumeChanged(int value)
}
}
void AudioSettingsWidget::updateLatencyLabel()
void AudioSettingsWidget::updateTargetLatencyRange()
{
m_ui.latencyLabel->setText(tr("%1 ms (avg)").arg(m_ui.latency->value()));
const Pcsx2Config::SPU2Options::SynchronizationMode sync_mode = static_cast<Pcsx2Config::SPU2Options::SynchronizationMode>(
m_dialog->getIntValue("SPU2/Output", "SynchMode", DEFAULT_SYNCHRONIZATION_MODE).value_or(DEFAULT_SYNCHRONIZATION_MODE));
m_ui.targetLatency->setMinimum((sync_mode == Pcsx2Config::SPU2Options::SynchronizationMode::TimeStretch) ?
Pcsx2Config::SPU2Options::MIN_LATENCY_TIMESTRETCH :
Pcsx2Config::SPU2Options::MIN_LATENCY);
m_ui.targetLatency->setMaximum(Pcsx2Config::SPU2Options::MAX_LATENCY);
}
void AudioSettingsWidget::updateLatencyLabels()
{
const bool minimal_output = m_dialog->getEffectiveBoolValue("SPU2/Output", "OutputLatencyMinimal", false);
m_ui.targetLatencyLabel->setText(tr("%1 ms").arg(m_ui.targetLatency->value()));
m_ui.outputLatencyLabel->setText(minimal_output ? tr("N/A") : tr("%1 ms").arg(m_ui.outputLatency->value()));
const u32 output_latency_ms = minimal_output ? 0 : static_cast<u32>(m_ui.outputLatency->value());
const u32 buffer_ms = static_cast<u32>(m_ui.targetLatency->value());
if (output_latency_ms > 0)
{
m_ui.latencySummary->setText(tr("Average Latency: %1 ms (%2 ms buffer + %3 ms output)")
.arg(buffer_ms + output_latency_ms)
.arg(buffer_ms)
.arg(output_latency_ms));
}
else
{
m_ui.latencySummary->setText(tr("Average Latency: %1 ms (plus minimum output)").arg(buffer_ms));
}
}
void AudioSettingsWidget::onMinimalOutputLatencyStateChanged()
{
m_ui.outputLatency->setEnabled(!m_dialog->getEffectiveBoolValue("SPU2/Output", "OutputLatencyMinimal", false));
}
void AudioSettingsWidget::updateTimestretchSequenceLengthLabel()

View File

@ -34,7 +34,9 @@ private Q_SLOTS:
void outputModuleChanged();
void outputBackendChanged();
void volumeChanged(int value);
void updateLatencyLabel();
void updateTargetLatencyRange();
void updateLatencyLabels();
void onMinimalOutputLatencyStateChanged();
void updateTimestretchSequenceLengthLabel();
void updateTimestretchSeekwindowLengthLabel();
void updateTimestretchOverlapLabel();

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>752</width>
<height>448</height>
<width>754</width>
<height>464</height>
</rect>
</property>
<property name="windowTitle">
@ -26,208 +26,6 @@
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Mixing Settings</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Interpolation:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="interpolation">
<item>
<property name="text">
<string>Nearest (Fastest / worst quality)</string>
</property>
</item>
<item>
<property name="text">
<string>Linear (Simple / okay sound)</string>
</property>
</item>
<item>
<property name="text">
<string>Cubic (Fake highs / okay sound)</string>
</property>
</item>
<item>
<property name="text">
<string>Hermite (Better highs / okay sound)</string>
</property>
</item>
<item>
<property name="text">
<string>Catmull-Rom (PS2-like / good sound)</string>
</property>
</item>
<item>
<property name="text">
<string>Gaussian (PS2-like / great sound)</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Synchronization:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="syncMode">
<item>
<property name="text">
<string>TimeStretch (Recommended)</string>
</property>
</item>
<item>
<property name="text">
<string>Async Mix (Breaks some games!)</string>
</property>
</item>
<item>
<property name="text">
<string>None (Audio can skip.)</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Expansion:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="expansionMode">
<item>
<property name="text">
<string>Stereo (None, Default)</string>
</property>
</item>
<item>
<property name="text">
<string>Quadrafonic</string>
</property>
</item>
<item>
<property name="text">
<string>Surround 5.1</string>
</property>
</item>
<item>
<property name="text">
<string>Surround 7.1</string>
</property>
</item>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3b">
<property name="text">
<string>ProLogic Level:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="dplLevel">
<item>
<property name="text">
<string>None (Default)</string>
</property>
</item>
<item>
<property name="text">
<string>ProLogic Decoding (basic)</string>
</property>
</item>
<item>
<property name="text">
<string>ProLogic II Decoding (gigaherz)</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Output Settings</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Output Module:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="outputModule"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Latency:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QSlider" name="latency">
<property name="minimum">
<number>15</number>
</property>
<property name="maximum">
<number>200</number>
</property>
<property name="value">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>200</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="latencyLabel">
<property name="text">
<string>100 ms (avg)</string>
</property>
</widget>
</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>
<item row="2" column="0">
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
@ -378,19 +176,6 @@
</layout>
</widget>
</item>
<item row="3" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1" rowspan="4">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
@ -401,6 +186,18 @@
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QSlider" name="volume">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
<property name="maximum">
<number>200</number>
</property>
@ -417,9 +214,18 @@
</item>
<item row="1" column="0">
<widget class="QLabel" name="volumeLabel">
<property name="minimumSize">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>100%</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
@ -440,6 +246,278 @@
</item>
</layout>
</item>
<item row="3" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Mixing Settings</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Interpolation:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="interpolation">
<item>
<property name="text">
<string>Nearest (Fastest / worst quality)</string>
</property>
</item>
<item>
<property name="text">
<string>Linear (Simple / okay sound)</string>
</property>
</item>
<item>
<property name="text">
<string>Cubic (Fake highs / okay sound)</string>
</property>
</item>
<item>
<property name="text">
<string>Hermite (Better highs / okay sound)</string>
</property>
</item>
<item>
<property name="text">
<string>Catmull-Rom (PS2-like / good sound)</string>
</property>
</item>
<item>
<property name="text">
<string>Gaussian (PS2-like / great sound)</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Synchronization:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="syncMode">
<item>
<property name="text">
<string>TimeStretch (Recommended)</string>
</property>
</item>
<item>
<property name="text">
<string>Async Mix (Breaks some games!)</string>
</property>
</item>
<item>
<property name="text">
<string>None (Audio can skip.)</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Expansion:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="expansionMode">
<item>
<property name="text">
<string>Stereo (None, Default)</string>
</property>
</item>
<item>
<property name="text">
<string>Quadrafonic</string>
</property>
</item>
<item>
<property name="text">
<string>Surround 5.1</string>
</property>
</item>
<item>
<property name="text">
<string>Surround 7.1</string>
</property>
</item>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3b">
<property name="text">
<string>ProLogic Level:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="dplLevel">
<item>
<property name="text">
<string>None (Default)</string>
</property>
</item>
<item>
<property name="text">
<string>ProLogic Decoding (basic)</string>
</property>
</item>
<item>
<property name="text">
<string>ProLogic II Decoding (gigaherz)</string>
</property>
</item>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Target Latency:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QSlider" name="targetLatency">
<property name="minimum">
<number>15</number>
</property>
<property name="maximum">
<number>200</number>
</property>
<property name="value">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>200</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="targetLatencyLabel">
<property name="text">
<string>100 ms</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Output Settings</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Output Module:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="outputModule"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Output Latency:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QSlider" name="outputLatency">
<property name="minimum">
<number>10</number>
</property>
<property name="maximum">
<number>200</number>
</property>
<property name="value">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>200</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="outputLatencyLabel">
<property name="text">
<string>100 ms</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="outputLatencyMinimal">
<property name="text">
<string>Minimal</string>
</property>
</widget>
</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>
<item row="3" column="1">
<widget class="QLabel" name="latencySummary">
<property name="text">
<string>Maximum Latency:</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>

View File

@ -808,6 +808,7 @@ struct Pcsx2Config
static constexpr s32 MAX_OVERLAP = 15;
BITFIELD32()
bool OutputLatencyMinimal : 1;
bool
DebugEnabled : 1,
MsgToConsole : 1,
@ -831,6 +832,7 @@ struct Pcsx2Config
s32 FinalVolume = 100;
s32 Latency = 100;
s32 OutputLatency = 20;
s32 SpeakerConfiguration = 0;
s32 DplDecodingLevel = 0;
@ -854,6 +856,7 @@ struct Pcsx2Config
OpEqu(FinalVolume) &&
OpEqu(Latency) &&
OpEqu(OutputLatency) &&
OpEqu(SpeakerConfiguration) &&
OpEqu(DplDecodingLevel) &&

View File

@ -827,6 +827,8 @@ void Pcsx2Config::SPU2Options::LoadSave(SettingsWrapper& wrap)
SettingsWrapEntry(OutputModule);
SettingsWrapEntry(BackendName);
SettingsWrapEntry(Latency);
SettingsWrapEntry(OutputLatency);
SettingsWrapBitBool(OutputLatencyMinimal);
SynchMode = static_cast<SynchronizationMode>(wrap.EntryBitfield(CURRENT_SETTINGS_SECTION, "SynchMode", static_cast<int>(SynchMode), static_cast<int>(SynchMode)));
SettingsWrapEntry(SpeakerConfiguration);
SettingsWrapEntry(DplDecodingLevel);

View File

@ -34,9 +34,6 @@
class Cubeb : public SndOutModule
{
private:
static constexpr int MINIMUM_LATENCY_MS = 20;
static constexpr int MAXIMUM_LATENCY_MS = 200;
//////////////////////////////////////////////////////////////////////////////////////////
// Stuff necessary for speaker expansion
class SampleReader
@ -115,9 +112,6 @@ private:
#ifdef _WIN32
bool m_COMInitializedByUs = false;
#endif
bool m_SuggestedLatencyMinimal = false;
int m_SuggestedLatencyMS = 20;
std::string m_Backend;
//////////////////////////////////////////////////////////////////////////////////////////
// Instance vars
@ -142,10 +136,6 @@ public:
bool Init() override
{
ReadSettings();
// TODO(Stenzek): Migrate the errors to Host::ReportErrorAsync() once more Qt stuff is merged.
#ifdef _WIN32
HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
m_COMInitializedByUs = SUCCEEDED(hr);
@ -160,7 +150,8 @@ public:
cubeb_set_log_callback(CUBEB_LOG_NORMAL, LogCallback);
#endif
int rv = cubeb_init(&m_context, "PCSX2", m_Backend.empty() ? nullptr : m_Backend.c_str());
const std::string backend(Host::GetStringSettingValue("SPU2/Output", "BackendName", ""));
int rv = cubeb_init(&m_context, "PCSX2", backend.empty() ? nullptr : backend.c_str());
if (rv != CUBEB_OK)
{
Host::ReportFormattedErrorAsync("Cubeb Error", "Could not initialize cubeb context: %d", rv);
@ -248,13 +239,13 @@ public:
params.layout = layout;
params.prefs = CUBEB_STREAM_PREF_NONE;
const u32 requested_latency_frames = static_cast<u32>((m_SuggestedLatencyMS * static_cast<u32>(SampleRate)) / 1000u);
const u32 requested_latency_frames = static_cast<u32>((EmuConfig.SPU2.OutputLatency * SampleRate) / 1000u);
u32 latency_frames = 0;
rv = cubeb_get_min_latency(m_context, &params, &latency_frames);
if (rv == CUBEB_ERROR_NOT_SUPPORTED)
{
Console.WriteLn("(Cubeb) Cubeb backend does not support latency queries, using latency of %d ms (%u frames).",
m_SuggestedLatencyMS, requested_latency_frames);
EmuConfig.SPU2.OutputLatency, requested_latency_frames);
latency_frames = requested_latency_frames;
}
else
@ -268,7 +259,7 @@ public:
const float minimum_latency_ms = static_cast<float>(latency_frames * 1000u) / static_cast<float>(SampleRate);
Console.WriteLn("(Cubeb) Minimum latency: %.2f ms (%u audio frames)", minimum_latency_ms, latency_frames);
if (!m_SuggestedLatencyMinimal)
if (!EmuConfig.SPU2.OutputLatencyMinimal)
{
if (latency_frames > requested_latency_frames)
{
@ -362,13 +353,6 @@ public:
{
return cubeb_get_backend_names();
}
void ReadSettings()
{
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("SPU2/Output", "BackendName", "");
}
};
static Cubeb s_Cubeb;

View File

@ -395,6 +395,8 @@ void SPU2::CheckForConfigChanges(const Pcsx2Config& old_config)
// Things which require re-initialzing the output.
if (opts.Latency != oldopts.Latency ||
opts.OutputLatency != oldopts.OutputLatency ||
opts.OutputLatencyMinimal != oldopts.OutputLatencyMinimal ||
opts.SpeakerConfiguration != oldopts.SpeakerConfiguration ||
opts.DplDecodingLevel != oldopts.DplDecodingLevel ||
opts.SequenceLenMS != oldopts.SequenceLenMS ||