diff --git a/ferretro_components/src/provided/sdl2/audio_thread.rs b/ferretro_components/src/provided/sdl2/audio_thread.rs index e059483..75a6a8a 100644 --- a/ferretro_components/src/provided/sdl2/audio_thread.rs +++ b/ferretro_components/src/provided/sdl2/audio_thread.rs @@ -1,7 +1,6 @@ use crate::prelude::*; use std::path::Path; -use std::time::Duration; use sdl2::Sdl; use sdl2::audio::{AudioCallback, AudioDevice, AudioSpecDesired}; @@ -17,7 +16,6 @@ pub struct SimpleSdl2AudioThreadComponent { struct MySdlAudio { must_resample: bool, reader: Consumer, - timing: SystemTiming, } impl AudioCallback for MySdlAudio { @@ -28,17 +26,20 @@ impl AudioCallback for MySdlAudio { todo!("correct software resampling") } let buf_len = data.len(); - let mut remaining = buf_len; - let mut dead_frames = 0; - while remaining > 0 { - let read = self.reader.pop_slice(&mut data[buf_len - remaining..]); - remaining -= read; - if read == 0 { - std::thread::sleep(Duration::from_secs_f64(1.0 / self.timing.fps)); - dead_frames += 1; - if dead_frames > self.timing.fps as usize / 2 { - break; + + let mut filled = self.reader.pop_slice(data); + filled += self.reader.pop_slice(&mut data[filled..]); + if filled == 0 { + data.fill(0); + } else { + while filled < buf_len { + let remaining = buf_len - filled; + if remaining < filled { + data.copy_within(..remaining, filled); + } else { + data.copy_within(..filled, filled); } + filled *= 2; } } } @@ -81,14 +82,16 @@ impl SimpleSdl2AudioThreadComponent { } fn new_device_from_timing(audio: &sdl2::AudioSubsystem, timing: &SystemTiming) -> crate::base::Result<(AudioDevice, Producer)> { + const CHANNELS: usize = 2; + const BUF_FRAMES: usize = 4; let samples_per_frame = timing.sample_rate / timing.fps; - let buf_len = samples_per_frame.ceil() as usize * 4; + let buf_len = samples_per_frame.ceil() as usize * CHANNELS * BUF_FRAMES * 2; let (writer, reader) = RingBuffer::new(buf_len).split(); let desired_spec = AudioSpecDesired { freq: Some(timing.sample_rate.round() as i32), - channels: Some(2), - samples: Some((samples_per_frame.ceil() * 1.0) as u16), + channels: Some(CHANNELS as u8), + samples: Some(samples_per_frame.ceil() as u16 * BUF_FRAMES as u16), }; let device = audio.open_playback( @@ -99,7 +102,6 @@ impl SimpleSdl2AudioThreadComponent { MySdlAudio { must_resample, // todo: include freqs from & to reader, - timing: timing.clone(), } })?; device.resume();