mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-26 23:55:40 +00:00
AudioStream: Add option to wait until a full buffer is queued
This commit is contained in:
parent
9316ce532b
commit
4e583890ea
|
@ -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<std::mutex> 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<std::mutex> buffer_lock(m_buffer_mutex);
|
||||
if (!m_buffer_filling.load())
|
||||
{
|
||||
std::unique_lock<std::mutex> 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<std::mutex> resampler_lock(m_resampler_mutex);
|
||||
m_buffer.Clear();
|
||||
m_underflow_flag.store(false);
|
||||
m_buffer_filling.store(m_wait_for_buffer_fill);
|
||||
ResetResampler();
|
||||
}
|
||||
|
||||
|
|
|
@ -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<SampleType> 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;
|
||||
|
|
Loading…
Reference in a new issue