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