From 957ddab6796cb6f644c60993c3035d8bd9c0a398 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Wed, 12 Sep 2018 18:07:16 +0100 Subject: [PATCH] audio_core: Flush stream when not playing anything --- src/audio_core/cubeb_sink.cpp | 11 +++++++++++ src/audio_core/null_sink.h | 2 ++ src/audio_core/sink_stream.h | 2 ++ src/audio_core/stream.cpp | 2 ++ src/audio_core/time_stretch.cpp | 4 ++++ src/audio_core/time_stretch.h | 2 ++ 6 files changed, 23 insertions(+) diff --git a/src/audio_core/cubeb_sink.cpp b/src/audio_core/cubeb_sink.cpp index 067dc98d2..79155a7a0 100644 --- a/src/audio_core/cubeb_sink.cpp +++ b/src/audio_core/cubeb_sink.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include #include #include "audio_core/cubeb_sink.h" #include "audio_core/stream.h" @@ -81,6 +82,10 @@ public: return queue.Size() / num_channels; } + void Flush() override { + should_flush = true; + } + u32 GetNumChannels() const { return num_channels; } @@ -94,6 +99,7 @@ private: Common::RingBuffer queue; std::array last_frame; + std::atomic should_flush{}; TimeStretcher time_stretch; static long DataCallback(cubeb_stream* stream, void* user_data, const void* input_buffer, @@ -163,6 +169,11 @@ long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const s16* const out{reinterpret_cast(buffer)}; const size_t out_frames = impl->time_stretch.Process(in.data(), num_in, out, num_frames); samples_written = out_frames * num_channels; + + if (impl->should_flush) { + impl->time_stretch.Flush(); + impl->should_flush = false; + } } else { samples_written = impl->queue.Pop(buffer, samples_to_write); } diff --git a/src/audio_core/null_sink.h b/src/audio_core/null_sink.h index fbb1bc225..2ed0c83b6 100644 --- a/src/audio_core/null_sink.h +++ b/src/audio_core/null_sink.h @@ -25,6 +25,8 @@ private: size_t SamplesInQueue(u32 /*num_channels*/) const override { return 0; } + + void Flush() override {} } null_sink_stream; }; diff --git a/src/audio_core/sink_stream.h b/src/audio_core/sink_stream.h index 743a743a3..4309ad094 100644 --- a/src/audio_core/sink_stream.h +++ b/src/audio_core/sink_stream.h @@ -27,6 +27,8 @@ public: virtual void EnqueueSamples(u32 num_channels, const std::vector& samples) = 0; virtual std::size_t SamplesInQueue(u32 num_channels) const = 0; + + virtual void Flush() = 0; }; using SinkStreamPtr = std::unique_ptr; diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp index 49c6efc85..84dcdd98d 100644 --- a/src/audio_core/stream.cpp +++ b/src/audio_core/stream.cpp @@ -73,6 +73,7 @@ static void VolumeAdjustSamples(std::vector& samples) { void Stream::PlayNextBuffer() { if (!IsPlaying()) { // Ensure we are in playing state before playing the next buffer + sink_stream.Flush(); return; } @@ -83,6 +84,7 @@ void Stream::PlayNextBuffer() { if (queued_buffers.empty()) { // No queued buffers - we are effectively paused + sink_stream.Flush(); return; } diff --git a/src/audio_core/time_stretch.cpp b/src/audio_core/time_stretch.cpp index d2e3391c1..da094c46b 100644 --- a/src/audio_core/time_stretch.cpp +++ b/src/audio_core/time_stretch.cpp @@ -22,6 +22,10 @@ void TimeStretcher::Clear() { m_sound_touch.clear(); } +void TimeStretcher::Flush() { + m_sound_touch.flush(); +} + size_t TimeStretcher::Process(const s16* in, size_t num_in, s16* out, size_t num_out) { const double time_delta = static_cast(num_out) / m_sample_rate; // seconds diff --git a/src/audio_core/time_stretch.h b/src/audio_core/time_stretch.h index 0322b8b78..7e39e695e 100644 --- a/src/audio_core/time_stretch.h +++ b/src/audio_core/time_stretch.h @@ -24,6 +24,8 @@ public: void Clear(); + void Flush(); + private: u32 m_sample_rate; u32 m_channel_count;