summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio_core/cubeb_sink.cpp11
-rw-r--r--src/audio_core/null_sink.h2
-rw-r--r--src/audio_core/sink_stream.h2
-rw-r--r--src/audio_core/stream.cpp2
-rw-r--r--src/audio_core/time_stretch.cpp4
-rw-r--r--src/audio_core/time_stretch.h2
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 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm> 5#include <algorithm>
6#include <atomic>
6#include <cstring> 7#include <cstring>
7#include "audio_core/cubeb_sink.h" 8#include "audio_core/cubeb_sink.h"
8#include "audio_core/stream.h" 9#include "audio_core/stream.h"
@@ -81,6 +82,10 @@ public:
81 return queue.Size() / num_channels; 82 return queue.Size() / num_channels;
82 } 83 }
83 84
85 void Flush() override {
86 should_flush = true;
87 }
88
84 u32 GetNumChannels() const { 89 u32 GetNumChannels() const {
85 return num_channels; 90 return num_channels;
86 } 91 }
@@ -94,6 +99,7 @@ private:
94 99
95 Common::RingBuffer<s16, 0x10000> queue; 100 Common::RingBuffer<s16, 0x10000> queue;
96 std::array<s16, 2> last_frame; 101 std::array<s16, 2> last_frame;
102 std::atomic<bool> should_flush{};
97 TimeStretcher time_stretch; 103 TimeStretcher time_stretch;
98 104
99 static long DataCallback(cubeb_stream* stream, void* user_data, const void* input_buffer, 105 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
163 s16* const out{reinterpret_cast<s16*>(buffer)}; 169 s16* const out{reinterpret_cast<s16*>(buffer)};
164 const size_t out_frames = impl->time_stretch.Process(in.data(), num_in, out, num_frames); 170 const size_t out_frames = impl->time_stretch.Process(in.data(), num_in, out, num_frames);
165 samples_written = out_frames * num_channels; 171 samples_written = out_frames * num_channels;
172
173 if (impl->should_flush) {
174 impl->time_stretch.Flush();
175 impl->should_flush = false;
176 }
166 } else { 177 } else {
167 samples_written = impl->queue.Pop(buffer, samples_to_write); 178 samples_written = impl->queue.Pop(buffer, samples_to_write);
168 } 179 }
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:
25 size_t SamplesInQueue(u32 /*num_channels*/) const override { 25 size_t SamplesInQueue(u32 /*num_channels*/) const override {
26 return 0; 26 return 0;
27 } 27 }
28
29 void Flush() override {}
28 } null_sink_stream; 30 } null_sink_stream;
29}; 31};
30 32
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:
27 virtual void EnqueueSamples(u32 num_channels, const std::vector<s16>& samples) = 0; 27 virtual void EnqueueSamples(u32 num_channels, const std::vector<s16>& samples) = 0;
28 28
29 virtual std::size_t SamplesInQueue(u32 num_channels) const = 0; 29 virtual std::size_t SamplesInQueue(u32 num_channels) const = 0;
30
31 virtual void Flush() = 0;
30}; 32};
31 33
32using SinkStreamPtr = std::unique_ptr<SinkStream>; 34using 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) {
73void Stream::PlayNextBuffer() { 73void Stream::PlayNextBuffer() {
74 if (!IsPlaying()) { 74 if (!IsPlaying()) {
75 // Ensure we are in playing state before playing the next buffer 75 // Ensure we are in playing state before playing the next buffer
76 sink_stream.Flush();
76 return; 77 return;
77 } 78 }
78 79
@@ -83,6 +84,7 @@ void Stream::PlayNextBuffer() {
83 84
84 if (queued_buffers.empty()) { 85 if (queued_buffers.empty()) {
85 // No queued buffers - we are effectively paused 86 // No queued buffers - we are effectively paused
87 sink_stream.Flush();
86 return; 88 return;
87 } 89 }
88 90
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() {
22 m_sound_touch.clear(); 22 m_sound_touch.clear();
23} 23}
24 24
25void TimeStretcher::Flush() {
26 m_sound_touch.flush();
27}
28
25size_t TimeStretcher::Process(const s16* in, size_t num_in, s16* out, size_t num_out) { 29size_t TimeStretcher::Process(const s16* in, size_t num_in, s16* out, size_t num_out) {
26 const double time_delta = static_cast<double>(num_out) / m_sample_rate; // seconds 30 const double time_delta = static_cast<double>(num_out) / m_sample_rate; // seconds
27 31
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:
24 24
25 void Clear(); 25 void Clear();
26 26
27 void Flush();
28
27private: 29private:
28 u32 m_sample_rate; 30 u32 m_sample_rate;
29 u32 m_channel_count; 31 u32 m_channel_count;