less underrun
This commit is contained in:
parent
08e69a3062
commit
74f8a948e5
|
@ -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<i16>,
|
||||
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<MySdlAudio>, Producer<i16>)> {
|
||||
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();
|
||||
|
|
Loading…
Reference in New Issue