audio: Add AudioBackend::stop_sound
This commit is contained in:
parent
63dd92259b
commit
d0142f1d67
|
@ -11,6 +11,7 @@ pub mod swf {
|
|||
|
||||
pub type AudioStreamHandle = Index;
|
||||
pub type SoundHandle = Index;
|
||||
pub type SoundInstanceHandle = Index;
|
||||
|
||||
type Error = Box<dyn std::error::Error>;
|
||||
|
||||
|
@ -35,7 +36,9 @@ pub trait AudioBackend {
|
|||
|
||||
/// Starts playing a sound instance that is not tied to a MovieClip timeline.
|
||||
/// In Flash, this is known as an "Event" sound.
|
||||
fn start_sound(&mut self, sound: SoundHandle, settings: &swf::SoundInfo);
|
||||
fn start_sound(&mut self, sound: SoundHandle, settings: &swf::SoundInfo)
|
||||
-> SoundInstanceHandle;
|
||||
|
||||
fn start_stream(
|
||||
&mut self,
|
||||
clip_id: crate::prelude::CharacterId,
|
||||
|
@ -44,6 +47,10 @@ pub trait AudioBackend {
|
|||
handle: &swf::SoundStreamHead,
|
||||
) -> AudioStreamHandle;
|
||||
|
||||
/// Stops a playing sound instance.
|
||||
/// No-op if the sound is not playing.
|
||||
fn stop_sound(&mut self, sound: SoundInstanceHandle);
|
||||
|
||||
/// Stops a playing stream souund.
|
||||
/// Should be called whenever a MovieClip timeline stops playing or seeks to a new frame.
|
||||
fn stop_stream(&mut self, stream: AudioStreamHandle);
|
||||
|
@ -100,7 +107,11 @@ impl<T: AudioBackend + ?Sized> AudioBackend for Box<T> {
|
|||
fn preload_sound_stream_end(&mut self, clip_id: swf::CharacterId) {
|
||||
self.deref_mut().preload_sound_stream_end(clip_id)
|
||||
}
|
||||
fn start_sound(&mut self, sound: SoundHandle, settings: &swf::SoundInfo) {
|
||||
fn start_sound(
|
||||
&mut self,
|
||||
sound: SoundHandle,
|
||||
settings: &swf::SoundInfo,
|
||||
) -> SoundInstanceHandle {
|
||||
self.deref_mut().start_sound(sound, settings)
|
||||
}
|
||||
fn start_stream(
|
||||
|
@ -114,6 +125,10 @@ impl<T: AudioBackend + ?Sized> AudioBackend for Box<T> {
|
|||
.start_stream(clip_id, clip_frame, clip_data, handle)
|
||||
}
|
||||
|
||||
fn stop_sound(&mut self, sound: SoundInstanceHandle) {
|
||||
self.deref_mut().stop_sound(sound)
|
||||
}
|
||||
|
||||
fn stop_stream(&mut self, stream: AudioStreamHandle) {
|
||||
self.deref_mut().stop_stream(stream)
|
||||
}
|
||||
|
@ -156,7 +171,13 @@ impl AudioBackend for NullAudioBackend {
|
|||
Ok(self.sounds.insert(()))
|
||||
}
|
||||
|
||||
fn start_sound(&mut self, _sound: SoundHandle, _sound_info: &swf::SoundInfo) {}
|
||||
fn start_sound(
|
||||
&mut self,
|
||||
_sound: SoundHandle,
|
||||
_sound_info: &swf::SoundInfo,
|
||||
) -> SoundInstanceHandle {
|
||||
SoundInstanceHandle::from_raw_parts(0, 0)
|
||||
}
|
||||
|
||||
fn start_stream(
|
||||
&mut self,
|
||||
|
@ -167,6 +188,9 @@ impl AudioBackend for NullAudioBackend {
|
|||
) -> AudioStreamHandle {
|
||||
self.streams.insert(())
|
||||
}
|
||||
|
||||
fn stop_sound(&mut self, _sound: SoundInstanceHandle) {}
|
||||
|
||||
fn stop_stream(&mut self, stream: AudioStreamHandle) {
|
||||
self.streams.remove(stream);
|
||||
}
|
||||
|
|
|
@ -1684,7 +1684,9 @@ impl<'gc, 'a> MovieClipData<'gc> {
|
|||
// The sound event type is controlled by the "Sync" setting in the Flash IDE.
|
||||
match start_sound.sound_info.event {
|
||||
// "Event" sounds always play, independent of the timeline.
|
||||
SoundEvent::Event => context.audio.start_sound(handle, &start_sound.sound_info),
|
||||
SoundEvent::Event => {
|
||||
context.audio.start_sound(handle, &start_sound.sound_info);
|
||||
}
|
||||
|
||||
// "Start" sounds only play if an instance of the same sound is not already playing.
|
||||
SoundEvent::Start => {
|
||||
|
|
|
@ -3,7 +3,9 @@ use generational_arena::Arena;
|
|||
use ruffle_core::backend::audio::decoders::{
|
||||
self, AdpcmDecoder, Mp3Decoder, PcmDecoder, SeekableDecoder,
|
||||
};
|
||||
use ruffle_core::backend::audio::{swf, AudioBackend, AudioStreamHandle, SoundHandle};
|
||||
use ruffle_core::backend::audio::{
|
||||
swf, AudioBackend, AudioStreamHandle, SoundHandle, SoundInstanceHandle,
|
||||
};
|
||||
use ruffle_core::tag_utils::SwfSlice;
|
||||
use std::io::Cursor;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
@ -351,7 +353,11 @@ impl AudioBackend for CpalAudioBackend {
|
|||
sound_instances.remove(stream);
|
||||
}
|
||||
|
||||
fn start_sound(&mut self, sound_handle: SoundHandle, settings: &swf::SoundInfo) {
|
||||
fn start_sound(
|
||||
&mut self,
|
||||
sound_handle: SoundHandle,
|
||||
settings: &swf::SoundInfo,
|
||||
) -> SoundInstanceHandle {
|
||||
let sound = &self.sounds[sound_handle];
|
||||
let data = Cursor::new(VecAsRef(Arc::clone(&sound.data)));
|
||||
// Create a signal that decodes and resamples the sound.
|
||||
|
@ -375,7 +381,12 @@ impl AudioBackend for CpalAudioBackend {
|
|||
clip_id: None,
|
||||
signal,
|
||||
active: true,
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
fn stop_sound(&mut self, sound: SoundInstanceHandle) {
|
||||
let mut sound_instances = self.sound_instances.lock().unwrap();
|
||||
sound_instances.remove(sound);
|
||||
}
|
||||
|
||||
fn stop_all_sounds(&mut self) {
|
||||
|
|
|
@ -3,7 +3,9 @@ use fnv::FnvHashMap;
|
|||
use generational_arena::Arena;
|
||||
use ruffle_core::backend::audio::decoders::{AdpcmDecoder, Mp3Decoder};
|
||||
use ruffle_core::backend::audio::swf::{self, AudioCompression};
|
||||
use ruffle_core::backend::audio::{AudioBackend, AudioStreamHandle, SoundHandle};
|
||||
use ruffle_core::backend::audio::{
|
||||
AudioBackend, AudioStreamHandle, SoundHandle, SoundInstanceHandle,
|
||||
};
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::rc::Rc;
|
||||
use wasm_bindgen::{closure::Closure, prelude::*, JsCast};
|
||||
|
@ -129,7 +131,7 @@ impl WebAudioBackend {
|
|||
&mut self,
|
||||
handle: SoundHandle,
|
||||
settings: Option<&swf::SoundInfo>,
|
||||
) -> SoundHandle {
|
||||
) -> SoundInstanceHandle {
|
||||
let sound = self.sounds.get(handle).unwrap();
|
||||
match &sound.source {
|
||||
SoundSource::AudioBuffer(audio_buffer) => {
|
||||
|
@ -640,8 +642,12 @@ impl AudioBackend for WebAudioBackend {
|
|||
}
|
||||
}
|
||||
|
||||
fn start_sound(&mut self, sound: SoundHandle, sound_info: &swf::SoundInfo) {
|
||||
self.start_sound_internal(sound, Some(sound_info));
|
||||
fn start_sound(
|
||||
&mut self,
|
||||
sound: SoundHandle,
|
||||
sound_info: &swf::SoundInfo,
|
||||
) -> SoundInstanceHandle {
|
||||
self.start_sound_internal(sound, Some(sound_info))
|
||||
}
|
||||
|
||||
fn start_stream(
|
||||
|
@ -691,6 +697,17 @@ impl AudioBackend for WebAudioBackend {
|
|||
}
|
||||
}
|
||||
|
||||
fn stop_sound(&mut self, sound: SoundInstanceHandle) {
|
||||
SOUND_INSTANCES.with(|instances| {
|
||||
let mut instances = instances.borrow_mut();
|
||||
if let Some(mut instance) = instances.remove(sound) {
|
||||
if let SoundInstanceType::AudioBuffer(ref mut node) = instance.instance_type {
|
||||
let _ = node.disconnect();
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn stop_stream(&mut self, stream: AudioStreamHandle) {
|
||||
SOUND_INSTANCES.with(|instances| {
|
||||
let mut instances = instances.borrow_mut();
|
||||
|
|
Loading…
Reference in New Issue