You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A reworking of #22753, which "improves the copy back from the audio
worklet's heap to JS by 7-12x depending on the browser." From the
previous description:
Since we pass in the stack for the worklet from the caller's heap, its
address doesn't change. And since the render quantum size doesn't change
after the audio worklet creation, the stack positions for the audio
buffers do not change either. This optimisation adds one-time subarray
views and replaces the float-by-float copy with a simple `set()` per
channel (per output).
The existing interactive tests (written for the original PR) can be run
for comparison:
```
test/runner interactive.test_audio_worklet_stereo_io
test/runner interactive.test_audio_worklet_2x_stereo_io
test/runner interactive.test_audio_worklet_mono_io
test/runner interactive.test_audio_worklet_2x_hard_pan_io
test/runner interactive.test_audio_worklet_params_mixing
test/runner interactive.test_audio_worklet_memory_growth
test/runner interactive.test_audio_worklet_hard_pans
```
These test various input/output arrangements as well as parameters
(parameters are interesting because, depending on the browser, the sizes
change as the params move from static to varying).
The original benchmark of the extracted copy is still valid:
https://wip.numfum.com/cw/2024-10-29/index.html
This is tested with 32- and 64-bit wasm (which required a reordering of
how structs and data were stored to avoid alignment issues).
Some explanations:
- Fixed-position output buffer views are created once in
the`WasmAudioWorkletProcessor` constructor
- Stack allocations for the `process()` call are split into aligned
struct data (see the comments) and audio/param data
- The struct writes are simplified by this splitting of data
- `ASSERTIONS` are used to ensure everything fits and correctly aligns
- The tests account for size changes in the params, which can vary from
a single float to 128 floats (a single float nicely showing up any
8-byte alignment issues for wasm64)
~~Future improvements: the output views are sequential, so instead of of
being individual views covering each channel the views could cover one
to however-many-views needed, with a single `set()` being enough for all
outputs.~~
console.log(`AudioWorklet creating ${this.outputViews.length} buffer one-time views (for a stack size of ${wwParams.stackSize} at address ${ptrToString(viewDataIdx*4)})`);
72
+
#endif
73
+
// Inserted in reverse so the lowest indices are closest to the stack top
console.assert(oldStackPtr==this.ctorOldStackPtr,'AudioWorklet stack address has unexpectedly moved');
129
+
console.assert(outputViewsNeeded<=this.outputViews.length,`Too many AudioWorklet outputs (need ${outputViewsNeeded} but have stack space for ${this.outputViews.length})`);
130
+
#endif
131
+
132
+
// Allocate the necessary stack space. All pointer variables are in bytes;
133
+
// 'structPtr' starts at the first struct entry (all run sequentially)
134
+
// and is the working start to each record; 'dataPtr' is the same for the
135
+
// audio/params data, starting after *all* the structs.
136
+
// 'structPtr' begins 16-byte aligned, allocated from the internal
137
+
// _emscripten_stack_alloc(), as are the output views, and so to ensure
138
+
// the views fall on the correct addresses (and we finish at stacktop) we
139
+
// request additional bytes, taking this alignment into account, then
0 commit comments