From d53425e3bf9cf41162f03aafdb0564721f40a240 Mon Sep 17 00:00:00 2001 From: OpenSauce04 Date: Thu, 7 Nov 2024 16:33:28 +0000 Subject: [PATCH] Improved playback consistency of realtime audio option during inconsistent framerates --- src/audio_core/hle/hle.cpp | 2 +- src/core/core.cpp | 4 ++-- src/core/core.h | 2 +- src/core/perf_stats.cpp | 11 +++++++++++ src/core/perf_stats.h | 6 ++++++ 5 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/audio_core/hle/hle.cpp b/src/audio_core/hle/hle.cpp index 108d5e2ca..bd27ce7b2 100644 --- a/src/audio_core/hle/hle.cpp +++ b/src/audio_core/hle/hle.cpp @@ -419,7 +419,7 @@ void DspHle::Impl::AudioTickCallback(s64 cycles_late) { // Reschedule recurrent event const double time_scale = Settings::values.enable_realtime_audio - ? std::clamp(Core::System::GetInstance().GetLastFrameTimeScale(), 1.0, 3.0) + ? std::clamp(Core::System::GetInstance().GetStableFrameTimeScale(), 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); diff --git a/src/core/core.cpp b/src/core/core.cpp index 747393fd7..bf8aca7e6 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -391,8 +391,8 @@ PerfStats::Results System::GetLastPerfStats() { return perf_stats ? perf_stats->GetLastStats() : PerfStats::Results{}; } -double System::GetLastFrameTimeScale() { - return perf_stats->GetLastFrameTimeScale(); +double System::GetStableFrameTimeScale() { + return perf_stats->GetStableFrameTimeScale(); } void System::Reschedule() { diff --git a/src/core/core.h b/src/core/core.h index 85bc79276..60f7605dd 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -184,7 +184,7 @@ public: [[nodiscard]] PerfStats::Results GetLastPerfStats(); - double GetLastFrameTimeScale(); + double GetStableFrameTimeScale(); /** * Gets a reference to the emulated CPU. diff --git a/src/core/perf_stats.cpp b/src/core/perf_stats.cpp index c05cf80e5..ea7f01ca6 100644 --- a/src/core/perf_stats.cpp +++ b/src/core/perf_stats.cpp @@ -129,6 +129,17 @@ double PerfStats::GetLastFrameTimeScale() const { return duration_cast(previous_frame_length).count() / FRAME_LENGTH; } +double PerfStats::GetStableFrameTimeScale() const { + std::scoped_lock lock{object_mutex}; + + constexpr double FRAME_LENGTH_MILLIS = (1.0 / SCREEN_REFRESH_RATE) * 1000; + const size_t num_frames = std::min(50UL, current_index + 1); + const double sum = std::accumulate(perf_history.begin() + current_index - num_frames, + perf_history.begin() + current_index, 0.0); + const double stable_frame_length = sum / num_frames; + return stable_frame_length / FRAME_LENGTH_MILLIS; +} + void FrameLimiter::WaitOnce() { if (frame_advancing_enabled) { // Frame advancing is enabled: wait on event instead of doing framelimiting diff --git a/src/core/perf_stats.h b/src/core/perf_stats.h index d68ff4dda..ce289592f 100644 --- a/src/core/perf_stats.h +++ b/src/core/perf_stats.h @@ -83,6 +83,12 @@ public: */ double GetLastFrameTimeScale() const; + /** + * Has the same functionality as GetLastFrameTimeScale, but uses the mean frame time over the + * last 50 frames rather than only the frame time of the previous frame. + */ + double GetStableFrameTimeScale() const; + void AddArticBaseTraffic(u32 bytes) { artic_transmitted += bytes; }