Qt: Implement (partial) audio settings

This commit is contained in:
Connor McLaughlin 2022-03-25 19:24:27 +10:00 committed by refractionpcsx2
parent fa36b9b5cb
commit 3dc6ae115f
4 changed files with 502 additions and 4 deletions

View File

@ -24,12 +24,93 @@
#include "SettingWidgetBinder.h"
#include "SettingsDialog.h"
static constexpr s32 DEFAULT_INTERPOLATION_MODE = 5;
static constexpr s32 DEFAULT_SYNCHRONIZATION_MODE = 0;
static constexpr s32 DEFAULT_EXPANSION_MODE = 0;
static const char* DEFAULT_OUTPUT_MODULE = "cubeb";
static constexpr s32 DEFAULT_OUTPUT_LATENCY = 100;
static constexpr s32 DEFAULT_VOLUME = 100;
static constexpr s32 DEFAULT_SOUNDTOUCH_SEQUENCE_LENGTH = 30;
static constexpr s32 DEFAULT_SOUNDTOUCH_SEEK_WINDOW = 20;
static constexpr s32 DEFAULT_SOUNDTOUCH_OVERLAP = 10;
static const char* s_output_module_entries[] = {
QT_TRANSLATE_NOOP("AudioSettingsWidget", "No Sound (Emulate SPU2 only)"),
QT_TRANSLATE_NOOP("AudioSettingsWidget", "Cubeb (Cross-platform)"),
#ifdef _WIN32
QT_TRANSLATE_NOOP("AudioSettingsWidget", "XAudio2"),
#endif
};
static const char* s_output_module_values[] = {
"nullout",
"cubeb",
#ifdef _WIN32
"xaudio2",
#endif
};
AudioSettingsWidget::AudioSettingsWidget(SettingsDialog* dialog, QWidget* parent)
: QWidget(parent)
{
// SettingsInterface* sif = dialog->getSettingsInterface();
SettingsInterface* sif = dialog->getSettingsInterface();
m_ui.setupUi(this);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.interpolation, "SPU2/Mixing", "Interpolation", DEFAULT_INTERPOLATION_MODE);
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::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.latency, &QSlider::valueChanged, this, &AudioSettingsWidget::updateLatencyLabel);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.volume, "SPU2/Mixing", "FinalVolume", DEFAULT_VOLUME);
connect(m_ui.volume, &QSlider::valueChanged, this, &AudioSettingsWidget::updateVolumeLabel);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.sequenceLength, "Soundtouch", "SequenceLengthMS", DEFAULT_SOUNDTOUCH_SEQUENCE_LENGTH);
connect(m_ui.sequenceLength, &QSlider::valueChanged, this, &AudioSettingsWidget::updateTimestretchSequenceLengthLabel);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.seekWindowSize, "Soundtouch", "SeekWindowMS", DEFAULT_SOUNDTOUCH_SEEK_WINDOW);
connect(m_ui.seekWindowSize, &QSlider::valueChanged, this, &AudioSettingsWidget::updateTimestretchSeekwindowLengthLabel);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.overlap, "Soundtouch", "OverlapMS", DEFAULT_SOUNDTOUCH_OVERLAP);
connect(m_ui.overlap, &QSlider::valueChanged, this, &AudioSettingsWidget::updateTimestretchOverlapLabel);
updateVolumeLabel();
updateLatencyLabel();
updateTimestretchSequenceLengthLabel();
updateTimestretchSeekwindowLengthLabel();
updateTimestretchOverlapLabel();
}
AudioSettingsWidget::~AudioSettingsWidget() = default;
void AudioSettingsWidget::updateVolumeLabel()
{
m_ui.volumeLabel->setText(tr("%1%").arg(m_ui.volume->value()));
}
void AudioSettingsWidget::updateLatencyLabel()
{
m_ui.latencyLabel->setText(tr("%1 ms (avg)").arg(m_ui.latency->value()));
}
void AudioSettingsWidget::updateTimestretchSequenceLengthLabel()
{
m_ui.sequenceLengthLabel->setText(tr("%1 ms").arg(m_ui.sequenceLength->value()));
}
void AudioSettingsWidget::updateTimestretchSeekwindowLengthLabel()
{
m_ui.seekWindowSizeLabel->setText(tr("%1 ms").arg(m_ui.seekWindowSize->value()));
}
void AudioSettingsWidget::updateTimestretchOverlapLabel()
{
m_ui.overlapLabel->setText(tr("%1 ms").arg(m_ui.overlap->value()));
}
void AudioSettingsWidget::resetTimestretchDefaults()
{
m_ui.sequenceLength->setValue(DEFAULT_SOUNDTOUCH_SEQUENCE_LENGTH);
m_ui.seekWindowSize->setValue(DEFAULT_SOUNDTOUCH_SEEK_WINDOW);
m_ui.overlap->setValue(DEFAULT_SOUNDTOUCH_OVERLAP);
}

