mirror of
https://github.com/RustAudio/rodio
synced 2024-12-13 13:42:34 +00:00
Make the dynamic mixer drop finished sources
This commit is contained in:
parent
cd193a541b
commit
885caa6e74
4 changed files with 32 additions and 15 deletions
|
@ -101,12 +101,21 @@ impl<S> Iterator for DynamicMixer<S> where S: Sample + Send + 'static {
|
|||
return None;
|
||||
}
|
||||
|
||||
let mut to_drop = Vec::new();
|
||||
|
||||
let mut sum = S::zero_value();
|
||||
for src in self.current_sources.iter_mut() {
|
||||
for (num, src) in self.current_sources.iter_mut().enumerate() {
|
||||
if let Some(val) = src.next() {
|
||||
sum += val;
|
||||
} else {
|
||||
to_drop.push(num);
|
||||
}
|
||||
}
|
||||
|
||||
for &td in to_drop.iter().rev() {
|
||||
self.current_sources.remove(td);
|
||||
}
|
||||
|
||||
Some(sum)
|
||||
}
|
||||
|
||||
|
|
|
@ -56,33 +56,42 @@ impl Engine {
|
|||
pub fn start<S>(&self, endpoint: &Endpoint, source: S)
|
||||
where S: Source<Item = f32> + Send + 'static
|
||||
{
|
||||
let mut voice_to_start = None;
|
||||
|
||||
let mixer = {
|
||||
let mut end_points = self.end_points.lock().unwrap();
|
||||
|
||||
match end_points.entry(endpoint.get_name()) {
|
||||
Entry::Vacant(e) => {
|
||||
let arc = new_voice(endpoint, &self.events_loop);
|
||||
e.insert(Arc::downgrade(&arc));
|
||||
arc
|
||||
let (mixer, voice) = new_voice(endpoint, &self.events_loop);
|
||||
e.insert(Arc::downgrade(&mixer));
|
||||
voice_to_start = Some(voice);
|
||||
mixer
|
||||
},
|
||||
Entry::Occupied(mut e) => {
|
||||
if let Some(m) = e.get().upgrade() {
|
||||
m.clone()
|
||||
} else {
|
||||
let voice = new_voice(endpoint, &self.events_loop);
|
||||
e.insert(Arc::downgrade(&voice));
|
||||
voice
|
||||
let (mixer, voice) = new_voice(endpoint, &self.events_loop);
|
||||
e.insert(Arc::downgrade(&mixer));
|
||||
voice_to_start = Some(voice);
|
||||
mixer
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
mixer.add(source);
|
||||
|
||||
if let Some(mut voice) = voice_to_start {
|
||||
voice.play();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: handle possible errors here
|
||||
fn new_voice(endpoint: &Endpoint, events_loop: &Arc<EventLoop>) -> Arc<dynamic_mixer::DynamicMixerController<f32>> {
|
||||
fn new_voice(endpoint: &Endpoint, events_loop: &Arc<EventLoop>)
|
||||
-> (Arc<dynamic_mixer::DynamicMixerController<f32>>, Voice) {
|
||||
// Determine the format to use for the new voice.
|
||||
let format = endpoint.get_supported_formats_list()
|
||||
.unwrap()
|
||||
|
@ -113,7 +122,7 @@ fn new_voice(endpoint: &Endpoint, events_loop: &Arc<EventLoop>) -> Arc<dynamic_m
|
|||
})
|
||||
.expect("The endpoint doesn't support any format!?");
|
||||
|
||||
let (mut voice, stream) = Voice::new(&endpoint, &format, events_loop)
|
||||
let (voice, stream) = Voice::new(&endpoint, &format, events_loop)
|
||||
.unwrap();
|
||||
|
||||
let (mixer_tx, mut mixer_rx) = {
|
||||
|
@ -152,9 +161,5 @@ fn new_voice(endpoint: &Endpoint, events_loop: &Arc<EventLoop>) -> Arc<dynamic_m
|
|||
task::spawn(future_to_exec).execute(Arc::new(MyExecutor));
|
||||
}
|
||||
|
||||
voice.play(); // TODO: don't do this now
|
||||
// TODO: is there a chance that a context switch here starts playing the sound and
|
||||
// immediately drops it?
|
||||
|
||||
mixer_tx
|
||||
(mixer_tx, voice)
|
||||
}
|
||||
|
|
|
@ -101,7 +101,7 @@ impl Sink {
|
|||
/// Builds a new `Sink`.
|
||||
#[inline]
|
||||
pub fn new(endpoint: &Endpoint) -> Sink {
|
||||
let (queue_tx, queue_rx) = queue::queue(false);
|
||||
let (queue_tx, queue_rx) = queue::queue(true);
|
||||
ENGINE.start(endpoint, queue_rx);
|
||||
|
||||
Sink {
|
||||
|
@ -188,6 +188,8 @@ impl Sink {
|
|||
impl Drop for Sink {
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
self.queue_tx.set_keep_alive_if_empty(false);
|
||||
|
||||
if !self.detached {
|
||||
self.stopped.store(true, Ordering::Relaxed);
|
||||
}
|
||||
|
|
|
@ -129,6 +129,7 @@ impl<S> Iterator for SourcesQueueOutput<S> where S: Sample + Send + 'static {
|
|||
// Since `self.current` has finished, we need to pick the next sound.
|
||||
// In order to avoid inlining this expensive operation, the code is in another function.
|
||||
if self.go_next().is_err() {
|
||||
println!("returned none");
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue