Skip to content

Commit 8ea671d

Browse files
committed
Fully working with MEMORY64
Also tested by moving the AW stack beyond 4GB.
1 parent 659323a commit 8ea671d

File tree

2 files changed

+30
-19
lines changed

2 files changed

+30
-19
lines changed

src/audio_worklet.js

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,19 @@ function createWasmAudioWorkletProcessor(audioParams) {
4646
// stops STACK_OVERFLOW_CHECK failing (since the stack will be full, and
4747
// 16 being the minimum allocation size due to alignments) and leaves room
4848
// for a single AudioSampleFrame as a minumum.
49+
// Note: here and in the rest of the code the natural '>>> 2' unsigned
50+
// shifts for bytes to HEAPU32 offsets have been replaced with '/ 4',
51+
// otherwise the values are truncated to 32-bit addresses, which fails
52+
// when compiling with MEMORY64.
4953
this.maxBuffers = Math.min(((Module['sz'] - /*minimum alloc*/ 16) / (this.samplesPerChannel * 4)) | 0, /*sensible limit*/ 10);
5054
#if ASSERTIONS
5155
console.assert(this.maxBuffers > 0, `AudioWorklet needs more stack allocating (at least ${this.samplesPerChannel * 4})`);
5256
#endif
5357
// These are still alloc'd to take advantage of the overflow checks, etc.
5458
var oldStackPtr = stackSave();
55-
var viewDataIdx = stackAlloc(this.maxBuffers * this.samplesPerChannel * 4) >> 2;
59+
var viewDataIdx = stackAlloc(this.maxBuffers * this.samplesPerChannel * 4) / 4;
5660
#if WEBAUDIO_DEBUG
57-
console.log(`AudioWorklet creating ${this.maxBuffers} buffer one-time views (for a stack size of ${Module['sz']})`);
61+
console.log(`AudioWorklet creating ${this.maxBuffers} buffer one-time views (for a stack size of ${Module['sz']} at address 0x${(viewDataIdx * 4).toString(16)})`);
5862
#endif
5963
this.outputViews = [];
6064
for (var i = this.maxBuffers; i > 0; i--) {
@@ -112,45 +116,55 @@ function createWasmAudioWorkletProcessor(audioParams) {
112116

113117
// Copy input audio descriptor structs and data to Wasm
114118
inputsPtr = dataPtr;
115-
k = inputsPtr >>> 2;
119+
k = inputsPtr / 4;
116120
dataPtr += numInputs * {{{ C_STRUCTS.AudioSampleFrame.__size__ }}};
117121
for (i of inputList) {
118122
// Write the AudioSampleFrame struct instance
119123
HEAPU32[k + {{{ C_STRUCTS.AudioSampleFrame.numberOfChannels / 4 }}}] = i.length;
120124
HEAPU32[k + {{{ C_STRUCTS.AudioSampleFrame.samplesPerChannel / 4 }}}] = this.samplesPerChannel;
121125
HEAPU32[k + {{{ C_STRUCTS.AudioSampleFrame.data / 4 }}}] = dataPtr;
126+
#if MEMORY64
127+
// See the note in the constructor for dealing with 64-bit addresses
128+
HEAPU32[k + {{{ C_STRUCTS.AudioSampleFrame.data / 4 + 1 }}}] = dataPtr / 0x100000000;
129+
#endif
122130
k += {{{ C_STRUCTS.AudioSampleFrame.__size__ / 4 }}};
123131
// Marshal the input audio sample data for each audio channel of this input
124132
for (j of i) {
125-
HEAPF32.set(j, dataPtr>>>2);
133+
HEAPF32.set(j, dataPtr / 4);
126134
dataPtr += bytesPerChannel;
127135
}
128136
}
129137

130138
// Copy parameters descriptor structs and data to Wasm
131139
paramsPtr = dataPtr;
132-
k = paramsPtr >>> 2;
140+
k = paramsPtr / 4;
133141
dataPtr += numParams * {{{ C_STRUCTS.AudioParamFrame.__size__ }}};
134142
for (i = 0; paramArray = parameters[i++];) {
135143
// Write the AudioParamFrame struct instance
136144
HEAPU32[k + {{{ C_STRUCTS.AudioParamFrame.length / 4 }}}] = paramArray.length;
137145
HEAPU32[k + {{{ C_STRUCTS.AudioParamFrame.data / 4 }}}] = dataPtr;
146+
#if MEMORY64
147+
HEAPU32[k + {{{ C_STRUCTS.AudioSampleFrame.data / 4 + 1 }}}] = dataPtr / 0x100000000;
148+
#endif
138149
k += {{{ C_STRUCTS.AudioParamFrame.__size__ / 4 }}};
139150
// Marshal the audio parameters array
140-
HEAPF32.set(paramArray, dataPtr>>2);
141-
dataPtr += paramArray.length*4;
151+
HEAPF32.set(paramArray, dataPtr / 4);
152+
dataPtr += paramArray.length * 4;
142153
}
143154

144155
// Copy output audio descriptor structs to Wasm (note that dataPtr after
145156
// the struct offsets should now be 16-byte aligned).
146157
outputsPtr = dataPtr;
147-
k = outputsPtr >>> 2;
158+
k = outputsPtr / 4;
148159
dataPtr += numOutputs * {{{ C_STRUCTS.AudioSampleFrame.__size__ }}};
149160
for (i of outputList) {
150161
// Write the AudioSampleFrame struct instance
151162
HEAPU32[k + {{{ C_STRUCTS.AudioSampleFrame.numberOfChannels / 4 }}}] = i.length;
152163
HEAPU32[k + {{{ C_STRUCTS.AudioSampleFrame.samplesPerChannel / 4 }}}] = this.samplesPerChannel;
153164
HEAPU32[k + {{{ C_STRUCTS.AudioSampleFrame.data / 4 }}}] = dataPtr;
165+
#if MEMORY64
166+
HEAPU32[k + {{{ C_STRUCTS.AudioSampleFrame.data / 4 + 1 }}}] = dataPtr / 0x100000000;
167+
#endif
154168
k += {{{ C_STRUCTS.AudioSampleFrame.__size__ / 4 }}};
155169
// Advance the output pointer to the next output (matching the pre-allocated views)
156170
dataPtr += bytesPerChannel * i.length;
@@ -179,7 +193,7 @@ function createWasmAudioWorkletProcessor(audioParams) {
179193
#endif
180194

181195
// Call out to Wasm callback to perform audio processing
182-
if (didProduceAudio = this.callbackFunction(numInputs, BigInt(inputsPtr), numOutputs, BigInt(outputsPtr), numParams, BigInt(paramsPtr), this.userData)) {
196+
if (didProduceAudio = this.callbackFunction(numInputs, {{{ toIndexType('inputsPtr') }}}, numOutputs, {{{ toIndexType('outputsPtr') }}}, numParams, {{{ toIndexType('paramsPtr') }}}, this.userData)) {
183197
// Read back the produced audio data to all outputs and their channels.
184198
// The preallocated 'outputViews' already have the correct offsets and
185199
// sizes into the stack (recall from the ctor that they run backwards).
@@ -262,12 +276,7 @@ class BootstrapMessages extends AudioWorkletProcessor {
262276
// 'ud' the passed user data
263277
p.postMessage({'_wsc': d['cb'], 'x': [d['ch'], 1/*EM_TRUE*/, d['ud']] });
264278
} else if (d['_wsc']) {
265-
#if MEMORY64
266-
var ptr = BigInt(d['_wsc']);
267-
#else
268-
var ptr = d['_wsc'];
269-
#endif
270-
Module['wasmTable'].get(ptr)(...d['x']);
279+
Module['wasmTable'].get({{{ toIndexType('d[\'_wsc\']') }}})(...d['x']);
271280
};
272281
}
273282
}

src/lib/libwebaudio.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -270,11 +270,13 @@ let LibraryWebAudio = {
270270
// Processor Name' used as a 'key' to verify the message type so as to
271271
// not get accidentally mixed with user submitted messages, the remainder
272272
// for space saving reasons, abbreviated from their variable names).
273+
// Note: we can only pass clonable object, so need to pass the function
274+
// pointer and not the wasm function object.
273275
'_wpn': UTF8ToString(HEAPU32[options]),
274276
'ap': audioParams,
275277
'ch': contextHandle,
276-
'cb': BigInt(callback),
277-
'ud': BigInt(userData)
278+
'cb': {{{ toIndexType('callback') }}},
279+
'ud': {{{ toIndexType('userData') }}}
278280
});
279281
},
280282

@@ -298,8 +300,8 @@ let LibraryWebAudio = {
298300
numberOfOutputs: HEAP32[options+1],
299301
outputChannelCount: HEAPU32[options+2] ? readChannelCountArray(HEAPU32[options+2]>>2, HEAP32[options+1]) : void 0,
300302
processorOptions: {
301-
'cb': BigInt(callback),
302-
'ud': BigInt(userData),
303+
'cb': {{{ toIndexType('callback') }}},
304+
'ud': {{{ toIndexType('userData') }}},
303305
'sc': emscriptenGetContextQuantumSize(contextHandle)
304306
}
305307
} : void 0;

0 commit comments

Comments
 (0)