Add proper sleeps in the engine

This commit is contained in:
Pierre Krieger 2015-09-10 21:27:16 +02:00
parent 0cd1002caf
commit 056a56950e
6 changed files with 38 additions and 13 deletions

View file

@ -9,8 +9,9 @@ repository = "https://github.com/tomaka/rodio"
documentation = "http://tomaka.github.io/rodio/rodio/index.html"
[dependencies]
cpal = "0.2.1"
cpal = "0.2.2"
#hound = "1.0.0"
hound = { git = "https://github.com/tomaka/hound", branch = "wavreader-ownership" }
lazy_static = "0.1.12"
time = "0.1.32"
vorbis = "0.0.13"

View file

@ -9,8 +9,9 @@ mod wav;
/// Trait for objects that produce an audio stream.
pub trait Decoder {
/// Appends data to the voice.
fn write(&mut self);
/// Appends data to the voice. Returns the number of nanoseconds after which new data will need
/// to have been submitted.
fn write(&mut self) -> u64;
}
/// Builds a new `Decoder` from a data stream by determining the correct format.

View file

@ -44,7 +44,7 @@ impl VorbisDecoder {
}
impl Decoder for VorbisDecoder {
fn write(&mut self) {
fn write(&mut self) -> u64 {
/*let (min, _) = self.reader.size_hint();
if min == 0 {
@ -52,11 +52,15 @@ impl Decoder for VorbisDecoder {
return;
}*/
{
let len = {
let mut buffer = self.voice.append_data(32768);
let len = buffer.len();
conversions::convert_and_write(self.reader.by_ref(), &mut buffer);
}
len
};
self.voice.play();
len as u64 * 1000000000 / self.voice.get_samples_rate().0 as u64
}
}

View file

@ -80,19 +80,25 @@ fn is_wave<R>(mut data: R) -> bool where R: Read + Seek {
}
impl Decoder for WavDecoder {
fn write(&mut self) {
fn write(&mut self) -> u64 {
let (min, _) = self.reader.size_hint();
if min == 0 {
// finished
return;
return 1000000000;
}
{
let len = {
let mut buffer = self.voice.append_data(min);
let len = buffer.len();
conversions::convert_and_write(self.reader.by_ref(), &mut buffer);
}
len
};
let duration = len as u64 * 1000000000 / self.voice.get_samples_rate().0 as u64;
self.voice.play();
duration
}
}

View file

@ -1,3 +1,4 @@
use std::cmp;
use std::io::{Read, Seek};
use std::thread::{self, Builder};
use std::sync::mpsc::{self, Sender, Receiver};
@ -9,6 +10,8 @@ use cpal::Voice;
use decoder;
use decoder::Decoder;
use time;
/// The internal engine of this library.
///
/// Each `Engine` owns a thread that runs in the background and plays the audio.
@ -85,12 +88,21 @@ fn background(rx: Receiver<Command>) {
}
}
// stores
let mut next_step_ns = time::precise_time_ns();
// updating the existing sounds
for &mut (_, ref mut decoder) in sounds.iter_mut() {
decoder.write();
for &mut (_, ref mut decoder) in &mut sounds {
let val = decoder.write();
let val = time::precise_time_ns() + val;
next_step_ns = cmp::min(next_step_ns, val);
}
// sleeping a bit?
thread::sleep_ms(1);
let sleep = next_step_ns as i64 - time::precise_time_ns() as i64;
let sleep = sleep - 500000;
if sleep >= 0 {
thread::sleep_ms(sleep as u32);
}
}
}

View file

@ -2,6 +2,7 @@ extern crate cpal;
extern crate hound;
#[macro_use]
extern crate lazy_static;
extern crate time;
extern crate vorbis;
pub use cpal::{Endpoint, get_endpoints_list, get_default_endpoint};