diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/IntSetting.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/IntSetting.kt
index 9b7981648..4c41eec6d 100644
--- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/IntSetting.kt
+++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/IntSetting.kt
@@ -36,6 +36,7 @@ enum class IntSetting(
ASYNC_CUSTOM_LOADING("async_custom_loading", Settings.SECTION_UTILITY, 1),
PRELOAD_TEXTURES("preload_textures", Settings.SECTION_UTILITY, 0),
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),
HW_SHADER("use_hw_shader", Settings.SECTION_RENDERER, 1),
VSYNC("use_vsync_new", Settings.SECTION_RENDERER, 1),
diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragmentPresenter.kt
index 93df469e3..ce10e0056 100644
--- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragmentPresenter.kt
+++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragmentPresenter.kt
@@ -898,6 +898,15 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
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(
SingleChoiceSetting(
IntSetting.AUDIO_INPUT_TYPE,
diff --git a/src/android/app/src/main/jni/config.cpp b/src/android/app/src/main/jni/config.cpp
index 9715a6f80..03b1a313c 100644
--- a/src/android/app/src/main/jni/config.cpp
+++ b/src/android/app/src/main/jni/config.cpp
@@ -198,6 +198,7 @@ void Config::ReadValues() {
// Audio
ReadSetting("Audio", Settings::values.audio_emulation);
ReadSetting("Audio", Settings::values.enable_audio_stretching);
+ ReadSetting("Audio", Settings::values.enable_realtime_audio);
ReadSetting("Audio", Settings::values.volume);
ReadSetting("Audio", Settings::values.output_type);
ReadSetting("Audio", Settings::values.output_device);
diff --git a/src/android/app/src/main/jni/default_ini.h b/src/android/app/src/main/jni/default_ini.h
index 78c76f846..5a53227ed 100644
--- a/src/android/app/src/main/jni/default_ini.h
+++ b/src/android/app/src/main/jni/default_ini.h
@@ -247,6 +247,10 @@ enable_dsp_lle_thread =
# 0: No, 1 (default): Yes
enable_audio_stretching =
+# Simulates the Nintendo 3DS audio for HLE
+# 0 (default): No, 1: Yes
+enable_realtime_audio =
+
# Output volume.
# 1.0 (default): 100%, 0.0; mute
volume =
diff --git a/src/android/app/src/main/res/values-es/strings.xml b/src/android/app/src/main/res/values-es/strings.xml
index 0cbc197db..73ba58d9d 100644
--- a/src/android/app/src/main/res/values-es/strings.xml
+++ b/src/android/app/src/main/res/values-es/strings.xml
@@ -246,6 +246,8 @@ Se esperan fallos gráficos temporales cuando ésta esté activado.
Volumen
Extensión de Audio
Extiende el audio para reducir los parones. Cuando se active, la latencia de audio se incrementará y reducirá un poco el rendimiento.
+ Activar audio en tiempo real
+ 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
Dispositivo de entrada de audio
Modo de salida del audio
diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml
index 16f4b4578..690c2fc37 100644
--- a/src/android/app/src/main/res/values/strings.xml
+++ b/src/android/app/src/main/res/values/strings.xml
@@ -281,6 +281,8 @@
Volume
Audio Stretching
Stretches audio to reduce stuttering. When enabled, increases audio latency and slightly reduces performance.
+ Enable real-time audio
+ Simulates the Nintendo 3DS audio for HLE, fixing audio lag when speed is lower from 100%. Might cause audio desync issues
Audio Input Device
Sound Output Mode
diff --git a/src/audio_core/hle/hle.cpp b/src/audio_core/hle/hle.cpp
index 9d5277504..108d5e2ca 100644
--- a/src/audio_core/hle/hle.cpp
+++ b/src/audio_core/hle/hle.cpp
@@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include
+
#include
#include
#include
@@ -21,6 +23,7 @@
#include "common/common_types.h"
#include "common/hash.h"
#include "common/logging/log.h"
+#include "common/settings.h"
#include "core/core.h"
#include "core/core_timing.h"
@@ -414,7 +417,12 @@ void DspHle::Impl::AudioTickCallback(s64 cycles_late) {
}
// 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(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)
diff --git a/src/citra/config.cpp b/src/citra/config.cpp
index f4806f231..41d86960b 100644
--- a/src/citra/config.cpp
+++ b/src/citra/config.cpp
@@ -186,6 +186,7 @@ void Config::ReadValues() {
// Audio
ReadSetting("Audio", Settings::values.audio_emulation);
ReadSetting("Audio", Settings::values.enable_audio_stretching);
+ ReadSetting("Audio", Settings::values.enable_realtime_audio);
ReadSetting("Audio", Settings::values.volume);
ReadSetting("Audio", Settings::values.output_type);
ReadSetting("Audio", Settings::values.output_device);
diff --git a/src/citra/default_ini.h b/src/citra/default_ini.h
index 28eea5762..c47345a8f 100644
--- a/src/citra/default_ini.h
+++ b/src/citra/default_ini.h
@@ -252,6 +252,10 @@ enable_dsp_lle_thread =
# 0: No, 1 (default): Yes
enable_audio_stretching =
+# Simulates the Nintendo 3DS audio for HLE
+# 0 (default): No, 1: Yes
+enable_realtime_audio =
+
# Output volume.
# 1.0 (default): 100%, 0.0; mute
volume =
diff --git a/src/citra_qt/configuration/config.cpp b/src/citra_qt/configuration/config.cpp
index 7b9a7f92f..137d7e841 100644
--- a/src/citra_qt/configuration/config.cpp
+++ b/src/citra_qt/configuration/config.cpp
@@ -278,6 +278,7 @@ void Config::ReadAudioValues() {
ReadGlobalSetting(Settings::values.audio_emulation);
ReadGlobalSetting(Settings::values.enable_audio_stretching);
+ ReadGlobalSetting(Settings::values.enable_realtime_audio);
ReadGlobalSetting(Settings::values.volume);
if (global) {
@@ -892,6 +893,7 @@ void Config::SaveAudioValues() {
WriteGlobalSetting(Settings::values.audio_emulation);
WriteGlobalSetting(Settings::values.enable_audio_stretching);
+ WriteGlobalSetting(Settings::values.enable_realtime_audio);
WriteGlobalSetting(Settings::values.volume);
if (global) {
diff --git a/src/citra_qt/configuration/configure_audio.cpp b/src/citra_qt/configuration/configure_audio.cpp
index bf301d41e..8c91cbb06 100644
--- a/src/citra_qt/configuration/configure_audio.cpp
+++ b/src/citra_qt/configuration/configure_audio.cpp
@@ -64,6 +64,7 @@ void ConfigureAudio::SetConfiguration() {
SetInputDeviceFromDeviceID();
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 =
static_cast(Settings::values.volume.GetValue() * ui->volume_slider->maximum());
@@ -155,6 +156,8 @@ void ConfigureAudio::SetVolumeIndicatorText(int percentage) {
void ConfigureAudio::ApplyConfiguration() {
ConfigurationShared::ApplyPerGameSetting(&Settings::values.enable_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,
ui->emulation_combo_box);
ConfigurationShared::ApplyPerGameSetting(
@@ -235,4 +238,7 @@ void ConfigureAudio::SetupPerGameUI() {
ConfigurationShared::SetColoredTristate(
ui->toggle_audio_stretching, Settings::values.enable_audio_stretching, audio_stretching);
+
+ ConfigurationShared::SetColoredTristate(ui->toggle_realtime_audio,
+ Settings::values.enable_realtime_audio, realtime_audio);
}
diff --git a/src/citra_qt/configuration/configure_audio.h b/src/citra_qt/configuration/configure_audio.h
index 001d574ed..b732d79fc 100644
--- a/src/citra_qt/configuration/configure_audio.h
+++ b/src/citra_qt/configuration/configure_audio.h
@@ -39,5 +39,6 @@ private:
void SetupPerGameUI();
ConfigurationShared::CheckState audio_stretching;
+ ConfigurationShared::CheckState realtime_audio;
std::unique_ptr ui;
};
diff --git a/src/citra_qt/configuration/configure_audio.ui b/src/citra_qt/configuration/configure_audio.ui
index 63df78c5a..60c31a352 100644
--- a/src/citra_qt/configuration/configure_audio.ui
+++ b/src/citra_qt/configuration/configure_audio.ui
@@ -95,6 +95,16 @@
+ -
+
+
+ Simulates the Nintendo 3DS audio for HLE, fixing audio lag when speed is lower from 100%. Might cause audio desync issues
+
+
+ Enable real-time audio
+
+
+
-
diff --git a/src/common/settings.cpp b/src/common/settings.cpp
index 833901a73..7afbfe8ab 100644
--- a/src/common/settings.cpp
+++ b/src/common/settings.cpp
@@ -123,6 +123,7 @@ void LogSettings() {
log_setting("Audio_InputType", values.input_type.GetValue());
log_setting("Audio_InputDevice", values.input_device.GetValue());
log_setting("Audio_EnableAudioStretching", values.enable_audio_stretching.GetValue());
+ log_setting("Audio_EnableRealtime", values.enable_realtime_audio.GetValue());
using namespace Service::CAM;
log_setting("Camera_OuterRightName", values.camera_name[OuterRightCamera]);
log_setting("Camera_OuterRightConfig", values.camera_config[OuterRightCamera]);
@@ -174,6 +175,7 @@ void RestoreGlobalState(bool is_powered_on) {
// Audio
values.audio_emulation.SetGlobal(true);
values.enable_audio_stretching.SetGlobal(true);
+ values.enable_realtime_audio.SetGlobal(true);
values.volume.SetGlobal(true);
// Core
diff --git a/src/common/settings.h b/src/common/settings.h
index 8bb6a474b..b4f8fb968 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -526,6 +526,7 @@ struct Values {
bool audio_muted;
SwitchableSetting audio_emulation{AudioEmulation::HLE, "audio_emulation"};
SwitchableSetting enable_audio_stretching{true, "enable_audio_stretching"};
+ SwitchableSetting enable_realtime_audio{false, "enable_realtime_audio"};
SwitchableSetting volume{1.f, 0.f, 1.f, "volume"};
Setting output_type{AudioCore::SinkType::Auto, "output_type"};
Setting output_device{"auto", "output_device"};
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 9f4fcf406..747393fd7 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -391,6 +391,10 @@ PerfStats::Results System::GetLastPerfStats() {
return perf_stats ? perf_stats->GetLastStats() : PerfStats::Results{};
}
+double System::GetLastFrameTimeScale() {
+ return perf_stats->GetLastFrameTimeScale();
+}
+
void System::Reschedule() {
if (!reschedule_pending) {
return;
diff --git a/src/core/core.h b/src/core/core.h
index a395360ac..85bc79276 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -184,6 +184,8 @@ public:
[[nodiscard]] PerfStats::Results GetLastPerfStats();
+ double GetLastFrameTimeScale();
+
/**
* Gets a reference to the emulated CPU.
* @returns A reference to the emulated CPU.