Implemented Citra Enhanced's realtime audio option

Co-authored-by: Gamer64ytb <76565986+Gamer64ytb@users.noreply.github.com>
This commit is contained in:
OpenSauce04 2024-05-16 12:33:00 +01:00 committed by OpenSauce
parent f1e0b5df60
commit d91334be84
17 changed files with 61 additions and 1 deletions

View File

@ -35,6 +35,7 @@ enum class IntSetting(
ASYNC_CUSTOM_LOADING("async_custom_loading", Settings.SECTION_UTILITY, 1), ASYNC_CUSTOM_LOADING("async_custom_loading", Settings.SECTION_UTILITY, 1),
PRELOAD_TEXTURES("preload_textures", Settings.SECTION_UTILITY, 0), PRELOAD_TEXTURES("preload_textures", Settings.SECTION_UTILITY, 0),
ENABLE_AUDIO_STRETCHING("enable_audio_stretching", Settings.SECTION_AUDIO, 1), ENABLE_AUDIO_STRETCHING("enable_audio_stretching", Settings.SECTION_AUDIO, 1),
ENABLE_REALTIME_AUDIO("enable_realtime_audio", Settings.SECTION_AUDIO, 0),
CPU_JIT("use_cpu_jit", Settings.SECTION_CORE, 1), CPU_JIT("use_cpu_jit", Settings.SECTION_CORE, 1),
HW_SHADER("use_hw_shader", Settings.SECTION_RENDERER, 1), HW_SHADER("use_hw_shader", Settings.SECTION_RENDERER, 1),
VSYNC("use_vsync_new", Settings.SECTION_RENDERER, 1), VSYNC("use_vsync_new", Settings.SECTION_RENDERER, 1),

View File

@ -859,6 +859,15 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
IntSetting.ENABLE_AUDIO_STRETCHING.defaultValue IntSetting.ENABLE_AUDIO_STRETCHING.defaultValue
) )
) )
add(
SwitchSetting(
IntSetting.ENABLE_REALTIME_AUDIO,
R.string.realtime_audio,
R.string.realtime_audio_description,
IntSetting.ENABLE_REALTIME_AUDIO.key,
IntSetting.ENABLE_REALTIME_AUDIO.defaultValue
)
)
add( add(
SingleChoiceSetting( SingleChoiceSetting(
IntSetting.AUDIO_INPUT_TYPE, IntSetting.AUDIO_INPUT_TYPE,

View File

@ -195,6 +195,7 @@ void Config::ReadValues() {
// Audio // Audio
ReadSetting("Audio", Settings::values.audio_emulation); ReadSetting("Audio", Settings::values.audio_emulation);
ReadSetting("Audio", Settings::values.enable_audio_stretching); ReadSetting("Audio", Settings::values.enable_audio_stretching);
ReadSetting("Audio", Settings::values.enable_realtime_audio);
ReadSetting("Audio", Settings::values.volume); ReadSetting("Audio", Settings::values.volume);
ReadSetting("Audio", Settings::values.output_type); ReadSetting("Audio", Settings::values.output_type);
ReadSetting("Audio", Settings::values.output_device); ReadSetting("Audio", Settings::values.output_device);

View File

@ -240,6 +240,10 @@ enable_dsp_lle_thread =
# 0: No, 1 (default): Yes # 0: No, 1 (default): Yes
enable_audio_stretching = enable_audio_stretching =
# Simulates the Nintendo 3DS audio for HLE
# 0 (default): No, 1: Yes
enable_realtime_audio =
# Output volume. # Output volume.
# 1.0 (default): 100%, 0.0; mute # 1.0 (default): 100%, 0.0; mute
volume = volume =

View File

@ -246,6 +246,8 @@ Se esperan fallos gráficos temporales cuando ésta esté activado.</string>
<string name="audio_volume">Volumen</string> <string name="audio_volume">Volumen</string>
<string name="audio_stretch">Extensión de Audio</string> <string name="audio_stretch">Extensión de Audio</string>
<string name="audio_stretch_description">Extiende el audio para reducir los parones. Cuando se active, la latencia de audio se incrementará y reducirá un poco el rendimiento.</string> <string name="audio_stretch_description">Extiende el audio para reducir los parones. Cuando se active, la latencia de audio se incrementará y reducirá un poco el rendimiento.</string>
<string name="realtime_audio">Activar audio en tiempo real</string>
<string name="realtime_audio_description">Simula el audio de la Nintendo 3DS para HLE, corrigiendo el retraso del audio cuando la velocidad es inferior al 100%. Podría causar problemas de desincronización del audio</string>
<string name="audio_input_type">Dispositivo de entrada de audio</string> <string name="audio_input_type">Dispositivo de entrada de audio</string>
<string name="sound_output_mode">Modo de salida del audio</string> <string name="sound_output_mode">Modo de salida del audio</string>

View File

@ -271,6 +271,8 @@
<string name="audio_volume">Volume</string> <string name="audio_volume">Volume</string>
<string name="audio_stretch">Audio Stretching</string> <string name="audio_stretch">Audio Stretching</string>
<string name="audio_stretch_description">Stretches audio to reduce stuttering. When enabled, increases audio latency and slightly reduces performance.</string> <string name="audio_stretch_description">Stretches audio to reduce stuttering. When enabled, increases audio latency and slightly reduces performance.</string>
<string name="realtime_audio">Enable real-time audio</string>
<string name="realtime_audio_description">Simulates the Nintendo 3DS audio for HLE, fixing audio lag when speed is lower from 100%. Might cause audio desync issues</string>
<string name="audio_input_type">Audio Input Device</string> <string name="audio_input_type">Audio Input Device</string>
<string name="sound_output_mode">Sound Output Mode</string> <string name="sound_output_mode">Sound Output Mode</string>

View File

@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version // Licensed under GPLv2 or any later version
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include <algorithm>
#include <boost/serialization/array.hpp> #include <boost/serialization/array.hpp>
#include <boost/serialization/base_object.hpp> #include <boost/serialization/base_object.hpp>
#include <boost/serialization/shared_ptr.hpp> #include <boost/serialization/shared_ptr.hpp>
@ -21,6 +23,7 @@
#include "common/common_types.h" #include "common/common_types.h"
#include "common/hash.h" #include "common/hash.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/settings.h"
#include "core/core.h" #include "core/core.h"
#include "core/core_timing.h" #include "core/core_timing.h"
@ -414,7 +417,12 @@ void DspHle::Impl::AudioTickCallback(s64 cycles_late) {
} }
// Reschedule recurrent event // Reschedule recurrent event
core_timing.ScheduleEvent(audio_frame_ticks - cycles_late, tick_event); const double time_scale =
Settings::values.enable_realtime_audio
? std::clamp(Core::System::GetInstance().GetLastFrameTimeScale(), 1.0, 3.0)
: 1.0;
s64 adjusted_ticks = static_cast<s64>(audio_frame_ticks / time_scale - cycles_late);
core_timing.ScheduleEvent(adjusted_ticks, tick_event);
} }
DspHle::DspHle(Core::System& system, Memory::MemorySystem& memory, Core::Timing& timing) DspHle::DspHle(Core::System& system, Memory::MemorySystem& memory, Core::Timing& timing)

View File

@ -121,6 +121,7 @@ void LogSettings() {
log_setting("Audio_InputType", values.input_type.GetValue()); log_setting("Audio_InputType", values.input_type.GetValue());
log_setting("Audio_InputDevice", values.input_device.GetValue()); log_setting("Audio_InputDevice", values.input_device.GetValue());
log_setting("Audio_EnableAudioStretching", values.enable_audio_stretching.GetValue()); log_setting("Audio_EnableAudioStretching", values.enable_audio_stretching.GetValue());
log_setting("Audio_EnableRealtime", values.enable_realtime_audio.GetValue());
using namespace Service::CAM; using namespace Service::CAM;
log_setting("Camera_OuterRightName", values.camera_name[OuterRightCamera]); log_setting("Camera_OuterRightName", values.camera_name[OuterRightCamera]);
log_setting("Camera_OuterRightConfig", values.camera_config[OuterRightCamera]); log_setting("Camera_OuterRightConfig", values.camera_config[OuterRightCamera]);
@ -171,6 +172,7 @@ void RestoreGlobalState(bool is_powered_on) {
// Audio // Audio
values.audio_emulation.SetGlobal(true); values.audio_emulation.SetGlobal(true);
values.enable_audio_stretching.SetGlobal(true); values.enable_audio_stretching.SetGlobal(true);
values.enable_realtime_audio.SetGlobal(true);
values.volume.SetGlobal(true); values.volume.SetGlobal(true);
// Core // Core

View File

@ -521,6 +521,7 @@ struct Values {
bool audio_muted; bool audio_muted;
SwitchableSetting<AudioEmulation> audio_emulation{AudioEmulation::HLE, "audio_emulation"}; SwitchableSetting<AudioEmulation> audio_emulation{AudioEmulation::HLE, "audio_emulation"};
SwitchableSetting<bool> enable_audio_stretching{true, "enable_audio_stretching"}; SwitchableSetting<bool> enable_audio_stretching{true, "enable_audio_stretching"};
SwitchableSetting<bool> enable_realtime_audio{false, "enable_realtime_audio"};
SwitchableSetting<float, true> volume{1.f, 0.f, 1.f, "volume"}; SwitchableSetting<float, true> volume{1.f, 0.f, 1.f, "volume"};
Setting<AudioCore::SinkType> output_type{AudioCore::SinkType::Auto, "output_type"}; Setting<AudioCore::SinkType> output_type{AudioCore::SinkType::Auto, "output_type"};
Setting<std::string> output_device{"auto", "output_device"}; Setting<std::string> output_device{"auto", "output_device"};

View File

@ -392,6 +392,10 @@ PerfStats::Results System::GetLastPerfStats() {
return perf_stats ? perf_stats->GetLastStats() : PerfStats::Results{}; return perf_stats ? perf_stats->GetLastStats() : PerfStats::Results{};
} }
double System::GetLastFrameTimeScale() {
return perf_stats->GetLastFrameTimeScale();
}
void System::Reschedule() { void System::Reschedule() {
if (!reschedule_pending) { if (!reschedule_pending) {
return; return;

View File

@ -193,6 +193,8 @@ public:
[[nodiscard]] PerfStats::Results GetLastPerfStats(); [[nodiscard]] PerfStats::Results GetLastPerfStats();
double GetLastFrameTimeScale();
/** /**
* Gets a reference to the emulated CPU. * Gets a reference to the emulated CPU.
* @returns A reference to the emulated CPU. * @returns A reference to the emulated CPU.

View File

@ -184,6 +184,7 @@ void Config::ReadValues() {
// Audio // Audio
ReadSetting("Audio", Settings::values.audio_emulation); ReadSetting("Audio", Settings::values.audio_emulation);
ReadSetting("Audio", Settings::values.enable_audio_stretching); ReadSetting("Audio", Settings::values.enable_audio_stretching);
ReadSetting("Audio", Settings::values.enable_realtime_audio);
ReadSetting("Audio", Settings::values.volume); ReadSetting("Audio", Settings::values.volume);
ReadSetting("Audio", Settings::values.output_type); ReadSetting("Audio", Settings::values.output_type);
ReadSetting("Audio", Settings::values.output_device); ReadSetting("Audio", Settings::values.output_device);

View File

@ -252,6 +252,10 @@ enable_dsp_lle_thread =
# 0: No, 1 (default): Yes # 0: No, 1 (default): Yes
enable_audio_stretching = enable_audio_stretching =
# Simulates the Nintendo 3DS audio for HLE
# 0 (default): No, 1: Yes
enable_realtime_audio =
# Output volume. # Output volume.
# 1.0 (default): 100%, 0.0; mute # 1.0 (default): 100%, 0.0; mute
volume = volume =

View File

@ -278,6 +278,7 @@ void Config::ReadAudioValues() {
ReadGlobalSetting(Settings::values.audio_emulation); ReadGlobalSetting(Settings::values.audio_emulation);
ReadGlobalSetting(Settings::values.enable_audio_stretching); ReadGlobalSetting(Settings::values.enable_audio_stretching);
ReadGlobalSetting(Settings::values.enable_realtime_audio);
ReadGlobalSetting(Settings::values.volume); ReadGlobalSetting(Settings::values.volume);
if (global) { if (global) {
@ -885,6 +886,7 @@ void Config::SaveAudioValues() {
WriteGlobalSetting(Settings::values.audio_emulation); WriteGlobalSetting(Settings::values.audio_emulation);
WriteGlobalSetting(Settings::values.enable_audio_stretching); WriteGlobalSetting(Settings::values.enable_audio_stretching);
WriteGlobalSetting(Settings::values.enable_realtime_audio);
WriteGlobalSetting(Settings::values.volume); WriteGlobalSetting(Settings::values.volume);
if (global) { if (global) {

View File

@ -64,6 +64,7 @@ void ConfigureAudio::SetConfiguration() {
SetInputDeviceFromDeviceID(); SetInputDeviceFromDeviceID();
ui->toggle_audio_stretching->setChecked(Settings::values.enable_audio_stretching.GetValue()); ui->toggle_audio_stretching->setChecked(Settings::values.enable_audio_stretching.GetValue());
ui->toggle_realtime_audio->setChecked(Settings::values.enable_realtime_audio.GetValue());
const s32 volume = const s32 volume =
static_cast<s32>(Settings::values.volume.GetValue() * ui->volume_slider->maximum()); static_cast<s32>(Settings::values.volume.GetValue() * ui->volume_slider->maximum());
@ -155,6 +156,8 @@ void ConfigureAudio::SetVolumeIndicatorText(int percentage) {
void ConfigureAudio::ApplyConfiguration() { void ConfigureAudio::ApplyConfiguration() {
ConfigurationShared::ApplyPerGameSetting(&Settings::values.enable_audio_stretching, ConfigurationShared::ApplyPerGameSetting(&Settings::values.enable_audio_stretching,
ui->toggle_audio_stretching, audio_stretching); ui->toggle_audio_stretching, audio_stretching);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.enable_realtime_audio,
ui->toggle_realtime_audio, realtime_audio);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.audio_emulation, ConfigurationShared::ApplyPerGameSetting(&Settings::values.audio_emulation,
ui->emulation_combo_box); ui->emulation_combo_box);
ConfigurationShared::ApplyPerGameSetting( ConfigurationShared::ApplyPerGameSetting(
@ -235,4 +238,7 @@ void ConfigureAudio::SetupPerGameUI() {
ConfigurationShared::SetColoredTristate( ConfigurationShared::SetColoredTristate(
ui->toggle_audio_stretching, Settings::values.enable_audio_stretching, audio_stretching); ui->toggle_audio_stretching, Settings::values.enable_audio_stretching, audio_stretching);
ConfigurationShared::SetColoredTristate(ui->toggle_realtime_audio,
Settings::values.enable_realtime_audio, realtime_audio);
} }

View File

@ -39,5 +39,6 @@ private:
void SetupPerGameUI(); void SetupPerGameUI();
ConfigurationShared::CheckState audio_stretching; ConfigurationShared::CheckState audio_stretching;
ConfigurationShared::CheckState realtime_audio;
std::unique_ptr<Ui::ConfigureAudio> ui; std::unique_ptr<Ui::ConfigureAudio> ui;
}; };

View File

@ -95,6 +95,16 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QCheckBox" name="toggle_realtime_audio">
<property name="toolTip">
<string>Simulates the Nintendo 3DS audio for HLE, fixing audio lag when speed is lower from 100%. Might cause audio desync issues</string>
</property>
<property name="text">
<string>Enable real-time audio</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QWidget" name="volume_layout" native="true"> <widget class="QWidget" name="volume_layout" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="horizontalLayout_2">