1- // This file is the main bootstrap script for Wasm Audio Worklets loaded in an Emscripten application.
2- // Build with -sAUDIO_WORKLET=1 linker flag to enable targeting Audio Worklets.
1+ // This file is the main bootstrap script for Wasm Audio Worklets loaded in an
2+ // Emscripten application. Build with -sAUDIO_WORKLET=1 linker flag to enable
3+ // targeting Audio Worklets.
34
4- // AudioWorkletGlobalScope does not have a onmessage/postMessage() functionality at the global scope, which
5- // means that after creating an AudioWorkletGlobalScope and loading this script into it, we cannot
5+ // AudioWorkletGlobalScope does not have a onmessage/postMessage() functionality
6+ // at the global scope, which means that after creating an
7+ // AudioWorkletGlobalScope and loading this script into it, we cannot
68// postMessage() information into it like one would do with Web Workers.
79
8- // Instead, we must create an AudioWorkletProcessor class, then instantiate a Web Audio graph node from it
9- // on the main thread. Using its message port and the node constructor's
10- // "processorOptions" field, we can share the necessary bootstrap information from the main thread to
11- // the AudioWorkletGlobalScope.
10+ // Instead, we must create an AudioWorkletProcessor class, then instantiate a
11+ // Web Audio graph node from it on the main thread. Using its message port and
12+ // the node constructor's "processorOptions" field, we can share the necessary
13+ // bootstrap information from the main thread to the AudioWorkletGlobalScope.
1214
1315function createWasmAudioWorkletProcessor ( audioParams ) {
1416 class WasmAudioWorkletProcessor extends AudioWorkletProcessor {
@@ -98,8 +100,9 @@ function createWasmAudioWorkletProcessor(audioParams) {
98100 // Call out to Wasm callback to perform audio processing
99101 if ( didProduceAudio = this . callbackFunction ( numInputs , inputsPtr , numOutputs , outputsPtr , numParams , paramsPtr , this . userData ) ) {
100102 // Read back the produced audio data to all outputs and their channels.
101- // (A garbage-free function TypedArray.copy(dstTypedArray, dstOffset, srcTypedArray, srcOffset, count) would sure be handy..
102- // but web does not have one, so manually copy all bytes in)
103+ // (A garbage-free function TypedArray.copy(dstTypedArray, dstOffset,
104+ // srcTypedArray, srcOffset, count) would sure be handy.. but web does
105+ // not have one, so manually copy all bytes in)
103106 for ( i of outputList ) {
104107 for ( j of i ) {
105108 for ( k = 0 ; k < 128 ; ++ k ) {
@@ -111,24 +114,28 @@ function createWasmAudioWorkletProcessor(audioParams) {
111114
112115 stackRestore ( oldStackPtr ) ;
113116
114- // Return 'true' to tell the browser to continue running this processor. (Returning 1 or any other truthy value won't work in Chrome)
117+ // Return 'true' to tell the browser to continue running this processor.
118+ // (Returning 1 or any other truthy value won't work in Chrome)
115119 return ! ! didProduceAudio ;
116120 }
117121 }
118122 return WasmAudioWorkletProcessor ;
119123}
120124
121- // Specify a worklet processor that will be used to receive messages to this AudioWorkletGlobalScope.
122- // We never connect this initial AudioWorkletProcessor to the audio graph to do any audio processing.
125+ // Specify a worklet processor that will be used to receive messages to this
126+ // AudioWorkletGlobalScope. We never connect this initial AudioWorkletProcessor
127+ // to the audio graph to do any audio processing.
123128class BootstrapMessages extends AudioWorkletProcessor {
124129 constructor ( arg ) {
125130 super ( ) ;
126- // Initialize the global Emscripten Module object that contains e.g. the Wasm Module and Memory objects.
127- // After this we are ready to load in the main application JS script, which the main thread will addModule()
131+ // Initialize the global Emscripten Module object that contains e.g. the
132+ // Wasm Module and Memory objects. After this we are ready to load in the
133+ // main application JS script, which the main thread will addModule()
128134 // to this scope.
129135 globalThis . Module = arg [ 'processorOptions' ] ;
130136#if ! MINIMAL_RUNTIME
131- // Default runtime relies on an injected instantiateWasm() function to initialize the Wasm Module.
137+ // Default runtime relies on an injected instantiateWasm() function to
138+ // initialize the Wasm Module.
132139 globalThis . Module [ 'instantiateWasm' ] = ( info , receiveInstance ) => {
133140 var instance = new WebAssembly . Instance ( Module [ 'wasm' ] , info ) ;
134141 receiveInstance ( instance , Module [ 'wasm' ] ) ;
@@ -139,41 +146,55 @@ class BootstrapMessages extends AudioWorkletProcessor {
139146 console . log ( 'AudioWorklet global scope looks like this:' ) ;
140147 console . dir ( globalThis ) ;
141148#endif
142- // Listen to messages from the main thread. These messages will ask this scope to create the real
143- // AudioWorkletProcessors that call out to Wasm to do audio processing.
149+ // Listen to messages from the main thread. These messages will ask this
150+ // scope to create the real AudioWorkletProcessors that call out to Wasm to
151+ // do audio processing.
144152 let p = globalThis [ 'messagePort' ] = this . port ;
145153 p . onmessage = ( msg ) => {
146154 let d = msg . data ;
147- if ( d [ '_wpn' ] ) { // '_wpn' is short for 'Worklet Processor Node', using an identifier that will never conflict with user messages
155+ if ( d [ '_wpn' ] ) {
156+ // '_wpn' is short for 'Worklet Processor Node', using an identifier
157+ // that will never conflict with user messages
148158#if MODULARIZE
149- // Instantiate the MODULARIZEd Module function, which is stored for us under the special global
150- // name AudioWorkletModule in MODULARIZE+AUDIO_WORKLET builds.
159+ // Instantiate the MODULARIZEd Module function, which is stored for us
160+ // under the special global name AudioWorkletModule in
161+ // MODULARIZE+AUDIO_WORKLET builds.
151162 if ( globalThis . AudioWorkletModule ) {
152- AudioWorkletModule ( Module ) ; // This populates the Module object with all the Wasm properties
153- delete globalThis . AudioWorkletModule ; // We have now instantiated the Module function, can discard it from global scope
163+ // This populates the Module object with all the Wasm properties
164+ AudioWorkletModule ( Module ) ;
165+ // We have now instantiated the Module function, can discard it from
166+ // global scope
167+ delete globalThis . AudioWorkletModule ;
154168 }
155169#endif
156170 // Register a real AudioWorkletProcessor that will actually do audio processing.
157171 registerProcessor ( d [ '_wpn' ] , createWasmAudioWorkletProcessor ( d [ 'audioParams' ] ) ) ;
158172#if WEBAUDIO_DEBUG
159173 console . log ( `Registered a new WasmAudioWorkletProcessor "${ d [ '_wpn' ] } " with AudioParams: ${ d [ 'audioParams' ] } ` ) ;
160174#endif
161- // Post a Wasm Call message back telling that we have now registered the AudioWorkletProcessor class,
162- // and should trigger the user onSuccess callback of the emscripten_create_wasm_audio_worklet_processor_async() call.
175+ // Post a Wasm Call message back telling that we have now registered the
176+ // AudioWorkletProcessor class, and should trigger the user onSuccess
177+ // callback of the
178+ // emscripten_create_wasm_audio_worklet_processor_async() call.
163179 p . postMessage ( { '_wsc' : d [ 'callback' ] , 'x' : [ d [ 'contextHandle' ] , 1 /*EM_TRUE*/ , d [ 'userData' ] ] } ) ; // "WaSm Call"
164- } else if ( d [ '_wsc' ] ) { // '_wsc' is short for 'wasm call', using an identifier that will never conflict with user messages
180+ } else if ( d [ '_wsc' ] ) {
181+ // '_wsc' is short for 'wasm call', using an identifier that will never
182+ // conflict with user messages
165183 Module [ 'wasmTable' ] . get ( d [ '_wsc' ] ) ( ...d [ 'x' ] ) ;
166184 } ;
167185 }
168186 }
169187
170- // No-op, not doing audio processing in this processor. It is just for receiving bootstrap messages.
171- // However browsers require it to still be present. It should never be called because we never add a
172- // node to the graph with this processor, although it does look like Chrome does still call this function.
188+ // No-op, not doing audio processing in this processor. It is just for
189+ // receiving bootstrap messages. However browsers require it to still be
190+ // present. It should never be called because we never add a node to the graph
191+ // with this processor, although it does look like Chrome does still call this
192+ // function.
173193 process ( ) {
174- // keep this function a no-op. Chrome redundantly wants to call this even though this processor is never added to the graph.
194+ // keep this function a no-op. Chrome redundantly wants to call this even
195+ // though this processor is never added to the graph.
175196 }
176197} ;
177198
178199// Register the dummy processor that will just receive messages.
179- registerProcessor ( " message" , BootstrapMessages ) ;
200+ registerProcessor ( ' message' , BootstrapMessages ) ;
0 commit comments