-
Notifications
You must be signed in to change notification settings - Fork 411
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support using wasm-pack in Worklets (particularly AudioWorklet) #689
Comments
Thanks for the report! Can you clarify why |
Sure. Thanks for the quick response! Using
Using There is a another problem, considering the Javascript wrapper code would be set up in the AudioWorklet context, and neither classes nor functions can be passed across the AudioWorklet's MessagePort. It would be really cool if wasm-pack included a protocol for calling its exported functions & classes across a MessagePort boundary (maybe with a new If I could at least use the wrapper code within the worklet, I think it would be a reasonable task for me to write some bridge code to load the generated wrappers in both the worklet and main thread, and pass arguments, object ids, and method/function names as well as return values through the MessagePort, which supports sending number, string, array, and object types. I've successfully implemented such an interface using raw FFI, and it seems to work quite well. However, not being able to import the generated javascript within the worklet thread means missing out on all of wasm-bindgen's type conversion goodness and being limited to numeric arguments & return types. It also means I have to maintain my own Typescript api interface rather than being able to use auto-generated types. This introduces a big point of failure if the exported Rust functions and wrapper typings get out of sync. |
Oh the problem with I agree that we could perhaps explore more extensive integration with audio worklets, but if |
The --target web cannot be used with audioworklet without important modification of the generated file .
Workarounds:
Ideally, i would like to be able to implement all the patterns from this article (audioworklet and wasm)
I've decided to continue on this issue. But if preferred, i can open another issue. thx ps: I think dynamic import are not allowed inside AudioWorkletGlobalScope (See issue 506) |
@BenoitDel Could you elaborate a little bit on the workarounds? I'm having a hard time with audio worklets and wasm-pack too. Currently I can only directly instantiate a WebAssembly.Instance by passing the raw bytes of the wasm file (fetched on the main thread) via the postMessage function on the AudioWorkletProcessor subclass, like in this example. This is very limiting, since strings don't work and calling JS functions from Rust is also impossible. I would love to learn some more about your workarounds! |
I do it the same way as you do. ( I am not working on this part of my project for now, but i will in 2-3 weeks. If i find how to implement the other pattern i will tell you about it). |
Interesting, thanks for the quick reply! The way I did it so far is by ignoring all JS boiler plate and just straight up fetching the data from the |
What a coincidence. I started to work on my first project in the audio domain, including rust and wasm and I currently have the same problem. I have not enough experience with rust, warm, and wasm-pack to help with this issue, but I'm happy to contribute when I learned more about the topic and architecture. @w-ensink here is a sample project https://github.com/the-drunk-coder/ruffbox. He uses enums to map parameters. This might be an option to replace the strings while still maintaining readability |
@cconnection Hey man! I had indeed seen that example, it was one of my goto's to get things working with Rust and AudioWorklets. Enums are a good option for small processors, but I'm trying to build a bigger, more dynamic project and then they're not a real option unfortunately. |
I have started to experiment with the The main problem is that we aren't allowed to fetch wasm code asynchronously inside the audio worklet, so we have to fetch the wasm file outside of the worklet and send it to the worklet via postMessage(). When you look on the code generated by
Currently, I try to split out the fetch function from the init, so that I can fetch the wasm file outside the worker and do the rest of the init process in the worklet with all wasm-pack / wasm-bindgen features. A first prototype looks like this wasm-pack.js
Now I can use it like this in the index.html and audio.js
Now I run into one problem. I get the following message:
First I thought that it is related to audio worklet, but actually I get the same error when using the normal output from
|
I think there is no notion of import in worklet.
|
The import works, I can call getImports and see console.logs. same for the init. |
What also might be interesting to note, is that the import works with the Emscripten version too, as can be seen in this example from Google. |
Yes, you re right it is just dynamic import (i hope this time i am right) that is not supported. Static import is in the specs and works in chromium (at least). Sorry for the mistake. |
I just managed to have a working prototyp, including strings. At the end, wasm-pack generates glue code which decodes and encodes the uint8arrays to a javascript string in UTF-8 and back. Currently, my prototyp is a complete manual editing of the generated code. So I can't build a new version with wasm-pack because the code will be overwritten. The next steps: I don't know enough about wasm-bindgen and wasm-pack, so I'm not sure if its a bindgen problem or wasm-pack problem or both. Maybe @alexcrichton can help us to go to the right direction? I can provide a sample project to show how the current code looks like. Update: |
Ah if worklets have such a restrictive environment then yes, we'd need to add a new target to wasm-bindgen which included the above shim or somehow referenced it. |
@alexcrichton how do we continue here? Should we open an issue in the wasm-bindgen repo? Is it possible to help integrating it into wasm-bindgen? |
Yeah I think it's best to have either an issue or a PR to wasm-bindgen to figure out the best way to move forward. |
Well, is there any real workaround for this? |
Unfortunately, I was not able to use wasm-pack due to this issue. What I ended up doing is:
While this was pretty painful to figure out, it does give you all the benefits of wasm-bindgen in an AudioWorklet context, and the DX is pretty good once everything's set up. Hopefully this can provide some inspiration for a new wasm-pack mode for AudioWorklets, but there's some more work needed to arrive at an implementation that's generic enough to provide in a library, and supports all the various bundlers people might be using. |
I also got things working similarly to how @Smona describes. I tried to package it up to make this process easier for myself in the future https://github.com/Marcel-G/waw-rs |
💡 Feature description
One of the key use cases for WebAssembly is audio processing. wasm-pack doesn't currently support AudioWorklets (purportedly the future of custom audio processing on the web) with any of its current
--target
options.The
web
andno-modules
targets get close, but error out during instantiation because the AudioWorklet context is lacking several browser APIs which the JS wrappers expect. This problem may extend to other Worker/Worklet contexts, but I've only attempted this with AudioWorklets.💻 Basic example
my_processor.worklet.js
The text was updated successfully, but these errors were encountered: