@@ -40,10 +40,16 @@ function createWasmAudioWorkletProcessor(audioParams) {
4040 this . samplesPerChannel = opts [ 'sc' ] ;
4141
4242 // Create up-front as many typed views for marshalling the output data as
43- // may be required (with an arbitrary maximum of 16 , for the case where a
43+ // may be required (with an arbitrary maximum of 10 , for the case where a
4444 // multi-MB stack is passed), allocated at the *top* of the worklet's
45- // stack (and whose addresses are fixed).
46- this . maxBuffers = Math . min ( ( ( Module [ 'sz' ] - /*stack guards?*/ 16 ) / ( this . samplesPerChannel * 4 ) ) | 0 , /*sensible limit*/ 16 ) ;
45+ // stack (and whose addresses are fixed). The 'minimum alloc' firstly
46+ // stops STACK_OVERFLOW_CHECK failing (since the stack will be full, and
47+ // 16 being the minimum allocation size due to alignments) and leaves room
48+ // for a single AudioSampleFrame as a minumum.
49+ this . maxBuffers = Math . min ( ( ( Module [ 'sz' ] - /*minimum alloc*/ 16 ) / ( this . samplesPerChannel * 4 ) ) | 0 , /*sensible limit*/ 10 ) ;
50+ #if ASSERTIONS
51+ console . assert ( this . maxBuffers > 0 , `AudioWorklet needs more stack allocating (at least ${ this . samplesPerChannel * 4 } )` ) ;
52+ #endif
4753 // These are still alloc'd to take advantage of the overflow checks, etc.
4854 var oldStackPtr = stackSave ( ) ;
4955 var viewDataIdx = stackAlloc ( this . maxBuffers * this . samplesPerChannel * 4 ) >> 2 ;
@@ -77,7 +83,6 @@ function createWasmAudioWorkletProcessor(audioParams) {
7783 stackMemoryNeeded = ( numInputs + numOutputs ) * { { { C_STRUCTS . AudioSampleFrame . __size__ } } } ,
7884 oldStackPtr = stackSave ( ) ,
7985 inputsPtr , outputsPtr , paramsPtr ,
80- outputDataPtr ,
8186 didProduceAudio , paramArray ;
8287
8388 // Calculate how much stack space is needed
@@ -91,14 +96,18 @@ function createWasmAudioWorkletProcessor(audioParams) {
9196#endif
9297
9398 // Allocate the necessary stack space (dataPtr is always in bytes, and
94- // advances as space for structs as data is taken, but note the switching
95- // between bytes and indices into the various heaps, usually in 'k').
96- dataPtr = stackAlloc ( stackMemoryNeeded ) ;
99+ // advances as space for structs and data is taken, but note the switching
100+ // between bytes and indices into the various heaps, usually in 'k'). This
101+ // will be 16-byte aligned (from _emscripten_stack_alloc()), as were the
102+ // output views, so we round up and advance the required bytes to ensure
103+ // the addresses all work out at the end.
104+ i = ( stackMemoryNeeded + 15 ) & ~ 15 ;
105+ dataPtr = stackAlloc ( i ) + ( i - stackMemoryNeeded ) ;
97106
98107 // Copy input audio descriptor structs and data to Wasm
99108 inputsPtr = dataPtr ;
100- k = inputsPtr >> 2 ;
101109 dataPtr += numInputs * { { { C_STRUCTS . AudioSampleFrame . __size__ } } } ;
110+ k = inputsPtr >> 2 ;
102111 for ( i of inputList ) {
103112 // Write the AudioSampleFrame struct instance
104113 HEAPU32 [ k + { { { C_STRUCTS . AudioSampleFrame . numberOfChannels / 4 } } } ] = i . length ;
@@ -114,8 +123,8 @@ function createWasmAudioWorkletProcessor(audioParams) {
114123
115124 // Copy parameters descriptor structs and data to Wasm
116125 paramsPtr = dataPtr ;
117- k = paramsPtr >> 2 ;
118126 dataPtr += numParams * { { { C_STRUCTS . AudioParamFrame . __size__ } } } ;
127+ k = paramsPtr >> 2 ;
119128 for ( i = 0 ; paramArray = parameters [ i ++ ] ; ) {
120129 // Write the AudioParamFrame struct instance
121130 HEAPU32 [ k + { { { C_STRUCTS . AudioParamFrame . length / 4 } } } ] = paramArray . length ;
@@ -126,13 +135,11 @@ function createWasmAudioWorkletProcessor(audioParams) {
126135 dataPtr += paramArray . length * 4 ;
127136 }
128137
129- // Copy output audio descriptor structs to Wasm
138+ // Copy output audio descriptor structs to Wasm (not that dataPtr after
139+ // the struct offsets should now be 16-byte aligned).
130140 outputsPtr = dataPtr ;
131- k = outputsPtr >> 2 ;
132141 dataPtr += numOutputs * { { { C_STRUCTS . AudioSampleFrame . __size__ } } } ;
133- #if ASSERTIONS
134- outputDataPtr = dataPtr ;
135- #endif
142+ k = outputsPtr >> 2 ;
136143 for ( i of outputList ) {
137144 // Write the AudioSampleFrame struct instance
138145 HEAPU32 [ k + { { { C_STRUCTS . AudioSampleFrame . numberOfChannels / 4 } } } ] = i . length ;
@@ -144,23 +151,27 @@ function createWasmAudioWorkletProcessor(audioParams) {
144151 }
145152
146153#if ASSERTIONS
147- // TODO: addresses are now wrong
148- k = outputDataPtr ;
149- for ( i = outputViewsNeeded - 1 ; i >= 0 ; i -- ) {
150- console . assert ( this . outputViews [ i ] . byteOffset == k , 'Internal error in addresses of the output array views' ) ;
151- k += bytesPerChannel ;
154+ // If all the maths worked out, we arrived at the original stack address
155+ console . assert ( dataPtr == oldStackPtr , `AudioWorklet stack missmatch (audio data finishes at ${ dataPtr } instead of ${ oldStackPtr } )` ) ;
156+ // Sanity check the output view addresses
157+ if ( numOutputs ) {
158+ k = dataPtr - bytesPerChannel ;
159+ for ( i = 0 ; i < outputViewsNeeded ; i ++ ) {
160+ console . assert ( k == this . outputViews [ i ] . byteOffset , 'AudioWorklet internal error in addresses of the output array views' ) ;
161+ k -= bytesPerChannel ;
162+ }
152163 }
153164#endif
154165
155166 // Call out to Wasm callback to perform audio processing
156167 if ( didProduceAudio = this . callbackFunction ( numInputs , inputsPtr , numOutputs , outputsPtr , numParams , paramsPtr , this . userData ) ) {
157168 // Read back the produced audio data to all outputs and their channels.
158- // The 'outputViews' are subarray views into the heap, each with the
159- // correct offset and size to be copied directly into the output .
160- k = 0 ;
169+ // The preallocated 'outputViews' already have the correct offsets and
170+ // sizes into the stack (recall from the ctor that they run backwards) .
171+ k = outputViewsNeeded - 1 ;
161172 for ( i of outputList ) {
162173 for ( j of i ) {
163- j . set ( this . outputViews [ k ++ ] ) ;
174+ j . set ( this . outputViews [ k -- ] ) ;
164175 }
165176 }
166177 }
0 commit comments