-
Notifications
You must be signed in to change notification settings - Fork 167
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] Bring Your Own Buffer style of memory management #2442
Comments
The conversation from TPAC: |
Teleconf: Probably a duplicate of #2427, which has more detail on AudioWorklet and WASM. |
The outcome from TPAC 2020: This is not an exact duplicate of #2427. This can be applied to non-WASM use cases as well. With both improvements, the performance of Audio Worklet can be certainly improved. What's being proposed is to call something like Also a callback function like |
Discussed during the AudioWG online F2F, some pseudo-code that show how this could work (just a proposal, nothing concrete, drafted while talking during the call): partial interface AudioWorkletProcessor {
enum BufferType {
INPUT = 1,
OUTPUT = 2
};
// indicates that this memory will be used by the AudioWorklet -- don't touch it yourself
// variant: register just the output, just the input.
// This can be called in the ctor, or while process is running to provide the output from something already computed
registerBuffers(ArrayBuffer memory, uint64_t offset, uint64_t maxLength, type = INPUT|OUTPUT);
// Called when the input or output channel count changes for whatever reason
// you can accept or deny the request. In case of error, `process` isn't called anymore
channelTopologyChange = function(ArrayBuffer memory, uint64_t offset, uint64_t newMaxLength) {
// return false; // reject the change request: audio will be down/up mixed to the previous topology
// find some memory in already allocated space/allocate new memory
return {
memory: memory,
offset: new_offset,
maxLength: new_max_length
type: INPUT
};
}
} then the memory backing the arrays in Being able to call |
This would be a great issue to discuss across groups as TPAC 2021 |
I did recently write an implementation that enables multithreaded Wasm code to define AudioWorkletProcessors and instantiate AudioWorkletNodes from Wasm. The branch can be found here: https://github.com/juj/emscripten/compare/wasm_workers...juj:audio_worklets?expand=1 The intent is to bring the support in to core Emscripten in the near future. The benefit of that branch with respect to this github issue is probably to concretely show what the JS<->Wasm marshalling copying overhead currently looks like, see the In the implementation explicit care was taken to make the marshalling as "tight" as possible with minimized JS overhead (use Wasm thread stack space to avoid mallocs, minimize excess computation or abstractions in JS). So far we don't unfortunately have any data to know how much that marshalling performance overhead is in general. For a small tone generator C program example of how one would use that API, see the end of the PR, tests/webaudio/tone_generator.c. |
I use Open Frameworks with Emscripten, and try to replace scriptprocessornode with audioworklet. This is how I import the memory:
This is the Audioworklet: `
} I think, my problem would be solved, if I could call |
@Jonathhhan check out the audio_worklets branch in my Emscripten Github repo. In particular, the commit juj/emscripten@4aa53f4 . That achieves such a shared setup where the main wasm application can run on the main browser thread, and create wasm-based audioworklet nodes that call to a custom wasm function entry point for audio processing. |
@juj thank you. I will try that soon. Yesterday I had success with the solution from @tklajnscek emscripten-core/emscripten#12502 would be really great, if audioworklets will become a standard feature of Emscripten. |
@juj Yes, that would be a huge improvement. Is a PR being reviewed somewhere? Is there something Audio WG can help/support? |
@juj I tried your tone_generator.c example like this:
Did I make mistake with the flags? |
No, that does look good. Tried it now and I don't get any issue. I am on commit
and build with
which generates
Then running on an ad hoc web server on localhost I do get the tone generator running. The error you print seems as if the command line directive function emscriptenGetAudioObject(objectHandle) {
return EmAudio[objectHandle];
} Zipped the build here, which does work for me on Windows in Chrome and Firefox Also pushed a commit to the branch that improves some assertions and error checks for e.g. the scenario when the browser does not support AudioWorklets at all. |
There is no PR yet, I am working on the prerequisite wasm workers PR first to build the necessary scaffolding to get audio worklets in the tree. |
@juj thanks. It works, if I paste:
manually. |
oh wait, this is probably a Windows vs macOS/Linux build issue: you must be on a Unix-like OS with a bash-like shell? There
will cause If you build by passing either
or
does that work? (not sure which of those escapes a $ character on cmdline, quick google search didn't find a hit either) |
@juj thanks a lot. |
Any updates on this |
This comment was marked as off-topic.
This comment was marked as off-topic.
2023 TPAC Audio WG Discussion: |
I now only finally paused to think about @padenot 's code snippet above (#2442 (comment)). Not sure if the thinking has evolved since it has been a long time, but I was puzzled over the My understanding is that And the handler of that It looks like the proposed handler there I.e. something like
This way the code would look similar to first allocation, and subsequent reallocations. One note is that there might be a big challenge to users with respect to multithreading safe memory allocation inside That could be achieved by making sure that |
@juj Thanks so much for detailed comment! We'll review and respond soon. |
@juj, I agree with everything you said in your comment: the API proposal and the caveat about this potentially requiring a multi-thread aware allocator (if the heap is shared between multiple threads, that is). I had over-allocation in mind when proposing the above, because this is typically how this can be/is solved in native. Sometimes you allocate a bit more upfront, or also in other cases when it goes from stereo to mono you don't free the second buffer. |
Discussing with WebAssembly group, we've been talking about having an alternate approach to managing the buffers used to communicate data between an AudioWorkletProcessor and the rendering thread environment (
input
,output
andparameters
buffers). It would be better for WASM in many ways if we allowed the AWP code to respond to the needs of the environment by providing its own buffers, rather than having to work with JS buffers or views provided from outside. This would eliminate the number of copies and make for a very direct WebAssembly/Web Audio connection.The text was updated successfully, but these errors were encountered: