Skip to content

Conversation

kettle11
Copy link
Contributor

@kettle11 kettle11 commented Mar 1, 2025

This pull request adds an optional feature-flagged Host that uses AudioWorklet on web when the atomics feature is enabled. When the web_audio_worklet and wasm-bindgen features are enabled and nightly Rust is compiled with the atomics flag enabled the WebAudioWorklet Host is available.

AudioWorklet should be lower latency, lower overhead, and less prone to jank. This implementations works pretty much the same as a native audio thread, allowing the implementation to be simpler than the existing WebAudio Host implementation.

To used shared memory it's also required (for security reasons) that the server hosting the Wasm to be configured with the correct CORS headers. I've added an example that shows how to build with the correct Rust flags and how to set the Cors headers in a test environment.

So far I've tested this in Chrome, Safari, and Firefox with the beep example and it seems to be working fine.

Edit: I'm not sure why a past merged PR shows up in Github's listed commits, but it seems to have no impact on this PR.

@roderickvd
Copy link
Collaborator

Very nice addition! This is a big one, so I'm gonna first trigger a Copilot review to walk through major points, if any, then do a further code review.

Apologies for the late response - new collaborator here and grooming through the backlog now.

Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This pull request adds AudioWorklet support for web audio in CPAL, providing a lower-latency, lower-overhead alternative to the existing WebAudio host when WebAssembly atomics are enabled. The implementation leverages shared memory between the main thread and audio worklet thread, allowing for more efficient audio processing similar to native platforms.

  • Introduces a new web_audio_worklet feature flag and host implementation
  • Adds JavaScript worklet processor code that interfaces with WebAssembly
  • Provides an example demonstrating the setup requirements and usage

Reviewed Changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/platform/mod.rs Adds conditional compilation for WebAudioWorklet host alongside existing WebAudio host
src/host/web_audio_worklet/mod.rs Core implementation of the AudioWorklet-based host with stream management
src/host/web_audio_worklet/worklet.js JavaScript AudioWorkletProcessor that interfaces with WASM audio processing
src/host/web_audio_worklet/dependent_module.rs Utility for dynamically loading JavaScript modules in AudioWorklet context
src/host/mod.rs Adds conditional module inclusion for web_audio_worklet
examples/web-audio-worklet-beep/* Complete example showing usage with required configuration
Cargo.toml Adds web_audio_worklet feature with necessary web-sys dependencies
Comments suppressed due to low confidence (1)

src/host/web_audio_worklet/worklet.js:1

  • [nitpick] The class name WasmProcessor is generic and could conflict with other WASM processors. Consider using a more specific name like CpalWasmProcessor to match the registered processor name.
registerProcessor("CpalProcessor", class WasmProcessor extends AudioWorkletProcessor {

@kettle11
Copy link
Contributor Author

kettle11 commented Aug 7, 2025

Thanks for following up!

I applied some of Copilot's suggestions and also realized that some files needed to build the example were missing so I fixed that as well. Let me know if anything further is needed.

Copy link
Collaborator

@roderickvd roderickvd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks very, very nice. Super to see such an exhaustive example too.

rustflags = ["-C", "target-feature=+atomics"]

[unstable]
build-std = ["std", "panic_abort"]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it have to abort? Could we leave that choice to the user?

Copy link
Contributor Author

@kettle11 kettle11 Aug 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think right now when using multiple threads and atomics panic has to be set to abort. I can't remember the exact reason, but if I try to disable the flag there are cryptic build errors. Searching online doesn't turn up anything quickly. I think it's an area that's under documented right now because few people are using multithreaded WebAssembly with Rust.

For now I think leaving this as-is makes the most sense.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, thanks for looking into it.

@spookyvision

This comment was marked as off-topic.

@roderickvd

This comment was marked as resolved.

* Update README to reference AudioWorklet usage
* Attribute authorship of AudioWorklet example
* Remove unwraps in example code
* Choose Apache 2.0 license for copied code
* Correctly report if the AudioWorklet host is available
* Fix incorrect module reference
* Correct 2 errors introduced in previous commit
@kettle11
Copy link
Contributor Author

OK, I made a series of fixes to respond to comments and caught a few other things in the process. Thanks for the review!

@roderickvd
Copy link
Collaborator

Thanks for the update! In the meantime a few conflicts came up because the platform implementation was changed (but simplified 😄 ) so if you could resolve those?

Then I’ll be out in the coming days so hope to have more time to look into it again over the weekend.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants