mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-30 09:35: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_output_sample_rate = output_sample_rate;
|
||||||
m_channels = channels;
|
m_channels = channels;
|
||||||
m_buffer_size = buffer_size;
|
m_buffer_size = buffer_size;
|
||||||
|
m_buffer_filling.store(m_wait_for_buffer_fill);
|
||||||
m_output_paused = true;
|
m_output_paused = true;
|
||||||
|
|
||||||
if (!SetBufferSize(buffer_size))
|
if (!SetBufferSize(buffer_size))
|
||||||
|
@ -55,6 +56,14 @@ void AudioStream::SetInputSampleRate(u32 sample_rate)
|
||||||
InternalSetInputSampleRate(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)
|
void AudioStream::InternalSetInputSampleRate(u32 sample_rate)
|
||||||
{
|
{
|
||||||
if (m_input_sample_rate == 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)
|
void AudioStream::EndWrite(u32 num_frames)
|
||||||
{
|
{
|
||||||
m_buffer.AdvanceTail(num_frames * m_channels);
|
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();
|
m_buffer_mutex.unlock();
|
||||||
FramesAvailable();
|
FramesAvailable();
|
||||||
}
|
}
|
||||||
|
@ -165,8 +179,9 @@ void AudioStream::ReadFrames(SampleType* samples, u32 num_frames, bool apply_vol
|
||||||
{
|
{
|
||||||
const u32 total_samples = num_frames * m_channels;
|
const u32 total_samples = num_frames * m_channels;
|
||||||
u32 samples_copied = 0;
|
u32 samples_copied = 0;
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> buffer_lock(m_buffer_mutex);
|
std::unique_lock<std::mutex> buffer_lock(m_buffer_mutex);
|
||||||
|
if (!m_buffer_filling.load())
|
||||||
|
{
|
||||||
if (m_input_sample_rate == m_output_sample_rate)
|
if (m_input_sample_rate == m_output_sample_rate)
|
||||||
{
|
{
|
||||||
samples_copied = std::min(m_buffer.GetSize(), total_samples);
|
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);
|
m_resampled_buffer.PopRange(samples, samples_copied);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ReleaseBufferLock(std::move(buffer_lock));
|
||||||
|
}
|
||||||
|
|
||||||
if (samples_copied < total_samples)
|
if (samples_copied < total_samples)
|
||||||
{
|
{
|
||||||
|
@ -214,16 +233,18 @@ void AudioStream::ReadFrames(SampleType* samples, u32 num_frames, bool apply_vol
|
||||||
resample_subpos %= 65536u;
|
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);
|
m_underflow_flag.store(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// read nothing, so zero-fill
|
// read nothing, so zero-fill
|
||||||
std::memset(samples, 0, sizeof(SampleType) * total_samples);
|
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_underflow_flag.store(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_buffer_filling.store(m_wait_for_buffer_fill);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (apply_volume && m_output_volume != FullVolume)
|
if (apply_volume && m_output_volume != FullVolume)
|
||||||
|
@ -267,6 +288,7 @@ void AudioStream::EmptyBuffers()
|
||||||
std::unique_lock<std::mutex> resampler_lock(m_resampler_mutex);
|
std::unique_lock<std::mutex> resampler_lock(m_resampler_mutex);
|
||||||
m_buffer.Clear();
|
m_buffer.Clear();
|
||||||
m_underflow_flag.store(false);
|
m_underflow_flag.store(false);
|
||||||
|
m_buffer_filling.store(m_wait_for_buffer_fill);
|
||||||
ResetResampler();
|
ResetResampler();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ public:
|
||||||
void SetSync(bool enable) { m_sync = enable; }
|
void SetSync(bool enable) { m_sync = enable; }
|
||||||
|
|
||||||
void SetInputSampleRate(u32 sample_rate);
|
void SetInputSampleRate(u32 sample_rate);
|
||||||
|
void SetWaitForBufferFill(bool enabled);
|
||||||
|
|
||||||
virtual void SetOutputVolume(u32 volume);
|
virtual void SetOutputVolume(u32 volume);
|
||||||
|
|
||||||
|
@ -109,10 +110,12 @@ private:
|
||||||
std::vector<SampleType> m_resample_buffer;
|
std::vector<SampleType> m_resample_buffer;
|
||||||
|
|
||||||
std::atomic_bool m_underflow_flag{false};
|
std::atomic_bool m_underflow_flag{false};
|
||||||
|
std::atomic_bool m_buffer_filling{false};
|
||||||
u32 m_max_samples = 0;
|
u32 m_max_samples = 0;
|
||||||
|
|
||||||
bool m_output_paused = true;
|
bool m_output_paused = true;
|
||||||
bool m_sync = true;
|
bool m_sync = true;
|
||||||
|
bool m_wait_for_buffer_fill = false;
|
||||||
|
|
||||||
// Resampling
|
// Resampling
|
||||||
double m_resampler_ratio = 1.0;
|
double m_resampler_ratio = 1.0;
|
||||||
|
|
Loading…
Reference in a new issue