From 2a10632dd2bb50a583c48ae6bacb9f230bd15e16 Mon Sep 17 00:00:00 2001
From: yuzubot <yuzu@yuzu-emu.org>
Date: Sun, 27 Mar 2022 12:02:42 +0000
Subject: "Merge Tagged PR 7346"

---
 src/audio_core/stream.cpp |  9 +++++++++
 src/audio_core/stream.h   | 15 ++++++++-------
 2 files changed, 17 insertions(+), 7 deletions(-)

(limited to 'src')

diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp
index 0abc989b2f..ca034568d4 100644
--- a/src/audio_core/stream.cpp
+++ b/src/audio_core/stream.cpp
@@ -87,6 +87,14 @@ static void VolumeAdjustSamples(std::vector<s16>& samples, float game_volume) {
 }
 
 void Stream::PlayNextBuffer(std::chrono::nanoseconds ns_late) {
+    auto now = std::chrono::steady_clock::now();
+    auto duration = now.time_since_epoch();
+    auto nanoseconds = std::chrono::duration_cast<std::chrono::nanoseconds>(duration);
+
+    if (nanoseconds > expected_cb_time) {
+        ns_late = nanoseconds - expected_cb_time;
+    }
+
     if (!IsPlaying()) {
         // Ensure we are in playing state before playing the next buffer
         sink_stream.Flush();
@@ -121,6 +129,7 @@ void Stream::PlayNextBuffer(std::chrono::nanoseconds ns_late) {
         ns_late = {};
     }
 
+    expected_cb_time = nanoseconds + (buffer_release_ns - ns_late);
     core_timing.ScheduleEvent(buffer_release_ns - ns_late, release_event, {});
 }
 
diff --git a/src/audio_core/stream.h b/src/audio_core/stream.h
index dbd97ec9c3..111404e76f 100644
--- a/src/audio_core/stream.h
+++ b/src/audio_core/stream.h
@@ -117,13 +117,14 @@ private:
     ReleaseCallback release_callback; ///< Buffer release callback for the stream
     State state{State::Stopped};      ///< Playback state of the stream
     std::shared_ptr<Core::Timing::EventType>
-        release_event;                      ///< Core timing release event for the stream
-    BufferPtr active_buffer;                ///< Actively playing buffer in the stream
-    std::queue<BufferPtr> queued_buffers;   ///< Buffers queued to be played in the stream
-    std::queue<BufferPtr> released_buffers; ///< Buffers recently released from the stream
-    SinkStream& sink_stream;                ///< Output sink for the stream
-    Core::Timing::CoreTiming& core_timing;  ///< Core timing instance.
-    std::string name;                       ///< Name of the stream, must be unique
+        release_event;                              ///< Core timing release event for the stream
+    BufferPtr active_buffer;                        ///< Actively playing buffer in the stream
+    std::queue<BufferPtr> queued_buffers;           ///< Buffers queued to be played in the stream
+    std::queue<BufferPtr> released_buffers;         ///< Buffers recently released from the stream
+    SinkStream& sink_stream;                        ///< Output sink for the stream
+    Core::Timing::CoreTiming& core_timing;          ///< Core timing instance.
+    std::string name;                               ///< Name of the stream, must be unique
+    std::chrono::nanoseconds expected_cb_time = {}; ///< Estimated time of next callback
 };
 
 using StreamPtr = std::shared_ptr<Stream>;
-- 
cgit v1.2.3-70-g09d2