diff --git a/site/source/docs/api_reference/wasm_audio_worklets.rst b/site/source/docs/api_reference/wasm_audio_worklets.rst index f44b1b1ed791..2328e8fd1bda 100644 --- a/site/source/docs/api_reference/wasm_audio_worklets.rst +++ b/site/source/docs/api_reference/wasm_audio_worklets.rst @@ -126,7 +126,7 @@ which resumes the audio context when the user clicks on the DOM Canvas element t "noise-generator", &options, &GenerateNoise, 0); // Connect it to audio context destination - emscripten_audio_worklet_node_connect(audioContext, wasmAudioWorklet); + emscripten_audio_node_connect(wasmAudioWorklet, audioContext, 0, 0); // Resume context on mouse click emscripten_set_click_callback("canvas", (void*)audioContext, 0, OnCanvasClick); diff --git a/src/library_sigs.js b/src/library_sigs.js index 7ab35f14a693..e7de157534c8 100644 --- a/src/library_sigs.js +++ b/src/library_sigs.js @@ -587,7 +587,7 @@ sigs = { emscripten_atomic_wait_async__sig: 'ipippd', emscripten_atomics_is_lock_free__sig: 'ii', emscripten_audio_context_state__sig: 'ii', - emscripten_audio_worklet_node_connect__sig: 'vii', + emscripten_audio_node_connect__sig: 'viiii', emscripten_audio_worklet_post_function_sig__sig: 'vippp', emscripten_audio_worklet_post_function_v__sig: 'vip', emscripten_audio_worklet_post_function_vd__sig: 'vipd', diff --git a/src/library_webaudio.js b/src/library_webaudio.js index 3385a173a194..23a174e21334 100644 --- a/src/library_webaudio.js +++ b/src/library_webaudio.js @@ -293,17 +293,19 @@ let LibraryWebAudio = { }, #endif // ~AUDIO_WORKLET - emscripten_audio_worklet_node_connect: (contextHandle, workletNode) => { + emscripten_audio_node_connect: (source, destination, outputIndex, inputIndex) => { + var srcNode = EmAudio[source]; + var dstNode = EmAudio[destination]; #if ASSERTIONS - assert(EmAudio[contextHandle], `Called emscripten_audio_worklet_node_connect() with an invalid AudioContext handle ${contextHandle}!`); - assert(EmAudio[contextHandle] instanceof (window.AudioContext || window.webkitAudioContext), `Called emscripten_audio_worklet_node_connect() on context handle ${contextHandle} that is not an AudioContext, but of type ${typeof EmAudio[contextHandle]} (${EmAudio[contextHandle]})`); - assert(EmAudio[workletNode], `Called emscripten_audio_worklet_node_connect() with an invalid AudioWorkletNode handle ${workletNode}`); - assert(EmAudio[workletNode].connect, `Called emscripten_audio_worklet_node_connect() on a handle ${workletNode} that is not an AudioWorkletNode, but of type ${typeof EmAudio[workletNode]} (${EmAudio[workletNode]})`); + assert(srcNode, `Called emscripten_audio_node_connect() with an invalid AudioNode handle ${source}`); + assert(srcNode instanceof window.AudioNode, `Called emscripten_audio_node_connect() on handle ${source} that is not an AudiotNode, but of type ${srcNode}`); + assert(dstNode, `Called emscripten_audio_node_connect() with an invalid AudioNode handle ${destination}!`); + assert(dstNode instanceof (window.AudioContext || window.webkitAudioContext) || dstNode instanceof window.AudioNode, `Called emscripten_audio_node_connect() on handle ${destination} that is not an AudioContext or AudioNode, but of type ${dstNode}`); #endif #if WEBAUDIO_DEBUG - console.log(`Connecting worklet with node ID ${workletNode} to Web Audio context with ID ${contextHandle}`); + console.log(`Connecting audio node ID ${source} to audio node ID ${destination} (${srcNode} to ${dstNode})`); #endif - EmAudio[workletNode].connect(EmAudio[contextHandle].destination); + srcNode.connect(dstNode.destination || dstNode, outputIndex, inputIndex); }, emscripten_current_thread_is_audio_worklet: () => typeof AudioWorkletGlobalScope !== 'undefined', diff --git a/system/include/emscripten/webaudio.h b/system/include/emscripten/webaudio.h index 6dc7c00f6c78..d3e3a5fe427e 100644 --- a/system/include/emscripten/webaudio.h +++ b/system/include/emscripten/webaudio.h @@ -129,8 +129,9 @@ typedef struct EmscriptenAudioWorkletNodeCreateOptions // userData4: A custom userdata pointer to pass to the callback function. This value will be passed on to the call to the given EmscriptenWorkletNodeProcessCallback callback function. EMSCRIPTEN_AUDIO_WORKLET_NODE_T emscripten_create_wasm_audio_worklet_node(EMSCRIPTEN_WEBAUDIO_T audioContext, const char *name, const EmscriptenAudioWorkletNodeCreateOptions *options, EmscriptenWorkletNodeProcessCallback processCallback, void *userData4); -// Connects the audio worklet node to the audio context -void emscripten_audio_worklet_node_connect(EMSCRIPTEN_WEBAUDIO_T audioContext, EMSCRIPTEN_AUDIO_WORKLET_NODE_T workletNode); +// Connects a node's output to a target, e.g., connect the worklet node to the context. +// For outputIndex and inputIndex, see the AudioNode.connect() documentation (setting 0 as the default values) +void emscripten_audio_node_connect(EMSCRIPTEN_WEBAUDIO_T source, EMSCRIPTEN_WEBAUDIO_T destination, int outputIndex, int inputIndex); // Returns true if the current thread is executing a Wasm AudioWorklet, false otherwise. // Note that calling this function can be relatively slow as it incurs a Wasm->JS transition, diff --git a/test/webaudio/audio_worklet_tone_generator.c b/test/webaudio/audio_worklet_tone_generator.c index 0f214a8d3d6e..90bc522ae66b 100644 --- a/test/webaudio/audio_worklet_tone_generator.c +++ b/test/webaudio/audio_worklet_tone_generator.c @@ -83,7 +83,7 @@ void AudioWorkletProcessorCreated(EMSCRIPTEN_WEBAUDIO_T audioContext, bool succe EMSCRIPTEN_AUDIO_WORKLET_NODE_T wasmAudioWorklet = emscripten_create_wasm_audio_worklet_node(audioContext, "tone-generator", &options, &ProcessAudio, 0); // Connect the audio worklet node to the graph. - emscripten_audio_worklet_node_connect(audioContext, wasmAudioWorklet); + emscripten_audio_node_connect(wasmAudioWorklet, audioContext, 0, 0); EM_ASM({ // Add a button on the page to toggle playback as a response to user click. let startButton = document.createElement('button'); diff --git a/test/webaudio/audioworklet.c b/test/webaudio/audioworklet.c index f4bbbd1d720c..9da333c67d71 100644 --- a/test/webaudio/audioworklet.c +++ b/test/webaudio/audioworklet.c @@ -95,7 +95,7 @@ void AudioWorkletProcessorCreated(EMSCRIPTEN_WEBAUDIO_T audioContext, bool succe // Instantiate the noise-generator Audio Worklet Processor. EMSCRIPTEN_AUDIO_WORKLET_NODE_T wasmAudioWorklet = emscripten_create_wasm_audio_worklet_node(audioContext, "noise-generator", &options, &ProcessAudio, 0); // Connect the audio worklet node to the graph. - emscripten_audio_worklet_node_connect(audioContext, wasmAudioWorklet); + emscripten_audio_node_connect(wasmAudioWorklet, audioContext, 0, 0); #ifdef REPORT_RESULT emscripten_set_timeout_loop(main_thread_tls_access, 10, 0); diff --git a/test/webaudio/audioworklet_emscripten_futex_wake.cpp b/test/webaudio/audioworklet_emscripten_futex_wake.cpp index 30bf1870a311..65d0c8dd6023 100644 --- a/test/webaudio/audioworklet_emscripten_futex_wake.cpp +++ b/test/webaudio/audioworklet_emscripten_futex_wake.cpp @@ -52,7 +52,7 @@ void AudioWorkletProcessorCreated(EMSCRIPTEN_WEBAUDIO_T audioContext, bool succe int outputChannelCounts[1] = { 1 }; EmscriptenAudioWorkletNodeCreateOptions options = { .numberOfInputs = 0, .numberOfOutputs = 1, .outputChannelCounts = outputChannelCounts }; EMSCRIPTEN_AUDIO_WORKLET_NODE_T wasmAudioWorklet = emscripten_create_wasm_audio_worklet_node(audioContext, "noise-generator", &options, &ProcessAudio, 0); - emscripten_audio_worklet_node_connect(audioContext, wasmAudioWorklet); + emscripten_audio_node_connect(wasmAudioWorklet, audioContext, 0, 0); InitHtmlUi(audioContext); }