From 42e032e8ad85b45ee8427632cee4ca88191ad4bd Mon Sep 17 00:00:00 2001 From: Carl Woffenden Date: Wed, 12 Feb 2025 13:13:26 +0100 Subject: [PATCH 01/16] Minor: Firefox now supports wasm64 --- test/test_browser.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/test_browser.py b/test/test_browser.py index 27a4a46a83ba3..f174b765353fc 100644 --- a/test/test_browser.py +++ b/test/test_browser.py @@ -5470,8 +5470,6 @@ def test_full_js_library_strict(self): 'strict': (['-sSTRICT'],), }) def test_audio_worklet(self, args): - if '-sMEMORY64' in args and is_firefox(): - self.skipTest('https://github.com/emscripten-core/emscripten/issues/19161') self.btest_exit('webaudio/audioworklet.c', args=['-sAUDIO_WORKLET', '-sWASM_WORKERS'] + args) # Tests that audioworklets and workers can be used at the same time From c858dea4c46775b22e5ff69a5087d57a4cefff28 Mon Sep 17 00:00:00 2001 From: Carl Woffenden Date: Thu, 13 Feb 2025 13:42:17 +0100 Subject: [PATCH 02/16] The AW test should now fail, waiting on audio playback --- test/test_browser.py | 2 +- test/webaudio/audioworklet.c | 26 +++++++++++++++++--------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/test/test_browser.py b/test/test_browser.py index f174b765353fc..70db289a0d4fb 100644 --- a/test/test_browser.py +++ b/test/test_browser.py @@ -5470,7 +5470,7 @@ def test_full_js_library_strict(self): 'strict': (['-sSTRICT'],), }) def test_audio_worklet(self, args): - self.btest_exit('webaudio/audioworklet.c', args=['-sAUDIO_WORKLET', '-sWASM_WORKERS'] + args) + self.btest_exit('webaudio/audioworklet.c', args=['-sAUDIO_WORKLET', '-sWASM_WORKERS', '-DTEST_AND_EXIT'] + args) # Tests that audioworklets and workers can be used at the same time def test_audio_worklet_worker(self): diff --git a/test/webaudio/audioworklet.c b/test/webaudio/audioworklet.c index 9b4bdd8a3dd60..c767014dbf375 100644 --- a/test/webaudio/audioworklet.c +++ b/test/webaudio/audioworklet.c @@ -22,16 +22,17 @@ begin to fire. */ -// REPORT_RESULT is defined when running in Emscripten test harness. You can -// strip these out in your own project. -#ifdef REPORT_RESULT +// TEST_AND_EXIT is defined when running in Emscripten test harness. You can +// strip these out in your own project (otherwise playback will end quickly). +#ifdef TEST_AND_EXIT _Thread_local int testTlsVariable = 1; int lastTlsVariableValueInAudioThread = 1; #endif // This function will be called for every fixed-size buffer of audio samples to be processed. bool ProcessAudio(int numInputs, const AudioSampleFrame *inputs, int numOutputs, AudioSampleFrame *outputs, int numParams, const AudioParamFrame *params, void *userData) { -#ifdef REPORT_RESULT +#ifdef TEST_AND_EXIT + // Only running in the test harness, see main_thread_tls_access() assert(testTlsVariable == lastTlsVariableValueInAudioThread); ++testTlsVariable; lastTlsVariableValueInAudioThread = testTlsVariable; @@ -63,14 +64,15 @@ EM_JS(void, InitHtmlUi, (EMSCRIPTEN_WEBAUDIO_T audioContext), { }; }); -#ifdef REPORT_RESULT +#ifdef TEST_AND_EXIT bool main_thread_tls_access(double time, void *userData) { // Try to mess the TLS variable on the main thread, with the expectation that - // it should not change the TLS value on the AudioWorklet thread. + // it should not change the TLS value on the AudioWorklet thread, asserted in + // ProcessAudio(). testTlsVariable = (int)time; + // Exit to the test harness after enough calls to ProcessAudio() if (lastTlsVariableValueInAudioThread >= 100) { - REPORT_RESULT(0); - return false; + emscripten_force_exit(EXIT_SUCCESS); } return true; } @@ -97,7 +99,8 @@ void AudioWorkletProcessorCreated(EMSCRIPTEN_WEBAUDIO_T audioContext, bool succe // Connect the audio worklet node to the graph. emscripten_audio_node_connect(wasmAudioWorklet, audioContext, 0, 0); -#ifdef REPORT_RESULT +#ifdef TEST_AND_EXIT + // Schedule this to exit after ProcessAudio() has been called 100 times emscripten_set_timeout_loop(main_thread_tls_access, 10, 0); #endif @@ -132,4 +135,9 @@ int main() { // and kick off Audio Worklet scope initialization, which shares the Wasm // Module and Memory to the AudioWorklet scope and initializes its stack. emscripten_start_wasm_audio_worklet_thread_async(context, wasmAudioWorkletStack, sizeof(wasmAudioWorkletStack), WebAudioWorkletThreadInitialized, 0); + +#ifdef TEST_AND_EXIT + // We're in the test harness and exiting is via main_thread_tls_access() + emscripten_exit_with_live_runtime(); +#endif } From 29451a4d4a3f82fc4b4e945dfa02b0a775c2d807 Mon Sep 17 00:00:00 2001 From: Carl Woffenden Date: Thu, 13 Feb 2025 14:29:26 +0100 Subject: [PATCH 03/16] Confirmed failure, now flagging as needing audio --- test/test_browser.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/test_browser.py b/test/test_browser.py index 70db289a0d4fb..5ca3faa88c20c 100644 --- a/test/test_browser.py +++ b/test/test_browser.py @@ -5469,6 +5469,7 @@ def test_full_js_library_strict(self): 'es6': (['-sEXPORT_ES6'],), 'strict': (['-sSTRICT'],), }) + @requires_sound_hardware def test_audio_worklet(self, args): self.btest_exit('webaudio/audioworklet.c', args=['-sAUDIO_WORKLET', '-sWASM_WORKERS', '-DTEST_AND_EXIT'] + args) From b7fb25aa0af5823a8395515262af2b598e29615e Mon Sep 17 00:00:00 2001 From: Carl Woffenden Date: Fri, 14 Feb 2025 10:33:13 +0100 Subject: [PATCH 04/16] Correctly halt for btest_exit() --- test/webaudio/audioworklet.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/test/webaudio/audioworklet.c b/test/webaudio/audioworklet.c index c767014dbf375..e4260e21e31ac 100644 --- a/test/webaudio/audioworklet.c +++ b/test/webaudio/audioworklet.c @@ -81,7 +81,11 @@ bool main_thread_tls_access(double time, void *userData) { // This callback will fire after the Audio Worklet Processor has finished being // added to the Worklet global scope. void AudioWorkletProcessorCreated(EMSCRIPTEN_WEBAUDIO_T audioContext, bool success, void *userData) { - if (!success) return; + if (!success) { + emscripten_out("Stopped in AudioWorkletProcessorCreated"); + assert(0); + return; + } // Specify the input and output node configurations for the Wasm Audio // Worklet. A simple setup with single mono output channel here, and no @@ -111,7 +115,11 @@ void AudioWorkletProcessorCreated(EMSCRIPTEN_WEBAUDIO_T audioContext, bool succe // AudioWorklet global scope, and is now ready to begin adding Audio Worklet // Processors. void WebAudioWorkletThreadInitialized(EMSCRIPTEN_WEBAUDIO_T audioContext, bool success, void *userData) { - if (!success) return; + if (!success) { + emscripten_out("Stopped in WebAudioWorkletThreadInitialized"); + assert(0); + return; + } WebAudioWorkletProcessorCreateOptions opts = { .name = "noise-generator", From a9132c81963c27d9ca50f5817a4c0064188520ff Mon Sep 17 00:00:00 2001 From: Carl Woffenden Date: Fri, 14 Feb 2025 10:58:01 +0100 Subject: [PATCH 05/16] Attempt to run CI with autoplay enabled --- .circleci/config.yml | 3 ++- test/test_browser.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5038ba89917ee..26a81e0a0ccbb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -310,7 +310,7 @@ commands: EMTEST_DETECT_TEMPFILE_LEAKS: "0" # --no-sandbox because we are running as root and chrome requires # this flag for now: https://crbug.com/638180 - CHROME_FLAGS_BASE: "--no-first-run -start-maximized --no-sandbox --use-gl=swiftshader --user-data-dir=/tmp/chrome-emscripten-profile --enable-experimental-web-platform-features" + CHROME_FLAGS_BASE: "--no-first-run -start-maximized --no-sandbox --use-gl=swiftshader --user-data-dir=/tmp/chrome-emscripten-profile --enable-experimental-web-platform-features --autoplay-policy=no-user-gesture-required" CHROME_FLAGS_HEADLESS: "--headless=new --remote-debugging-port=1234" CHROME_FLAGS_WASM: "--enable-experimental-webassembly-features --js-flags=\"--experimental-wasm-stack-switching --experimental-wasm-type-reflection\"" CHROME_FLAGS_NOCACHE: "--disk-cache-dir=/dev/null --disk-cache-size=1 --media-cache-size=1 --disable-application-cache --incognito" @@ -360,6 +360,7 @@ commands: user_pref("javascript.options.shared_memory", true); user_pref("javascript.options.wasm_memory64", true); user_pref("dom.postMessage.sharedArrayBuffer.bypassCOOP_COEP.insecure.enabled", true); + user_pref("media.autoplay.default", 0); EOF - run: name: run tests (<< parameters.title >>) diff --git a/test/test_browser.py b/test/test_browser.py index 5ca3faa88c20c..de24802276096 100644 --- a/test/test_browser.py +++ b/test/test_browser.py @@ -5469,7 +5469,7 @@ def test_full_js_library_strict(self): 'es6': (['-sEXPORT_ES6'],), 'strict': (['-sSTRICT'],), }) - @requires_sound_hardware + # @requires_sound_hardware def test_audio_worklet(self, args): self.btest_exit('webaudio/audioworklet.c', args=['-sAUDIO_WORKLET', '-sWASM_WORKERS', '-DTEST_AND_EXIT'] + args) From 92c8b5c94ffa3da8d73cf0b6263ab55058d07920 Mon Sep 17 00:00:00 2001 From: Carl Woffenden Date: Fri, 14 Feb 2025 13:23:01 +0100 Subject: [PATCH 06/16] Retrying without wasm64 --- test/test_browser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_browser.py b/test/test_browser.py index de24802276096..3381996d71d6e 100644 --- a/test/test_browser.py +++ b/test/test_browser.py @@ -5457,7 +5457,7 @@ def test_full_js_library_strict(self): # Tests the AudioWorklet demo @parameterized({ '': ([],), - 'memory64': (['-sMEMORY64'],), + # 'memory64': (['-sMEMORY64'],), 'with_fs': (['--preload-file', test_file('hello_world.c') + '@/'],), 'closure': (['--closure', '1', '-Oz'],), 'asyncify': (['-sASYNCIFY'],), From a42c6d4cab2b4231b72f903b3065e9cca32c5a30 Mon Sep 17 00:00:00 2001 From: Carl Woffenden Date: Fri, 14 Feb 2025 16:01:57 +0100 Subject: [PATCH 07/16] Try adding a dummy sound device... --- .circleci/config.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 26a81e0a0ccbb..06cb93f6ef2d8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -34,6 +34,8 @@ commands: - run: name: download chrome command: | + # Try adding a dummy sound device for Chrome... + modprobe snd-dummy # TODO: Make these part of the base image apt-get install -q -y libu2f-udev libvulkan1 xdg-utils # wget -O ~/chrome.deb https://dl.google.com/linux/direct/google-chrome-beta_current_amd64.deb From 4b80dd23afeee81ac9db24c387214fc2423ea9d7 Mon Sep 17 00:00:00 2001 From: Carl Woffenden Date: Fri, 14 Feb 2025 17:28:32 +0100 Subject: [PATCH 08/16] Try with a full path... --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 06cb93f6ef2d8..c202bacfc4121 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -35,7 +35,7 @@ commands: name: download chrome command: | # Try adding a dummy sound device for Chrome... - modprobe snd-dummy + /usr/sbin/modprobe snd-dummy # TODO: Make these part of the base image apt-get install -q -y libu2f-udev libvulkan1 xdg-utils # wget -O ~/chrome.deb https://dl.google.com/linux/direct/google-chrome-beta_current_amd64.deb From 9bcf181c9706ebb874be95c860d6342b2159454a Mon Sep 17 00:00:00 2001 From: Carl Woffenden Date: Fri, 14 Feb 2025 18:48:50 +0100 Subject: [PATCH 09/16] Try with Chrome flags for audio... --- .circleci/config.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c202bacfc4121..f8cfbdcdf183b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -34,8 +34,6 @@ commands: - run: name: download chrome command: | - # Try adding a dummy sound device for Chrome... - /usr/sbin/modprobe snd-dummy # TODO: Make these part of the base image apt-get install -q -y libu2f-udev libvulkan1 xdg-utils # wget -O ~/chrome.deb https://dl.google.com/linux/direct/google-chrome-beta_current_amd64.deb @@ -312,12 +310,13 @@ commands: EMTEST_DETECT_TEMPFILE_LEAKS: "0" # --no-sandbox because we are running as root and chrome requires # this flag for now: https://crbug.com/638180 - CHROME_FLAGS_BASE: "--no-first-run -start-maximized --no-sandbox --use-gl=swiftshader --user-data-dir=/tmp/chrome-emscripten-profile --enable-experimental-web-platform-features --autoplay-policy=no-user-gesture-required" + CHROME_FLAGS_BASE: "--no-first-run -start-maximized --no-sandbox --use-gl=swiftshader --user-data-dir=/tmp/chrome-emscripten-profile --enable-experimental-web-platform-features" CHROME_FLAGS_HEADLESS: "--headless=new --remote-debugging-port=1234" CHROME_FLAGS_WASM: "--enable-experimental-webassembly-features --js-flags=\"--experimental-wasm-stack-switching --experimental-wasm-type-reflection\"" CHROME_FLAGS_NOCACHE: "--disk-cache-dir=/dev/null --disk-cache-size=1 --media-cache-size=1 --disable-application-cache --incognito" + CHROME_FLAGS_AUDIO: "--autoplay-policy=no-user-gesture-required --use-fake-device-for-media-stream" command: | - export EMTEST_BROWSER="/usr/bin/google-chrome $CHROME_FLAGS_BASE $CHROME_FLAGS_HEADLESS $CHROME_FLAGS_WASM $CHROME_FLAGS_NOCACHE" + export EMTEST_BROWSER="/usr/bin/google-chrome $CHROME_FLAGS_BASE $CHROME_FLAGS_HEADLESS $CHROME_FLAGS_WASM $CHROME_FLAGS_NOCACHE $CHROME_FLAGS_AUDIO" # There are tests in the browser test suite that using libraries # that are not included by "./embuilder build ALL". For example the # PIC version of libSDL which is used by test_sdl2_misc_main_module From f9a781b5b69161b31e3bdcd785fd7edadb24ddb8 Mon Sep 17 00:00:00 2001 From: Carl Woffenden Date: Sat, 15 Feb 2025 10:46:32 +0100 Subject: [PATCH 10/16] Try dummy audio for FF; remove LACKS_SOUND_HARDWARE --- .circleci/config.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f8cfbdcdf183b..4ec0e5bc3c9db 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -306,7 +306,6 @@ commands: - run: name: run tests (<< parameters.title >>) environment: - EMTEST_LACKS_SOUND_HARDWARE: "1" EMTEST_DETECT_TEMPFILE_LEAKS: "0" # --no-sandbox because we are running as root and chrome requires # this flag for now: https://crbug.com/638180 @@ -314,7 +313,9 @@ commands: CHROME_FLAGS_HEADLESS: "--headless=new --remote-debugging-port=1234" CHROME_FLAGS_WASM: "--enable-experimental-webassembly-features --js-flags=\"--experimental-wasm-stack-switching --experimental-wasm-type-reflection\"" CHROME_FLAGS_NOCACHE: "--disk-cache-dir=/dev/null --disk-cache-size=1 --media-cache-size=1 --disable-application-cache --incognito" - CHROME_FLAGS_AUDIO: "--autoplay-policy=no-user-gesture-required --use-fake-device-for-media-stream" + # The runners lack sound hardware so fallback to a dummy device (and + # bypass the user gesture so audio tests work without interaction) + CHROME_FLAGS_AUDIO: " --use-fake-device-for-media-stream --autoplay-policy=no-user-gesture-required" command: | export EMTEST_BROWSER="/usr/bin/google-chrome $CHROME_FLAGS_BASE $CHROME_FLAGS_HEADLESS $CHROME_FLAGS_WASM $CHROME_FLAGS_NOCACHE $CHROME_FLAGS_AUDIO" # There are tests in the browser test suite that using libraries @@ -361,6 +362,7 @@ commands: user_pref("javascript.options.shared_memory", true); user_pref("javascript.options.wasm_memory64", true); user_pref("dom.postMessage.sharedArrayBuffer.bypassCOOP_COEP.insecure.enabled", true); + user_pref("media.navigator.streams.fake", true); user_pref("media.autoplay.default", 0); EOF - run: @@ -371,11 +373,12 @@ commands: # support in headless mode) resolves EMTEST_LACKS_GRAPHICS_HARDWARE: "1" EMTEST_LACKS_WEBGPU: "1" - EMTEST_LACKS_SOUND_HARDWARE: "1" # OffscreenCanvas support is not yet done in Firefox. EMTEST_LACKS_OFFSCREEN_CANVAS: "1" EMTEST_DETECT_TEMPFILE_LEAKS: "0" DISPLAY: ":0" + # Note: as per Chrome, the FF profile enables a dummy audio device + # (so doesn't need the EMTEST_LACKS_SOUND_HARDWARE var) command: | export EMTEST_BROWSER="$HOME/firefox/firefox -headless -profile $HOME/tmp-firefox-profile/" # There are tests in the browser test suite that using libraries From e8ca2c4609d34e45ef885ff600486e37a3a957cc Mon Sep 17 00:00:00 2001 From: Carl Woffenden Date: Tue, 18 Feb 2025 19:28:42 +0100 Subject: [PATCH 11/16] Removed FF flags (they don't work) --- .circleci/config.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4ec0e5bc3c9db..cde1d2f5be0b5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -362,8 +362,6 @@ commands: user_pref("javascript.options.shared_memory", true); user_pref("javascript.options.wasm_memory64", true); user_pref("dom.postMessage.sharedArrayBuffer.bypassCOOP_COEP.insecure.enabled", true); - user_pref("media.navigator.streams.fake", true); - user_pref("media.autoplay.default", 0); EOF - run: name: run tests (<< parameters.title >>) @@ -373,12 +371,12 @@ commands: # support in headless mode) resolves EMTEST_LACKS_GRAPHICS_HARDWARE: "1" EMTEST_LACKS_WEBGPU: "1" + # TODO: replicate with FF the same as CHROME_FLAGS_AUDIO + EMTEST_LACKS_SOUND_HARDWARE: "1" # OffscreenCanvas support is not yet done in Firefox. EMTEST_LACKS_OFFSCREEN_CANVAS: "1" EMTEST_DETECT_TEMPFILE_LEAKS: "0" DISPLAY: ":0" - # Note: as per Chrome, the FF profile enables a dummy audio device - # (so doesn't need the EMTEST_LACKS_SOUND_HARDWARE var) command: | export EMTEST_BROWSER="$HOME/firefox/firefox -headless -profile $HOME/tmp-firefox-profile/" # There are tests in the browser test suite that using libraries From 9fd83f756f7f06d65d1ab848b1198736ee50a86d Mon Sep 17 00:00:00 2001 From: Carl Woffenden Date: Tue, 18 Feb 2025 19:29:32 +0100 Subject: [PATCH 12/16] Flagged tests as requiring sound hardware --- test/test_browser.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/test_browser.py b/test/test_browser.py index 3381996d71d6e..b48c243279ccb 100644 --- a/test/test_browser.py +++ b/test/test_browser.py @@ -5457,7 +5457,7 @@ def test_full_js_library_strict(self): # Tests the AudioWorklet demo @parameterized({ '': ([],), - # 'memory64': (['-sMEMORY64'],), + 'memory64': (['-sMEMORY64'],), 'with_fs': (['--preload-file', test_file('hello_world.c') + '@/'],), 'closure': (['--closure', '1', '-Oz'],), 'asyncify': (['-sASYNCIFY'],), @@ -5469,7 +5469,7 @@ def test_full_js_library_strict(self): 'es6': (['-sEXPORT_ES6'],), 'strict': (['-sSTRICT'],), }) - # @requires_sound_hardware + @requires_sound_hardware def test_audio_worklet(self, args): self.btest_exit('webaudio/audioworklet.c', args=['-sAUDIO_WORKLET', '-sWASM_WORKERS', '-DTEST_AND_EXIT'] + args) @@ -5489,8 +5489,9 @@ def test_audio_worklet_post_function(self, args): '': ([],), 'closure': (['--closure', '1', '-Oz'],), }) + @requires_sound_hardware def test_audio_worklet_modularize(self, args): - self.btest_exit('webaudio/audioworklet.c', args=['-sAUDIO_WORKLET', '-sWASM_WORKERS', '-sMODULARIZE=1', '-sEXPORT_NAME=MyModule', '--shell-file', test_file('shell_that_launches_modularize.html')] + args) + self.btest_exit('webaudio/audioworklet.c', args=['-sAUDIO_WORKLET', '-sWASM_WORKERS', '-sMODULARIZE=1', '-sEXPORT_NAME=MyModule', '--shell-file', test_file('shell_that_launches_modularize.html'), '-DTEST_AND_EXIT'] + args) # Tests multiple inputs, forcing a larger stack (note: passing BROWSER_TEST is # specific to this test to allow it to exit rather than play forever). From 9e6350267cd56e4c8ca900447dd6650167de2667 Mon Sep 17 00:00:00 2001 From: Carl Woffenden Date: Tue, 18 Feb 2025 19:43:56 +0100 Subject: [PATCH 13/16] Revert back test (changes moved to #23695) --- test/webaudio/audioworklet.c | 38 +++++++++++------------------------- 1 file changed, 11 insertions(+), 27 deletions(-) diff --git a/test/webaudio/audioworklet.c b/test/webaudio/audioworklet.c index e4260e21e31ac..9b4bdd8a3dd60 100644 --- a/test/webaudio/audioworklet.c +++ b/test/webaudio/audioworklet.c @@ -22,17 +22,16 @@ begin to fire. */ -// TEST_AND_EXIT is defined when running in Emscripten test harness. You can -// strip these out in your own project (otherwise playback will end quickly). -#ifdef TEST_AND_EXIT +// REPORT_RESULT is defined when running in Emscripten test harness. You can +// strip these out in your own project. +#ifdef REPORT_RESULT _Thread_local int testTlsVariable = 1; int lastTlsVariableValueInAudioThread = 1; #endif // This function will be called for every fixed-size buffer of audio samples to be processed. bool ProcessAudio(int numInputs, const AudioSampleFrame *inputs, int numOutputs, AudioSampleFrame *outputs, int numParams, const AudioParamFrame *params, void *userData) { -#ifdef TEST_AND_EXIT - // Only running in the test harness, see main_thread_tls_access() +#ifdef REPORT_RESULT assert(testTlsVariable == lastTlsVariableValueInAudioThread); ++testTlsVariable; lastTlsVariableValueInAudioThread = testTlsVariable; @@ -64,15 +63,14 @@ EM_JS(void, InitHtmlUi, (EMSCRIPTEN_WEBAUDIO_T audioContext), { }; }); -#ifdef TEST_AND_EXIT +#ifdef REPORT_RESULT bool main_thread_tls_access(double time, void *userData) { // Try to mess the TLS variable on the main thread, with the expectation that - // it should not change the TLS value on the AudioWorklet thread, asserted in - // ProcessAudio(). + // it should not change the TLS value on the AudioWorklet thread. testTlsVariable = (int)time; - // Exit to the test harness after enough calls to ProcessAudio() if (lastTlsVariableValueInAudioThread >= 100) { - emscripten_force_exit(EXIT_SUCCESS); + REPORT_RESULT(0); + return false; } return true; } @@ -81,11 +79,7 @@ bool main_thread_tls_access(double time, void *userData) { // This callback will fire after the Audio Worklet Processor has finished being // added to the Worklet global scope. void AudioWorkletProcessorCreated(EMSCRIPTEN_WEBAUDIO_T audioContext, bool success, void *userData) { - if (!success) { - emscripten_out("Stopped in AudioWorkletProcessorCreated"); - assert(0); - return; - } + if (!success) return; // Specify the input and output node configurations for the Wasm Audio // Worklet. A simple setup with single mono output channel here, and no @@ -103,8 +97,7 @@ void AudioWorkletProcessorCreated(EMSCRIPTEN_WEBAUDIO_T audioContext, bool succe // Connect the audio worklet node to the graph. emscripten_audio_node_connect(wasmAudioWorklet, audioContext, 0, 0); -#ifdef TEST_AND_EXIT - // Schedule this to exit after ProcessAudio() has been called 100 times +#ifdef REPORT_RESULT emscripten_set_timeout_loop(main_thread_tls_access, 10, 0); #endif @@ -115,11 +108,7 @@ void AudioWorkletProcessorCreated(EMSCRIPTEN_WEBAUDIO_T audioContext, bool succe // AudioWorklet global scope, and is now ready to begin adding Audio Worklet // Processors. void WebAudioWorkletThreadInitialized(EMSCRIPTEN_WEBAUDIO_T audioContext, bool success, void *userData) { - if (!success) { - emscripten_out("Stopped in WebAudioWorkletThreadInitialized"); - assert(0); - return; - } + if (!success) return; WebAudioWorkletProcessorCreateOptions opts = { .name = "noise-generator", @@ -143,9 +132,4 @@ int main() { // and kick off Audio Worklet scope initialization, which shares the Wasm // Module and Memory to the AudioWorklet scope and initializes its stack. emscripten_start_wasm_audio_worklet_thread_async(context, wasmAudioWorkletStack, sizeof(wasmAudioWorkletStack), WebAudioWorkletThreadInitialized, 0); - -#ifdef TEST_AND_EXIT - // We're in the test harness and exiting is via main_thread_tls_access() - emscripten_exit_with_live_runtime(); -#endif } From e9f37db8aeda7303dbf910e5cb6af45395a4bc72 Mon Sep 17 00:00:00 2001 From: Carl Woffenden Date: Tue, 18 Feb 2025 20:00:37 +0100 Subject: [PATCH 14/16] Finish moving test code to other PR --- test/test_browser.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_browser.py b/test/test_browser.py index b48c243279ccb..15b0ec6ea4267 100644 --- a/test/test_browser.py +++ b/test/test_browser.py @@ -5471,7 +5471,7 @@ def test_full_js_library_strict(self): }) @requires_sound_hardware def test_audio_worklet(self, args): - self.btest_exit('webaudio/audioworklet.c', args=['-sAUDIO_WORKLET', '-sWASM_WORKERS', '-DTEST_AND_EXIT'] + args) + self.btest_exit('webaudio/audioworklet.c', args=['-sAUDIO_WORKLET', '-sWASM_WORKERS'] + args) # Tests that audioworklets and workers can be used at the same time def test_audio_worklet_worker(self): @@ -5491,7 +5491,7 @@ def test_audio_worklet_post_function(self, args): }) @requires_sound_hardware def test_audio_worklet_modularize(self, args): - self.btest_exit('webaudio/audioworklet.c', args=['-sAUDIO_WORKLET', '-sWASM_WORKERS', '-sMODULARIZE=1', '-sEXPORT_NAME=MyModule', '--shell-file', test_file('shell_that_launches_modularize.html'), '-DTEST_AND_EXIT'] + args) + self.btest_exit('webaudio/audioworklet.c', args=['-sAUDIO_WORKLET', '-sWASM_WORKERS', '-sMODULARIZE=1', '-sEXPORT_NAME=MyModule', '--shell-file', test_file('shell_that_launches_modularize.html')] + args) # Tests multiple inputs, forcing a larger stack (note: passing BROWSER_TEST is # specific to this test to allow it to exit rather than play forever). From 5d27dc8a4b2eb25bd315cae596726135efbb7335 Mon Sep 17 00:00:00 2001 From: Carl Woffenden Date: Tue, 18 Feb 2025 21:27:22 +0100 Subject: [PATCH 15/16] SDL audio tests with wasm64 disabled for now --- test/test_browser.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/test_browser.py b/test/test_browser.py index 15b0ec6ea4267..daeeb957d6c22 100644 --- a/test/test_browser.py +++ b/test/test_browser.py @@ -3231,6 +3231,7 @@ def test_sdl2_misc_via_object(self): '': (['-sUSE_SDL=2', '-sUSE_SDL_MIXER=2'],), 'dash_l': (['-lSDL2', '-lSDL2_mixer'],), }) + @no_wasm64('TODO: SDL2 audio memory64') @requires_sound_hardware def test_sdl2_mixer_wav(self, flags): shutil.copy(test_file('sounds/the_entertainer.wav'), 'sound.wav') @@ -3244,6 +3245,7 @@ def test_sdl2_mixer_wav(self, flags): # TODO: need to source freepats.cfg and a midi file # 'mod': (['mid'], 'MIX_INIT_MID', 'midi.mid'), }) + @no_wasm64('TODO: SDL2 audio memory64') @requires_sound_hardware def test_sdl2_mixer_music(self, formats, flags, music_name): shutil.copy(test_file('sounds', music_name), '.') From 900819250757d092cccf4901c278cc72d8b86e8c Mon Sep 17 00:00:00 2001 From: Carl Woffenden Date: Tue, 18 Feb 2025 21:32:45 +0100 Subject: [PATCH 16/16] Changed todo to URL of PR --- test/test_browser.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_browser.py b/test/test_browser.py index daeeb957d6c22..20fa6eadc142c 100644 --- a/test/test_browser.py +++ b/test/test_browser.py @@ -3231,7 +3231,7 @@ def test_sdl2_misc_via_object(self): '': (['-sUSE_SDL=2', '-sUSE_SDL_MIXER=2'],), 'dash_l': (['-lSDL2', '-lSDL2_mixer'],), }) - @no_wasm64('TODO: SDL2 audio memory64') + @no_wasm64('https://github.com/libsdl-org/SDL/pull/12332') @requires_sound_hardware def test_sdl2_mixer_wav(self, flags): shutil.copy(test_file('sounds/the_entertainer.wav'), 'sound.wav') @@ -3245,7 +3245,7 @@ def test_sdl2_mixer_wav(self, flags): # TODO: need to source freepats.cfg and a midi file # 'mod': (['mid'], 'MIX_INIT_MID', 'midi.mid'), }) - @no_wasm64('TODO: SDL2 audio memory64') + @no_wasm64('https://github.com/libsdl-org/SDL/pull/12332') @requires_sound_hardware def test_sdl2_mixer_music(self, formats, flags, music_name): shutil.copy(test_file('sounds', music_name), '.')