AudioStream: Rewrite and integrate expander

This commit is contained in:
Stenzek
2024-09-01 13:16:10 +10:00
parent 14ab642ff3
commit 3fbdcdb4ff
23 changed files with 190 additions and 2645 deletions

View File

@@ -24,12 +24,6 @@ AudioSettingsWidget::AudioSettingsWidget(SettingsWindow* dialog, QWidget* parent
for (u32 i = 0; i < static_cast<u32>(AudioBackend::Count); i++)
m_ui.audioBackend->addItem(QString::fromUtf8(AudioStream::GetBackendDisplayName(static_cast<AudioBackend>(i))));
for (u32 i = 0; i < static_cast<u32>(AudioExpansionMode::Count); i++)
{
m_ui.expansionMode->addItem(
QString::fromUtf8(AudioStream::GetExpansionModeDisplayName(static_cast<AudioExpansionMode>(i))));
}
for (u32 i = 0; i < static_cast<u32>(AudioStretchMode::Count); i++)
{
m_ui.stretchMode->addItem(
@@ -39,9 +33,6 @@ AudioSettingsWidget::AudioSettingsWidget(SettingsWindow* dialog, QWidget* parent
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.audioBackend, "Audio", "Backend",
&AudioStream::ParseBackendName, &AudioStream::GetBackendName,
AudioStream::DEFAULT_BACKEND);
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.expansionMode, "Audio", "ExpansionMode",
&AudioStream::ParseExpansionMode, &AudioStream::GetExpansionModeName,
AudioStreamParameters::DEFAULT_EXPANSION_MODE);
SettingWidgetBinder::BindWidgetToEnumSetting(sif, m_ui.stretchMode, "Audio", "StretchMode",
&AudioStream::ParseStretchMode, &AudioStream::GetStretchModeName,
AudioStreamParameters::DEFAULT_STRETCH_MODE);
@@ -53,11 +44,8 @@ AudioSettingsWidget::AudioSettingsWidget(SettingsWindow* dialog, QWidget* parent
AudioStreamParameters::DEFAULT_OUTPUT_LATENCY_MINIMAL);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.muteCDAudio, "CDROM", "MuteCDAudio", false);
connect(m_ui.audioBackend, &QComboBox::currentIndexChanged, this, &AudioSettingsWidget::updateDriverNames);
connect(m_ui.expansionMode, &QComboBox::currentIndexChanged, this, &AudioSettingsWidget::onExpansionModeChanged);
connect(m_ui.expansionSettings, &QToolButton::clicked, this, &AudioSettingsWidget::onExpansionSettingsClicked);
connect(m_ui.stretchMode, &QComboBox::currentIndexChanged, this, &AudioSettingsWidget::onStretchModeChanged);
connect(m_ui.stretchSettings, &QToolButton::clicked, this, &AudioSettingsWidget::onStretchSettingsClicked);
onExpansionModeChanged();
onStretchModeChanged();
updateDriverNames();
@@ -109,11 +97,6 @@ AudioSettingsWidget::AudioSettingsWidget(SettingsWindow* dialog, QWidget* parent
dialog->registerWidgetHelp(m_ui.muteCDAudio, tr("Mute CD Audio"), tr("Unchecked"),
tr("Forcibly mutes both CD-DA and XA audio from the CD-ROM. Can be used to disable "
"background music in some games."));
dialog->registerWidgetHelp(m_ui.expansionMode, tr("Expansion Mode"), tr("Disabled (Stereo)"),
tr("Determines how audio is expanded from stereo to surround for supported games. This "
"includes games that support Dolby Pro Logic/Pro Logic II."));
dialog->registerWidgetHelp(m_ui.expansionSettings, tr("Expansion Settings"), tr("N/A"),
tr("These settings fine-tune the behavior of the FreeSurround-based channel expander."));
dialog->registerWidgetHelp(
m_ui.stretchMode, tr("Stretch Mode"), tr("Time Stretching"),
tr("When running outside of 100% speed, adjusts the tempo on audio instead of dropping frames. Produces "
@@ -131,34 +114,6 @@ AudioSettingsWidget::AudioSettingsWidget(SettingsWindow* dialog, QWidget* parent
AudioSettingsWidget::~AudioSettingsWidget() = default;
AudioExpansionMode AudioSettingsWidget::getEffectiveExpansionMode() const
{
return AudioStream::ParseExpansionMode(
m_dialog
->getEffectiveStringValue("Audio", "ExpansionMode",
AudioStream::GetExpansionModeName(AudioStreamParameters::DEFAULT_EXPANSION_MODE))
.c_str())
.value_or(AudioStreamParameters::DEFAULT_EXPANSION_MODE);
}
u32 AudioSettingsWidget::getEffectiveExpansionBlockSize() const
{
const AudioExpansionMode expansion_mode = getEffectiveExpansionMode();
if (expansion_mode == AudioExpansionMode::Disabled)
return 0;
const u32 config_block_size =
m_dialog->getEffectiveIntValue("Audio", "ExpandBlockSize", AudioStreamParameters::DEFAULT_EXPAND_BLOCK_SIZE);
return std::has_single_bit(config_block_size) ? config_block_size : std::bit_ceil(config_block_size);
}
void AudioSettingsWidget::onExpansionModeChanged()
{
const AudioExpansionMode expansion_mode = getEffectiveExpansionMode();
m_ui.expansionSettings->setEnabled(expansion_mode != AudioExpansionMode::Disabled);
updateLatencyLabel();
}
void AudioSettingsWidget::onStretchModeChanged()
{
const AudioStretchMode stretch_mode =
@@ -253,7 +208,6 @@ void AudioSettingsWidget::updateDeviceNames()
void AudioSettingsWidget::updateLatencyLabel()
{
const u32 expand_buffer_ms = AudioStream::GetMSForBufferSize(SPU::SAMPLE_RATE, getEffectiveExpansionBlockSize());
const u32 config_buffer_ms =
m_dialog->getEffectiveIntValue("Audio", "BufferMS", AudioStreamParameters::DEFAULT_BUFFER_MS);
const u32 config_output_latency_ms =
@@ -270,34 +224,14 @@ void AudioSettingsWidget::updateLatencyLabel()
config_output_latency_ms;
if (output_latency_ms > 0)
{
if (expand_buffer_ms > 0)
{
m_ui.bufferingLabel->setText(tr("Maximum Latency: %1 ms (%2 ms buffer + %3 ms expand + %4 ms output)")
.arg(config_buffer_ms + expand_buffer_ms + output_latency_ms)
.arg(config_buffer_ms)
.arg(expand_buffer_ms)
.arg(output_latency_ms));
}
else
{
m_ui.bufferingLabel->setText(tr("Maximum Latency: %1 ms (%2 ms buffer + %3 ms output)")
.arg(config_buffer_ms + output_latency_ms)
.arg(config_buffer_ms)
.arg(output_latency_ms));
}
m_ui.bufferingLabel->setText(tr("Maximum Latency: %1 ms (%2 ms buffer + %3 ms output)")
.arg(config_buffer_ms + output_latency_ms)
.arg(config_buffer_ms)
.arg(output_latency_ms));
}
else
{
if (expand_buffer_ms > 0)
{
m_ui.bufferingLabel->setText(tr("Maximum Latency: %1 ms (%2 ms expand, minimum output latency unknown)")
.arg(expand_buffer_ms + config_buffer_ms)
.arg(expand_buffer_ms));
}
else
{
m_ui.bufferingLabel->setText(tr("Maximum Latency: %1 ms (minimum output latency unknown)").arg(config_buffer_ms));
}
m_ui.bufferingLabel->setText(tr("Maximum Latency: %1 ms (minimum output latency unknown)").arg(config_buffer_ms));
}
}
@@ -347,95 +281,6 @@ void AudioSettingsWidget::onOutputMutedChanged(int new_state)
g_emu_thread->setAudioOutputMuted(muted);
}
void AudioSettingsWidget::onExpansionSettingsClicked()
{
QDialog dlg(QtUtils::GetRootWidget(this));
Ui::AudioExpansionSettingsDialog dlgui;
dlgui.setupUi(&dlg);
dlgui.icon->setPixmap(QIcon::fromTheme(QStringLiteral("volume-up-line")).pixmap(32, 32));
SettingsInterface* sif = m_dialog->getSettingsInterface();
SettingWidgetBinder::BindWidgetToIntSetting(sif, dlgui.blockSize, "Audio", "ExpandBlockSize",
AudioStreamParameters::DEFAULT_EXPAND_BLOCK_SIZE, 0);
QtUtils::BindLabelToSlider(dlgui.blockSize, dlgui.blockSizeLabel);
SettingWidgetBinder::BindWidgetToFloatSetting(sif, dlgui.circularWrap, "Audio", "ExpandCircularWrap",
AudioStreamParameters::DEFAULT_EXPAND_CIRCULAR_WRAP);
QtUtils::BindLabelToSlider(dlgui.circularWrap, dlgui.circularWrapLabel);
SettingWidgetBinder::BindWidgetToNormalizedSetting(sif, dlgui.shift, "Audio", "ExpandShift", 100.0f,
AudioStreamParameters::DEFAULT_EXPAND_SHIFT);
QtUtils::BindLabelToSlider(dlgui.shift, dlgui.shiftLabel, 100.0f);
SettingWidgetBinder::BindWidgetToNormalizedSetting(sif, dlgui.depth, "Audio", "ExpandDepth", 10.0f,
AudioStreamParameters::DEFAULT_EXPAND_DEPTH);
QtUtils::BindLabelToSlider(dlgui.depth, dlgui.depthLabel, 10.0f);
SettingWidgetBinder::BindWidgetToNormalizedSetting(sif, dlgui.focus, "Audio", "ExpandFocus", 100.0f,
AudioStreamParameters::DEFAULT_EXPAND_FOCUS);
QtUtils::BindLabelToSlider(dlgui.focus, dlgui.focusLabel, 100.0f);
SettingWidgetBinder::BindWidgetToNormalizedSetting(sif, dlgui.centerImage, "Audio", "ExpandCenterImage", 100.0f,
AudioStreamParameters::DEFAULT_EXPAND_CENTER_IMAGE);
QtUtils::BindLabelToSlider(dlgui.centerImage, dlgui.centerImageLabel, 100.0f);
SettingWidgetBinder::BindWidgetToNormalizedSetting(sif, dlgui.frontSeparation, "Audio", "ExpandFrontSeparation",
10.0f, AudioStreamParameters::DEFAULT_EXPAND_FRONT_SEPARATION);
QtUtils::BindLabelToSlider(dlgui.frontSeparation, dlgui.frontSeparationLabel, 10.0f);
SettingWidgetBinder::BindWidgetToNormalizedSetting(sif, dlgui.rearSeparation, "Audio", "ExpandRearSeparation", 10.0f,
AudioStreamParameters::DEFAULT_EXPAND_REAR_SEPARATION);
QtUtils::BindLabelToSlider(dlgui.rearSeparation, dlgui.rearSeparationLabel, 10.0f);
SettingWidgetBinder::BindWidgetToIntSetting(sif, dlgui.lowCutoff, "Audio", "ExpandLowCutoff",
AudioStreamParameters::DEFAULT_EXPAND_LOW_CUTOFF);
QtUtils::BindLabelToSlider(dlgui.lowCutoff, dlgui.lowCutoffLabel);
SettingWidgetBinder::BindWidgetToIntSetting(sif, dlgui.highCutoff, "Audio", "ExpandHighCutoff",
AudioStreamParameters::DEFAULT_EXPAND_HIGH_CUTOFF);
QtUtils::BindLabelToSlider(dlgui.highCutoff, dlgui.highCutoffLabel);
connect(dlgui.buttonBox->button(QDialogButtonBox::Close), &QPushButton::clicked, &dlg, &QDialog::accept);
connect(dlgui.buttonBox->button(QDialogButtonBox::RestoreDefaults), &QPushButton::clicked, this, [this, &dlg]() {
m_dialog->setIntSettingValue("Audio", "ExpandBlockSize",
m_dialog->isPerGameSettings() ?
std::nullopt :
std::optional<int>(AudioStreamParameters::DEFAULT_EXPAND_BLOCK_SIZE));
m_dialog->setFloatSettingValue("Audio", "ExpandCircularWrap",
m_dialog->isPerGameSettings() ?
std::nullopt :
std::optional<float>(AudioStreamParameters::DEFAULT_EXPAND_CIRCULAR_WRAP));
m_dialog->setFloatSettingValue(
"Audio", "ExpandShift",
m_dialog->isPerGameSettings() ? std::nullopt : std::optional<float>(AudioStreamParameters::DEFAULT_EXPAND_SHIFT));
m_dialog->setFloatSettingValue(
"Audio", "ExpandDepth",
m_dialog->isPerGameSettings() ? std::nullopt : std::optional<float>(AudioStreamParameters::DEFAULT_EXPAND_DEPTH));
m_dialog->setFloatSettingValue(
"Audio", "ExpandFocus",
m_dialog->isPerGameSettings() ? std::nullopt : std::optional<float>(AudioStreamParameters::DEFAULT_EXPAND_FOCUS));
m_dialog->setFloatSettingValue("Audio", "ExpandCenterImage",
m_dialog->isPerGameSettings() ?
std::nullopt :
std::optional<float>(AudioStreamParameters::DEFAULT_EXPAND_CENTER_IMAGE));
m_dialog->setFloatSettingValue("Audio", "ExpandFrontSeparation",
m_dialog->isPerGameSettings() ?
std::nullopt :
std::optional<float>(AudioStreamParameters::DEFAULT_EXPAND_FRONT_SEPARATION));
m_dialog->setFloatSettingValue("Audio", "ExpandRearSeparation",
m_dialog->isPerGameSettings() ?
std::nullopt :
std::optional<float>(AudioStreamParameters::DEFAULT_EXPAND_REAR_SEPARATION));
m_dialog->setIntSettingValue("Audio", "ExpandLowCutoff",
m_dialog->isPerGameSettings() ?
std::nullopt :
std::optional<int>(AudioStreamParameters::DEFAULT_EXPAND_LOW_CUTOFF));
m_dialog->setIntSettingValue("Audio", "ExpandHighCutoff",
m_dialog->isPerGameSettings() ?
std::nullopt :
std::optional<int>(AudioStreamParameters::DEFAULT_EXPAND_HIGH_CUTOFF));
dlg.done(0);
QMetaObject::invokeMethod(this, &AudioSettingsWidget::onExpansionSettingsClicked, Qt::QueuedConnection);
});
dlg.exec();
updateLatencyLabel();
}
void AudioSettingsWidget::onStretchSettingsClicked()
{
QDialog dlg(QtUtils::GetRootWidget(this));

View File

@@ -10,7 +10,6 @@
#include <QtWidgets/QWidget>
enum class AudioBackend : u8;
enum class AudioExpansionMode : u8;
class SettingsWindow;
@@ -23,7 +22,6 @@ public:
~AudioSettingsWidget();
private Q_SLOTS:
void onExpansionModeChanged();
void onStretchModeChanged();
void updateDriverNames();
@@ -35,13 +33,10 @@ private Q_SLOTS:
void onFastForwardVolumeChanged(int new_value);
void onOutputMutedChanged(int new_state);
void onExpansionSettingsClicked();
void onStretchSettingsClicked();
private:
AudioBackend getEffectiveBackend() const;
AudioExpansionMode getEffectiveExpansionMode() const;
u32 getEffectiveExpansionBlockSize() const;
void resetVolume(bool fast_forward);
Ui::AudioSettingsWidget m_ui;

View File

@@ -29,51 +29,17 @@
<string>Configuration</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="5" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Output Latency:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="outputDevice"/>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="audioBackend"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Driver:</string>
</property>
</widget>
</item>
<item row="7" column="0" colspan="2">
<widget class="QLabel" name="bufferingLabel">
<property name="text">
<string>Maximum latency: 0 frames (0.00ms)</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Backend:</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Stretch Mode:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Output Device:</string>
</property>
</widget>
</item>
<item row="6" column="1">
<item row="5" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QSlider" name="outputLatencyMS">
@@ -113,62 +79,21 @@
<item row="1" column="1">
<widget class="QComboBox" name="driver"/>
</item>
<item row="5" column="0">
<item row="3" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Stretch Mode:</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Buffer Size:</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Expansion Mode:</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Output Latency:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_5" stretch="1,0">
<item>
<widget class="QComboBox" name="expansionMode"/>
</item>
<item>
<widget class="QToolButton" name="expansionSettings">
<property name="toolTip">
<string>Expansion Settings</string>
</property>
<property name="icon">
<iconset theme="settings-3-line"/>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_6" stretch="1,0">
<item>
<widget class="QComboBox" name="stretchMode"/>
</item>
<item>
<widget class="QToolButton" name="stretchSettings">
<property name="toolTip">
<string>Stretch Settings</string>
</property>
<property name="icon">
<iconset theme="settings-3-line"/>
</property>
</widget>
</item>
</layout>
</item>
<item row="5" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_4" stretch="1,0">
<item>
<widget class="QSlider" name="bufferMS">
@@ -207,6 +132,57 @@
</item>
</layout>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_6" stretch="1,0">
<item>
<widget class="QComboBox" name="stretchMode"/>
</item>
<item>
<widget class="QToolButton" name="stretchSettings">
<property name="toolTip">
<string>Stretch Settings</string>
</property>
<property name="icon">
<iconset theme="settings-3-line"/>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Output Device:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="audioBackend"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Driver:</string>
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<widget class="QLabel" name="bufferingLabel">
<property name="text">
<string>Maximum latency: 0 frames (0.00ms)</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Backend:</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@@ -365,7 +341,7 @@
</layout>
</widget>
<resources>
<include location="resources/resources.qrc"/>
<include location="resources/duckstation-qt.qrc"/>
</resources>
<connections/>
</ui>