Skip to content

avm2: support SampleDataEvent dynamic audio - #24762

Closed
cmdocmd wants to merge 1 commit into
ruffle-rs:masterfrom
cmdocmd:avm2-sound-sample-data
Closed

cmdocmd wants to merge 1 commit into
ruffle-rs:masterfrom
cmdocmd:avm2-sound-sample-data

Conversation

@cmdocmd

@cmdocmd cmdocmd commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

Description

Previously, Ruffle did not support AVM2 dynamically generated audio through SampleDataEvent.SAMPLE_DATA. The callback could run, but the generated samples were not sent to the audio mixer, so tools such as SiON/VMML were silent.

This PR adds dynamic SampleDataEvent audio support by:

dispatching SAMPLE_DATA events for dynamic Sound objects
reading generated stereo float32 samples from the callback ByteArray
feeding them into the audio mixer at 44.1 kHz
tracking sample positions and startTime
supporting short final blocks, SOUND_COMPLETE, SoundChannel.stop(), SoundMixer.stopAll(), and multiple dynamic sounds

The behavior was compared against Adobe Flash Player. Stable observable behavior now matches Flash, including sample positions, ByteArray reuse, varying block sizes, stream completion, stereo output, multiple sounds, and startTime offsets.

One timing-dependent difference remains: Flash may request multiple SAMPLE_DATA blocks before Sound.play() returns. This varies with buffering/platform timing, so Ruffle intentionally does not hardcode a fixed number of synchronous callbacks.

The VMML reproduction from #20302 was also tested with a locally built Ruffle browser extension, and the Play button now works with music playback.

Fixes #20302

Testing

Added a new AVM2 SWF regression test:

tests/tests/swfs/avm2/sound_sample_data/

Its expected output was generated from Adobe Flash Player.

Checks run successfully:

cargo check -p ruffle_core
cargo test -p tests --test tests -- sound_sample_data --nocapture
git diff --check

Existing related AVM2 sound tests and a broader sound regression sweep were also run successfully.

Checklist

  • I, a human, have self-reviewed this PR and fully understand the changes within.
  • I have made or updated tests where possible.
  • All of my commits are properly scoped, compile successfully, and pass all tests.
  • This PR does not make sense to split up into smaller PRs.
  • An LLM was involved in the authoring of this code.

@torokati44

Copy link
Copy Markdown
Member

See also: #14203

@cmdocmd
cmdocmd force-pushed the avm2-sound-sample-data branch from ada5f05 to fde2e47 Compare September 23, 2026 08:34
@cmdocmd

cmdocmd commented Sep 23, 2026

Copy link
Copy Markdown
Contributor Author

See also: #14203

Thanks for the pointer. I compared this with the previous SampleDataEvent work.

The regression test now covers the key Flash behaviors, including ByteArray reuse, varying block sizes, stream completion, stop/stopAll, multiple sounds, startTime offsets, generated-sound lifecycle, and the 32-sound limit.

The comparison also caught one missing behavior here: after a Sound becomes generated, load() must throw Error #2037. I verified this in Flash and updated the implementation/test accordingly.

The main remaining difference is callback scheduling before Sound.play() returns, which appears timing/buffering-dependent in Flash, so this PR does not hardcode a fixed callback count.

@cmdocmd

cmdocmd commented Sep 23, 2026

Copy link
Copy Markdown
Contributor Author

Tested it on:
#20302
#7879
#14156

All works.

@cmdocmd

cmdocmd commented Sep 23, 2026

Copy link
Copy Markdown
Contributor Author

I will close this since there is already older PR for this.

@cmdocmd cmdocmd closed this Sep 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Play button doesn't work in music tool VMML

2 participants