From 4e583890ea33ec834d7d4bbb1ff51ebd5afd7ee4 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Thu, 28 Jan 2021 20:12:24 +1000 Subject: [PATCH] AudioStream: Add option to wait until a full buffer is queued --- src/common/audio_stream.cpp | 28 +++++++++++++++++++++++++--- src/common/audio_stream.h | 3 +++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/common/audio_stream.cpp b/src/common/audio_stream.cpp index dd57f2aec..1ba911eca 100644 --- a/src/common/audio_stream.cpp +++ b/src/common/audio_stream.cpp @@ -27,6 +27,7 @@ bool AudioStream::Reconfigure(u32 input_sample_rate /* = DefaultInputSampleRate m_output_sample_rate = output_sample_rate; m_channels = channels; m_buffer_size = buffer_size; + m_buffer_filling.store(m_wait_for_buffer_fill); m_output_paused = true; if (!SetBufferSize(buffer_size)) @@ -55,6 +56,14 @@ void AudioStream::SetInputSampleRate(u32 sample_rate) InternalSetInputSampleRate(sample_rate); } +void AudioStream::SetWaitForBufferFill(bool enabled) +{ + std::unique_lock buffer_lock(m_buffer_mutex); + m_wait_for_buffer_fill = enabled; + if (enabled && m_buffer.IsEmpty()) + m_buffer_filling.store(true); +} + void AudioStream::InternalSetInputSampleRate(u32 sample_rate) { if (m_input_sample_rate == sample_rate) @@ -123,6 +132,11 @@ void AudioStream::WriteFrames(const SampleType* frames, u32 num_frames) void AudioStream::EndWrite(u32 num_frames) { m_buffer.AdvanceTail(num_frames * m_channels); + if (m_buffer_filling.load()) + { + if ((m_buffer.GetSize() / m_channels) >= m_buffer_size) + m_buffer_filling.store(false); + } m_buffer_mutex.unlock(); FramesAvailable(); } @@ -165,8 +179,9 @@ void AudioStream::ReadFrames(SampleType* samples, u32 num_frames, bool apply_vol { const u32 total_samples = num_frames * m_channels; u32 samples_copied = 0; + std::unique_lock buffer_lock(m_buffer_mutex); + if (!m_buffer_filling.load()) { - std::unique_lock buffer_lock(m_buffer_mutex); if (m_input_sample_rate == m_output_sample_rate) { samples_copied = std::min(m_buffer.GetSize(), total_samples); @@ -187,6 +202,10 @@ void AudioStream::ReadFrames(SampleType* samples, u32 num_frames, bool apply_vol m_resampled_buffer.PopRange(samples, samples_copied); } } + else + { + ReleaseBufferLock(std::move(buffer_lock)); + } if (samples_copied < total_samples) { @@ -214,16 +233,18 @@ void AudioStream::ReadFrames(SampleType* samples, u32 num_frames, bool apply_vol resample_subpos %= 65536u; } - Log_DevPrintf("Audio buffer underflow, resampled %u frames to %u", samples_copied / m_channels, num_frames); + Log_VerbosePrintf("Audio buffer underflow, resampled %u frames to %u", samples_copied / m_channels, num_frames); m_underflow_flag.store(true); } else { // read nothing, so zero-fill std::memset(samples, 0, sizeof(SampleType) * total_samples); - Log_DevPrintf("Audio buffer underflow with no samples, added %u frames silence", num_frames); + Log_VerbosePrintf("Audio buffer underflow with no samples, added %u frames silence", num_frames); m_underflow_flag.store(true); } + + m_buffer_filling.store(m_wait_for_buffer_fill); } if (apply_volume && m_output_volume != FullVolume) @@ -267,6 +288,7 @@ void AudioStream::EmptyBuffers() std::unique_lock resampler_lock(m_resampler_mutex); m_buffer.Clear(); m_underflow_flag.store(false); + m_buffer_filling.store(m_wait_for_buffer_fill); ResetResampler(); } diff --git a/src/common/audio_stream.h b/src/common/audio_stream.h index eb0115272..137269cd4 100644 --- a/src/common/audio_stream.h +++ b/src/common/audio_stream.h @@ -37,6 +37,7 @@ public: void SetSync(bool enable) { m_sync = enable; } void SetInputSampleRate(u32 sample_rate); + void SetWaitForBufferFill(bool enabled); virtual void SetOutputVolume(u32 volume); @@ -109,10 +110,12 @@ private: std::vector m_resample_buffer; std::atomic_bool m_underflow_flag{false}; + std::atomic_bool m_buffer_filling{false}; u32 m_max_samples = 0; bool m_output_paused = true; bool m_sync = true; + bool m_wait_for_buffer_fill = false; // Resampling double m_resampler_ratio = 1.0;