From ea1c8a3b81a8e7beccf536accbf0ef7ccbbcfc57 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 16 Feb 2020 12:46:25 -0500 Subject: [PATCH] Ensures the stereo audio queue is the same length (in time) as the mono. --- OSBindings/SDL/main.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/OSBindings/SDL/main.cpp b/OSBindings/SDL/main.cpp index f8e50bdb1..56940d3aa 100644 --- a/OSBindings/SDL/main.cpp +++ b/OSBindings/SDL/main.cpp @@ -168,10 +168,12 @@ struct MachineRunner { struct SpeakerDelegate: public Outputs::Speaker::Speaker::Delegate { // This is empirically the best that I can seem to do with SDL's timer precision. - static constexpr int buffer_size = 1024; + static constexpr int buffered_samples = 1024; + bool is_stereo = false; void speaker_did_complete_samples(Outputs::Speaker::Speaker *speaker, const std::vector &buffer) final { std::lock_guard lock_guard(audio_buffer_mutex_); + const auto buffer_size = buffered_samples * (is_stereo ? 2 : 1); if(audio_buffer_.size() > buffer_size) { audio_buffer_.erase(audio_buffer_.begin(), audio_buffer_.end() - buffer_size); } @@ -181,9 +183,10 @@ struct SpeakerDelegate: public Outputs::Speaker::Speaker::Delegate { void audio_callback(Uint8 *stream, int len) { std::lock_guard lock_guard(audio_buffer_mutex_); - std::size_t sample_length = static_cast(len) / sizeof(int16_t); - std::size_t copy_length = std::min(sample_length, audio_buffer_.size()); - int16_t *target = static_cast(static_cast(stream)); + // SDL buffer length is in bytes, so there's no need to adjust for stereo/mono in here. + const std::size_t sample_length = static_cast(len) / sizeof(int16_t); + const std::size_t copy_length = std::min(sample_length, audio_buffer_.size()); + int16_t *const target = static_cast(static_cast(stream)); std::memcpy(stream, audio_buffer_.data(), copy_length * sizeof(int16_t)); if(copy_length < sample_length) { @@ -661,13 +664,14 @@ int main(int argc, char *argv[]) { desired_audio_spec.freq = 48000; // TODO: how can I get SDL to reveal the output rate of this machine? desired_audio_spec.format = AUDIO_S16; desired_audio_spec.channels = 1 + int(speaker->get_is_stereo()); - desired_audio_spec.samples = SpeakerDelegate::buffer_size; + desired_audio_spec.samples = SpeakerDelegate::buffered_samples; desired_audio_spec.callback = SpeakerDelegate::SDL_audio_callback; desired_audio_spec.userdata = &speaker_delegate; speaker_delegate.audio_device = SDL_OpenAudioDevice(nullptr, 0, &desired_audio_spec, &obtained_audio_spec, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE); - speaker->set_output_rate(obtained_audio_spec.freq, desired_audio_spec.samples, speaker->get_is_stereo()); + speaker->set_output_rate(obtained_audio_spec.freq, desired_audio_spec.samples, obtained_audio_spec.channels == 2); + speaker_delegate.is_stereo = obtained_audio_spec.channels == 2; speaker->set_delegate(&speaker_delegate); SDL_PauseAudioDevice(speaker_delegate.audio_device, 0); }