RustAudio / cpal

Cross-platform audio I/O library in pure Rust
Apache License 2.0
2.73k stars 364 forks source link

Choppy sound when running through WASM on high-end mobile devices #780

Open Chiplis opened 1 year ago

Chiplis commented 1 year ago

Hey guys! I've been working on a GameBoy emulator which runs on the web: https://nicolas-siplis.com/ironboy/

I've been using Pixels + Winit + CPAL for handling video, audio and inputs and so far this has worked perfectly fine on all platforms I tested, including the web!

... Except on mobile devices. For some reason audio always seems choppy when running on mobile, and though I've tried I can't seem to pinpoint why it might be happening. It's hard to run things like flamegraph when you're debugging a mobile device, so I'm sort of at my wit's end.

If you want to take a look at the source code for the project (which isn't doing anything fancy with CPAL, AFAICT), check out https://github.com/nicolas-siplis/IronBoy/blob/master/src/apu.rs

w-ensink commented 1 year ago

The web implementation of CPAL is pretty hacky and is rendering on the main thread. I wouldn't expect much from it. WebAudio is just terrible when it comes to WASM support.

Chiplis commented 1 year ago

The web implementation of CPAL is pretty hacky and is rendering on the main thread. I wouldn't expect much from it. WebAudio is just terrible when it comes to WASM support.

Is there something that makes rendering on a WebWorker a non viable option? I have no idea how the web implementation of CPAL works under the hood, but I can try and work on that assuming it's not a deal breaker for some reason.

w-ensink commented 1 year ago

I haven't looked at it for a while, but I do remember it was very hard. If I remember correctly, for it to work as intended you need to load a AudioWorkletProcessor into a AudioWorkletNode. This AudioWorkletProcessor needs to be it's own plain JavaScript module, which in turn needs to load the wasm binary with the processing code. And all interaction needs to go via some kind of channel. This is very hard (if not impossible) to do via the Cpal api, because you'd expect the api to be available in the main module and you expect to write the audio processing code there as well.