avm1: Add is_streaming flag to Sound

`Sound.loadSound` with `isStreaming` of true causes any previously
playing audio on the same object to be stopped.
This commit is contained in:
Mike Welsh 2022-09-05 23:38:07 -07:00
parent dec4e30655
commit f438e2032f
2 changed files with 29 additions and 0 deletions

View File

@ -86,6 +86,7 @@ fn attach_sound<'gc>(
.character_by_export_name(name)
{
sound_object.set_sound(activation.context.gc_context, Some(*sound));
sound_object.set_is_streaming(activation.context.gc_context, false);
sound_object.set_duration(
activation.context.gc_context,
activation
@ -251,6 +252,14 @@ fn load_sound<'gc>(
.get(1)
.unwrap_or(&Value::Undefined)
.as_bool(activation.swf_version());
if is_streaming {
// Streaming MP3s can only have a single active instance.
// (Previous `attachSound` instances will continue to play.)
if let Some(sound_instance) = sound.sound_instance() {
activation.context.stop_sound(sound_instance);
}
}
sound.set_is_streaming(activation.context.gc_context, is_streaming);
let future = activation.context.load_manager.load_sound_avm1(
activation.context.player.clone(),
sound,
@ -384,6 +393,12 @@ pub fn start<'gc>(
use swf::{SoundEvent, SoundInfo};
if let Some(sound_object) = this.as_sound_object() {
if let Some(sound) = sound_object.sound() {
if sound_object.is_streaming() {
// Streaming MP3s can only have a single active instance.
if let Some(sound_instance) = sound_object.sound_instance() {
activation.context.stop_sound(sound_instance);
}
}
let sound_instance = activation.context.start_sound(
sound,
&SoundInfo {

View File

@ -37,6 +37,11 @@ pub struct SoundObjectData<'gc> {
/// Duration of the currently attached sound in milliseconds.
duration: Option<u32>,
/// Whether this sound is an external streaming MP3.
/// This will be true if `Sound.loadSound` was called with `isStreaming` of `true`.
/// A streaming sound can only have a single active instance.
is_streaming: bool,
}
impl fmt::Debug for SoundObject<'_> {
@ -64,6 +69,7 @@ impl<'gc> SoundObject<'gc> {
owner: None,
position: 0,
duration: None,
is_streaming: false,
},
))
}
@ -115,6 +121,14 @@ impl<'gc> SoundObject<'gc> {
pub fn set_position(self, gc_context: MutationContext<'gc, '_>, position: u32) {
self.0.write(gc_context).position = position;
}
pub fn is_streaming(self) -> bool {
self.0.read().is_streaming
}
pub fn set_is_streaming(self, gc_context: MutationContext<'gc, '_>, is_streaming: bool) {
self.0.write(gc_context).is_streaming = is_streaming;
}
}
impl<'gc> TObject<'gc> for SoundObject<'gc> {