mirror of
https://github.com/RustAudio/rodio
synced 2024-12-13 21:52:38 +00:00
Dropping the Sink now stops all sounds
This commit is contained in:
parent
d786f79e02
commit
a23aeaa4ff
2 changed files with 36 additions and 15 deletions
|
@ -100,7 +100,7 @@ impl Engine {
|
|||
// the iterator that produces sounds
|
||||
let next_sounds = Arc::new(Mutex::new(Vec::new()));
|
||||
let source = QueueIterator { current: Box::new(None.into_iter()), next: next_sounds.clone() };
|
||||
let source_id = &next_sounds as *const _ as *const u8 as usize;
|
||||
let source_id = &*next_sounds as *const Mutex<_> as *const u8 as usize;
|
||||
|
||||
// at each loop, the background thread will store the remaining time of the sound in this
|
||||
// value
|
||||
|
@ -165,8 +165,10 @@ impl<'a> Handle<'a> {
|
|||
commands.send(Command::SetVolume(self.source_id, value)).unwrap();
|
||||
}
|
||||
|
||||
// note that this method could take `self` instead of `&self`, but it makes `Sink`'s life
|
||||
// easier not to take `self`
|
||||
#[inline]
|
||||
pub fn stop(self) {
|
||||
pub fn stop(&self) {
|
||||
let commands = self.engine.commands.lock().unwrap();
|
||||
commands.send(Command::Stop(self.source_id)).unwrap();
|
||||
|
||||
|
@ -222,7 +224,7 @@ fn background(rx: Receiver<Command>) {
|
|||
Command::Stop(decoder) => {
|
||||
for (_, &mut (_, ref mut sounds)) in voices.iter_mut() {
|
||||
sounds.retain(|dec| {
|
||||
&*dec.0.next as *const _ as *const u8 as usize != decoder
|
||||
&*dec.0.next as *const Mutex<_> as *const u8 as usize != decoder
|
||||
})
|
||||
}
|
||||
},
|
||||
|
@ -230,7 +232,7 @@ fn background(rx: Receiver<Command>) {
|
|||
Command::SetVolume(decoder, volume) => {
|
||||
for (_, &mut (_, ref mut sounds)) in voices.iter_mut() {
|
||||
if let Some(d) = sounds.iter_mut()
|
||||
.find(|dec| &*dec.0.next as *const _ as *const u8 as usize == decoder)
|
||||
.find(|dec| &*dec.0.next as *const Mutex<_> as *const u8 as usize == decoder)
|
||||
{
|
||||
d.2 = volume;
|
||||
}
|
||||
|
@ -242,7 +244,7 @@ fn background(rx: Receiver<Command>) {
|
|||
// removing sounds that have finished playing
|
||||
for decoder in mem::replace(&mut sounds_to_remove, Vec::new()) {
|
||||
for (_, &mut (_, ref mut sounds)) in voices.iter_mut() {
|
||||
sounds.retain(|dec| &*dec.0.next as *const _ != decoder);
|
||||
sounds.retain(|dec| &*dec.0.next as *const Mutex<_> != decoder);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
39
src/lib.rs
39
src/lib.rs
|
@ -28,20 +28,30 @@ lazy_static! {
|
|||
static ref ENGINE: engine::Engine = engine::Engine::new();
|
||||
}
|
||||
|
||||
/// Handle to a playing sound.
|
||||
/// Handle to an endpoint that outputs sounds.
|
||||
///
|
||||
/// Note that dropping the handle doesn't stop the sound. You must call `stop` explicitely.
|
||||
pub struct Sink(engine::Handle<'static>);
|
||||
/// Dropping the `Sink` stops all sounds. You can use `detach` if you want the sounds to continue
|
||||
/// playing.
|
||||
pub struct Sink {
|
||||
handle: engine::Handle<'static>,
|
||||
// if true, then the sound will stop playing at the end
|
||||
stop: bool,
|
||||
}
|
||||
|
||||
impl Sink {
|
||||
/// Builds a new `Sink`.
|
||||
pub fn new(endpoint: &Endpoint) -> Sink {
|
||||
Sink(ENGINE.start(&endpoint))
|
||||
Sink {
|
||||
handle: ENGINE.start(&endpoint),
|
||||
stop: true,
|
||||
}
|
||||
}
|
||||
|
||||
/// Appends a sound to the queue of sounds to play.
|
||||
pub fn append<S>(&self, source: S) where S: Source + Send + 'static,
|
||||
S::Item: Sample, S::Item: Send
|
||||
{
|
||||
self.0.append(source);
|
||||
self.handle.append(source);
|
||||
}
|
||||
|
||||
/// Changes the volume of the sound.
|
||||
|
@ -50,13 +60,13 @@ impl Sink {
|
|||
/// multiply each sample by this value.
|
||||
#[inline]
|
||||
pub fn set_volume(&mut self, value: f32) {
|
||||
self.0.set_volume(value);
|
||||
self.handle.set_volume(value);
|
||||
}
|
||||
|
||||
/// Stops the sound.
|
||||
/// Destroys the sink without stopping the sounds that are still playing.
|
||||
#[inline]
|
||||
pub fn stop(self) {
|
||||
self.0.stop()
|
||||
pub fn detach(mut self) {
|
||||
self.stop = false;
|
||||
}
|
||||
|
||||
/// Returns the minimum duration before the end of the sounds submitted to this sink.
|
||||
|
@ -64,7 +74,7 @@ impl Sink {
|
|||
/// Note that this is a minimum value, and the sound can last longer.
|
||||
#[inline]
|
||||
pub fn get_min_remaining_duration(&self) -> Duration {
|
||||
self.0.get_min_remaining_duration()
|
||||
self.handle.get_min_remaining_duration()
|
||||
}
|
||||
|
||||
/// Sleeps the current thread until the sound ends.
|
||||
|
@ -75,6 +85,15 @@ impl Sink {
|
|||
}
|
||||
}
|
||||
|
||||
impl Drop for Sink {
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
if self.stop {
|
||||
self.handle.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Plays a sound once. Returns a `Sink` that can be used to control the sound.
|
||||
#[inline]
|
||||
pub fn play_once<R>(endpoint: &Endpoint, input: R) -> Sink
|
||||
|
|
Loading…
Reference in a new issue