Skip to content

Commit 4cba21c

Browse files
committed
Recreate views as heap grows
1 parent 3dc85ca commit 4cba21c

File tree

1 file changed

+24
-13
lines changed

1 file changed

+24
-13
lines changed

src/audio_worklet.js

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,36 +35,44 @@ function createWasmAudioWorkletProcessor(audioParams) {
3535
this.samplesPerChannel = opts.samplesPerChannel;
3636
this.bytesPerChannel = this.samplesPerChannel * {{{ getNativeTypeSize('float') }}};
3737

38-
// Create up-front as many typed views for marshalling the output data as
39-
// may be required (with an arbitrary maximum of 64, for the case where a
40-
// multi-MB stack is passed), allocated at the *top* of the worklet's
41-
// stack (and whose addresses are fixed). The 'minimum alloc' firstly
42-
// stops STACK_OVERFLOW_CHECK failing (since the stack will be full, and
43-
// 16 being the minimum allocation size due to alignments) and leaves room
44-
// for a single AudioSampleFrame as a minumum.
38+
// Creates the output views (see createOutputViews() docs)
4539
this.maxBuffers = Math.min(((wwParams.stackSize - /*minimum alloc*/ 16) / this.bytesPerChannel) | 0, /*sensible limit*/ 64);
40+
this.outputViews = [];
4641
#if ASSERTIONS
4742
console.assert(this.maxBuffers > 0, `AudioWorklet needs more stack allocating (at least ${this.bytesPerChannel})`);
4843
#endif
44+
this.createOutputViews();
45+
46+
#if ASSERTIONS
47+
// Explicitly verify this later in process()
48+
this.ctorOldStackPtr = stackSave();
49+
#endif
50+
}
51+
52+
/**
53+
* Create up-front as many typed views for marshalling the output data as
54+
* may be required (with an arbitrary maximum of 64, for the case where a
55+
* multi-MB stack is passed), allocated at the *top* of the worklet's stack
56+
* (and whose addresses are fixed). The 'minimum alloc' firstly stops
57+
* STACK_OVERFLOW_CHECK failing (since the stack will be full, and 16 bytes
58+
* being the minimum allocation size due to alignments) and leaves room for
59+
* a single AudioSampleFrame as a minumum.
60+
*/
61+
createOutputViews() {
4962
// These are still alloc'd to take advantage of the overflow checks, etc.
5063
var oldStackPtr = stackSave();
5164
var viewDataIdx = {{{ getHeapOffset('stackAlloc(this.maxBuffers * this.bytesPerChannel)', 'float') }}};
5265
#if WEBAUDIO_DEBUG
5366
console.log(`AudioWorklet creating ${this.maxBuffers} buffer one-time views (for a stack size of ${wwParams.stackSize} at address 0x${(viewDataIdx * 4).toString(16)})`);
5467
#endif
55-
this.outputViews = [];
68+
this.outputViews.length = 0;
5669
for (var n = this.maxBuffers; n > 0; n--) {
5770
// Added in reverse so the lowest indices are closest to the stack top
5871
this.outputViews.unshift(
5972
HEAPF32.subarray(viewDataIdx, viewDataIdx += this.samplesPerChannel)
6073
);
6174
}
6275
stackRestore(oldStackPtr);
63-
64-
#if ASSERTIONS
65-
// Explicitly verify this later in process()
66-
this.ctorOldStackPtr = oldStackPtr;
67-
#endif
6876
}
6977

7078
static get parameterDescriptors() {
@@ -79,6 +87,9 @@ function createWasmAudioWorkletProcessor(audioParams) {
7987
* @param {Object} parameters
8088
*/
8189
process(inputList, outputList, parameters) {
90+
if (HEAPF32.buffer != this.outputViews[0].buffer) {
91+
this.createOutputViews();
92+
}
8293
var numInputs = inputList.length;
8394
var numOutputs = outputList.length;
8495

0 commit comments

Comments
 (0)