mirror of https://github.com/PCSX2/pcsx2.git
SPU2: Split output latency and target buffer size
This commit is contained in:
parent
c274e447dd
commit
0c8beedb94
|
@ -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()
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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/>
|
||||
|
|
|
@ -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) &&
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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, ¶ms, &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;
|
||||
|
|
|
@ -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 ||
|
||||
|
|
Loading…
Reference in New Issue