Skip to content

Commit 24a90e4

Browse files
committed
Create one-time fixed views into the heap
We can remove the float-by-float JS copy and replace with this simple TypedArray set() calls.
1 parent 0b70098 commit 24a90e4

File tree

1 file changed

+23
-11
lines changed

1 file changed

+23
-11
lines changed

src/audio_worklet.js

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ function createWasmAudioWorkletProcessor(audioParams) {
3737
// 'render quantum size', and this exercise of passing in the value
3838
// shouldn't be required (to be verified).
3939
this.samplesPerChannel = opts['sc'];
40+
// Typed views of the output buffers on the worklet's stack, which after
41+
// creation should not change (since the stack is passed externally once).
42+
this.outputViews = null;
4043
}
4144

4245
static get parameterDescriptors() {
@@ -64,9 +67,6 @@ function createWasmAudioWorkletProcessor(audioParams) {
6467

6568
// Allocate the necessary stack space.
6669
inputsPtr = stackAlloc(stackMemoryNeeded);
67-
#if WEBAUDIO_DEBUG
68-
console.log(`WasmAudioWorkletProcessorr::process() ${inputsPtr} (needed: ${stackMemoryNeeded})`);
69-
#endif
7070

7171
// Copy input audio descriptor structs and data to Wasm
7272
k = inputsPtr >> 2;
@@ -97,6 +97,20 @@ function createWasmAudioWorkletProcessor(audioParams) {
9797
// Reserve space for the output data
9898
dataPtr += bytesPerChannel * i.length;
9999
}
100+
if (!this.outputViews) {
101+
this.outputViews = [];
102+
k = outputDataPtr;
103+
for (/*which output*/ i of outputList) {
104+
for (/*which channel*/ j of i) {
105+
this.outputViews.push({
106+
// dataPtr is the sanity check (to be implemented)
107+
// dataSub is the one-time subarray into the heap
108+
dataPtr: k,
109+
dataSub: HEAPF32.subarray(k, k += this.samplesPerChannel)
110+
});
111+
}
112+
}
113+
}
100114

101115
// Copy parameters descriptor structs and data to Wasm
102116
paramsPtr = dataPtr;
@@ -115,14 +129,12 @@ function createWasmAudioWorkletProcessor(audioParams) {
115129
// Call out to Wasm callback to perform audio processing
116130
if (didProduceAudio = this.callbackFunction(numInputs, inputsPtr, numOutputs, outputsPtr, numParams, paramsPtr, this.userData)) {
117131
// Read back the produced audio data to all outputs and their channels.
118-
// (A garbage-free function TypedArray.copy(dstTypedArray, dstOffset,
119-
// srcTypedArray, srcOffset, count) would sure be handy.. but web does
120-
// not have one, so manually copy all bytes in)
121-
for (/*which output*/ i of outputList) {
122-
for (/*which channel Float32Array<samplesPerChannel>*/ j of i) {
123-
for (/*channel index*/ k = 0; k < this.samplesPerChannel; ++k) {
124-
j[k] = HEAPF32[outputDataPtr++];
125-
}
132+
// The 'outputViews' are subarray views into the heap, each with the
133+
// correct offset and size to be copied directly into the output.
134+
k = 0;
135+
for (i of outputList) {
136+
for (j of i) {
137+
j.set(this.outputViews[k++].dataSub);
126138
}
127139
}
128140
}

0 commit comments

Comments
 (0)