less underrun

This commit is contained in:
lifning 2021-12-18 00:30:11 -08:00
parent 08e69a3062
commit 74f8a948e5
1 changed files with 18 additions and 16 deletions

View File

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