rodio
rodio copied to clipboard
Cannot get any better than 12-16 ms latency
#[allow(dead_code)]
pub struct SamplePlayer {
output_handle: OutputStreamHandle,
stream: OutputStream,
}
impl SamplePlayer {
pub fn new() -> Self {
let (_stream, stream_handle) = OutputStream::try_default().unwrap();
Self { output_handle: stream_handle, stream: _stream }
}
pub fn play_sample(&self, sample: &Sample) {
let now = Instant::now();
let _ = &self.output_handle.play_raw(sample.raw_audio.clone());
println!("{}", now.elapsed().as_secs_f32() * 1000.);
}
}
Sample:
pub struct Sample {
pub raw_audio: SamplesConverter<Buffered<Decoder<File>>, f32>,
}
impl Sample {
pub fn new(file: File) -> Self {
let source = Decoder::new(file).unwrap();
let buffer = source.buffered();
Self {
raw_audio: buffer.convert_samples(),
}
}
pub fn new_from_filepath(path: String) -> Self {
let f = File::open(path).unwrap();
Self::new(f)
}
}
Hello everybody, I'm working on a simple drum machine. Since this is an instrument, it's latency must be lower than ~8 ms. But I cannot get any lower than 12-16 ms right now. And I know, this is a playback library and might not be the right way to create a low latency instrument, but I think 16 ms is still way too much for a playback library.
This is the project link if you want to check the entire code. I can create a small test version of just the audio part if needed.
@ramazanemreosmanoglu In
pub fn play_sample(&self, sample: &Sample) {
let now = Instant::now();
let _ = &self.output_handle.play_raw(sample.raw_audio.clone());
println!("{}", now.elapsed().as_secs_f32() * 1000.);
}
You're cloning inside of timing block. So you're really measuring clone
+ play_raw
.
Move the clone outside of the timing block:
pub fn play_sample(&self, sample: &Sample) {
let signal = sample.raw_audio.clone();
let now = Instant::now();
let _ = &self.output_handle.play_raw(signal);
println!("{}", now.elapsed().as_secs_f32() * 1000.);
}
Is there a way to play a source without cloning? As far as I can see playing the same source repeatedly simply requires a clone (using a buffered
source), because play_raw
moves the source. I'm also noticing a latency above what I was hoping for, and haven't figured out yet how to avoid cloning, which likely contributes to it.
couldn't you preload all the sounds at the start, pause them and then unpause them, when you need to use them?