View File

@ -29,6 +29,14 @@ public:
AudioSettingsWidget(SettingsDialog* dialog, QWidget* parent);
~AudioSettingsWidget();
private Q_SLOTS:
void updateVolumeLabel();
void updateLatencyLabel();
void updateTimestretchSequenceLengthLabel();
void updateTimestretchSeekwindowLengthLabel();
void updateTimestretchOverlapLabel();
void resetTimestretchDefaults();
private:
Ui::AudioSettingsWidget m_ui;
};

View File

@ -6,13 +6,421 @@
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
<width>752</width>
<height>430</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<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>
</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>
<property name="text">
<string>No Sound (Emulate SPU2 only)</string>
</property>
</item>
<item>
<property name="text">
<string>Cubeb (Cross-platform)</string>
</property>
</item>
<item>
<property name="text">
<string>XAudio2</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Latency:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QSlider" name="latency">
<property name="minimum">
<number>15</number>
</property>
<property name="maximum">
<number>3000</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>
</layout>
</widget>
</item>
<item row="2" column="0">
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Timestretch Settings</string>
</property>
<layout class="QFormLayout" name="formLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Sequence Length:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QSlider" name="sequenceLength">
<property name="minimum">
<number>20</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>10</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="sequenceLengthLabel">
<property name="text">
<string>100</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Seekwindow Size:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QSlider" name="seekWindowSize">
<property name="minimum">
<number>10</number>
</property>
<property name="maximum">
<number>30</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>2</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="seekWindowSizeLabel">
<property name="text">
<string>100</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Overlap:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QSlider" name="overlap">
<property name="minimum">
<number>5</number>
</property>
<property name="maximum">
<number>15</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>1</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="overlapLabel">
<property name="text">
<string>100</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="minimumSize">
<size>
<width>120</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Reset Defaults</string>
</property>
</widget>
</item>
</layout>
</item>
</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>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Volume</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QSlider" name="volume">
<property name="maximum">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBothSides</enum>
</property>
<property name="tickInterval">
<number>10</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="volumeLabel">
<property name="text">
<string>100%</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>

View File

@ -26,6 +26,7 @@
#include "SettingsDialog.h"
#include "AdvancedSystemSettingsWidget.h"
#include "AudioSettingsWidget.h"
#include "BIOSSettingsWidget.h"
#include "EmulationSettingsWidget.h"
#include "GameSummaryWidget.h"
@ -114,7 +115,7 @@ void SettingsDialog::setupUi(const GameList::Entry* game)
addWidget(m_graphics_settings = new GraphicsSettingsWidget(this, m_ui.settingsContainer), tr("Graphics"), QStringLiteral("brush-line"),
tr("<strong>Graphics Settings</strong><hr>"));
addWidget(new QWidget(m_ui.settingsContainer), tr("Audio"), QStringLiteral("volume-up-line"),
addWidget(m_audio_settings = new AudioSettingsWidget(this, m_ui.settingsContainer), tr("Audio"), QStringLiteral("volume-up-line"),
tr("<strong>Audio Settings</strong><hr>These options control the audio output of the console. Mouse over an option for additional "
"information."));
addWidget(