-
Notifications
You must be signed in to change notification settings - Fork 168
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
[audioworklet] AudioWorklets integration with WebAssembly #2427
Comments
Do you mean
Does this mean that we have to introduce some PS: The exmaples on Wiki are not up-to-date, so please consider referring the current spec. I'll update the wiki pages so it won't get looked at any more. |
I'm unfamiliar with the basic spec concepts here, so forgive me for imprecise terminology, but I would think that we would register the memory (to use as input/output) once per independent "audio stream" of which there could be multiple per global. Also, I was imagining the registration would pass in the memory as typed arrays which means the API would work for both JS (and similarly be an optimization for JS) and wasm, not semantically caring which was used. One potential problem and a question: judging from the code sample, inputs and outputs aren't simply arrays, but arrays of arrays. If the number of input/output arrays is static, then this seems easy enough to fix, you just register arrays of typed arrays up front. But if the number of arrays is dynamic, something fancier would be required. |
In general, the arrays are dynamic. But if you set up |
Ah, good to hear. Given the complications of a good solution for a dynamic count, perhaps this feature could be stipulated to require or set an explicit channel count. |
Which feature are we talking about here? I think it's critically important that an AudioWorkletNode at least support dynamic channels for a single-input/single-output case. Then it is conceptually possible to define every current node with an AudioWorkletNode. And that's a great indication that the AudioWorklet has minimum set of features to be generally useful in constructing new nodes. |
The feature of (in addition to what currently exists) being able to say up front (before |
Yes, this exactly is AudioWorklet's case. I believe that the 1-in-1-out node will be the majority of use cases.
I think what you're asking might be relevant to this issue. Basically this storage will be a static one, so you can cache it on the global scope then it is accessed by all other objects in the scope. Not a pretty picture. What kind of API are you envisioning? How can we do "I need this memory upfront, but expose it only inside of process() method"? |
One more-specific API idea would be to pass the array-of-typed-arrays for input and output to the Question: does the number of input/output channels only change in direct response to the user calling some JS method/setter or does it ever change implicitly in response to something else? If the former, then perhaps said method for changing the number of channels could also take a new array-of-typed-arrays (matching the new number of channels). Such a method would also allow being called with the same number of channels as before, which would give the user a way to change what what memory was being used at runtime. |
The number of input channels can change by itself, sort of. Say you have an oscillator connected to your worklet. It's mono. Now If this really matters to you (and it seems it does), you can arrange things so that the number of input channels is fixed (using channelCount = desired count, channelCountMode = "explicit"). It's then up to you to figure out if that's really appropriate for you application. |
Ah, I see, thanks. So maybe if you specify your buffers up-front, then that automatically sets channelCount = number-of-given-channels and sets chanelCountMode = "explicit"? |
Currently |
Ah, ok, I was reading Jukka's code in the first comment and thinking these arrays would be passed as arguments to the |
@padenot pinging myself so I answer here tomorrow or something. |
From the WG discussion today:
Our conclusion is that we'd like to defer the issue of optimizing copying to the next version of Web Audio, so we come up with the best of the multiple possible approaches to this problem. In the mean time we'll learn a lot about where the meaningful gaps exist in AudioWorklet in its current form. |
Just noting that we talked directly with the WebAssembly folks about this today at TPAC and resolved to keep working on it, taking a good look in the near future at a "bespoke tailored" connection between AudioWorklet and WASM. |
An extension point to consider when designing new APIs is an alternative |
This comment was marked as off-topic.
This comment was marked as off-topic.
Teleconf: Profiling the cost of copying to and from the WASM heap would be quite interesting. |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
It can be made to work without changing the name of the function, and instead dispatching based on the shape of the second argument. If it's an ES6 class, it has to conform to the required prototype. If it's an object, it needs to have the right keys, and those keys need to be functions. They can have the same names, and be implemented in js or directly in WASM. This clealry ties in to WebAudio/web-audio-api-v2#4. When WebAudio/web-audio-api-v2#4 is solved, then I believe the solution for WebAudio/web-audio-api-v2#5 will come naturally. |
The original example above contains this block: // Compile and Instantiate Wasm Module here, communicate with SharedArrayBuffer with the remaining program
this.wasmModule = ...;
this.wasmInstance = ...;
this.wasmHeap = new Float32Array(...); In practice, you cannot instantiate a Wasm module in a constructor like that, as instantiation is asynchronous, so the exports must be assigned to instance variables in a callback (after the constructor has returned, and possibly after the The Wasm memory can (and often must) be directly created within the constructor, as you cannot (in practice) pass a buffer more than a few MB as an argument (from the main thread) without the audio thread dropping out. See #2269 . |
This would be a great issue to discuss across groups as TPAC 2021 |
This comment was marked as off-topic.
This comment was marked as off-topic.
@juj Since you opened this issue years ago - the WG believes that prioritizing registerBuffer() proposal over this issue is more sensible at this time. What do you think? |
Yes, |
Thank you. Then I will close this issue and the WG will focus on #2442. |
Reading the AudioWorklet reference at /~https://github.com/WebAudio/web-audio-api/wiki/AudioWorklet-Examples and /~https://github.com/WebAudio/web-audio-api/wiki/AudioWorklet-IDL-Proposal, it looks like code that would utilize WebAssembly to render audio in an AudioWorklet would look something like the following:
Talking with WebAssembly developers and @lukewagner, he is suggesting that it would be made possible to register the WebAssembly heap at AudioWorklet construction time, so that one would be able to optimize away the copies on the lines marked with stars
// *
.Would something like this be feasible?
The text was updated successfully, but these errors were encountered: