diff options
Diffstat (limited to 'src/audio_core')
-rw-r--r-- | src/audio_core/cubeb_sink.cpp | 11 | ||||
-rw-r--r-- | src/audio_core/null_sink.h | 2 | ||||
-rw-r--r-- | src/audio_core/sink_stream.h | 2 | ||||
-rw-r--r-- | src/audio_core/stream.cpp | 2 | ||||
-rw-r--r-- | src/audio_core/time_stretch.cpp | 4 | ||||
-rw-r--r-- | src/audio_core/time_stretch.h | 2 |
6 files changed, 23 insertions, 0 deletions
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 <algorithm> +#include <atomic> #include <cstring> #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<s16, 0x10000> queue; std::array<s16, 2> last_frame; + std::atomic<bool> 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<s16*>(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<s16>& samples) = 0; virtual std::size_t SamplesInQueue(u32 num_channels) const = 0; + + virtual void Flush() = 0; }; using SinkStreamPtr = std::unique_ptr<SinkStream>; 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<s16>& 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<double>(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; |