55#include <stdlib.h>
66#include <assert.h>
77
8- // Tests that these audio worklet compatible functions work:
8+ // Tests that these audio worklet compatible functions work, details in comments below.
99// - emscripten_thread_supports_atomics_wait()
1010// - emscripten_lock_init()
11+ // - emscripten_lock_try_acquire()
1112// - emscripten_lock_busyspin_wait_acquire()
1213// - emscripten_lock_busyspin_waitinf_acquire()
13- // - emscripten_lock_try_acquire()
1414// - emscripten_lock_release()
15- // - emscripten_get_now() does not crash in a Wasm Audio Worklet.
15+ // - emscripten_get_now()
16+
17+ typedef enum {
18+ // No wait support in audio worklets
19+ TEST_HAS_WAIT ,
20+ // Acquired in main, fail in process
21+ TEST_TRY_ACQUIRE ,
22+ // Keep acquired so time-out
23+ TEST_WAIT_ACQUIRE_FAIL ,
24+ // Release in main, succeed in process
25+ TEST_WAIT_ACQUIRE ,
26+ // Release in process after above
27+ TEST_RELEASE ,
28+ // Released in process above, spin in main
29+ TEST_WAIT_INFINTE_1 ,
30+ // Release in process to stop spinning in main
31+ TEST_WAIT_INFINTE_2 ,
32+ // Call emscripten_get_now() in process
33+ TEST_GET_NOW ,
34+ // Test finished
35+ TEST_DONE
36+ } Test ;
1637
1738emscripten_lock_t testLock = EMSCRIPTEN_LOCK_T_STATIC_INITIALIZER ;
18- int testSuccess = 0 ;
39+ _Atomic Test whichTest = TEST_HAS_WAIT ;
40+ double startTime = 0 ;
1941
2042bool ProcessAudio (int numInputs , const AudioSampleFrame * inputs , int numOutputs , AudioSampleFrame * outputs , int numParams , const AudioParamFrame * params , void * userData ) {
21- // We're in the audio worklet so no wait support
22- int supportsAtomicWait = emscripten_thread_supports_atomics_wait ();
23- printf ("supportsAtomicWait: %d\n" , supportsAtomicWait );
24- assert (!supportsAtomicWait );
25-
26- // Fail to grab the lock
27- int tryLock = emscripten_lock_try_acquire (& testLock );
28- printf ("emscripten_lock_try_acquire: %d\n" , tryLock );
29- assert (!tryLock );
30-
31- //emscripten_futex_wake(&futexLocation, 1);
32- printf ("%f\n" , emscripten_get_now ());
33-
34- //emscripten_futex_wait(&futexLocation, 1, /*maxWaitMs=*/2);
35- testSuccess = 1 ;
43+ int result = 0 ;
44+ switch (whichTest ) {
45+ case TEST_HAS_WAIT :
46+ // Should not have wait support here
47+ result = emscripten_thread_supports_atomics_wait ();
48+ printf ("TEST_HAS_WAIT: %d\n" , result );
49+ assert (!result );
50+ whichTest = TEST_TRY_ACQUIRE ;
51+ break ;
52+ case TEST_TRY_ACQUIRE :
53+ // Was locked after init, should fail to acquire
54+ result = emscripten_lock_try_acquire (& testLock );
55+ printf ("TEST_TRY_ACQUIRE: %d\n" , result );
56+ assert (!result );
57+ whichTest = TEST_WAIT_ACQUIRE_FAIL ;
58+ break ;
59+ case TEST_WAIT_ACQUIRE_FAIL :
60+ // Still locked so we fail to acquire
61+ result = emscripten_lock_busyspin_wait_acquire (& testLock , 100 );
62+ printf ("TEST_WAIT_ACQUIRE_FAIL: %d\n" , result );
63+ assert (!result );
64+ whichTest = TEST_WAIT_ACQUIRE ;
65+ case TEST_WAIT_ACQUIRE :
66+ // Will get unlocked in main, so should quickly acquire
67+ result = emscripten_lock_busyspin_wait_acquire (& testLock , 100 );
68+ printf ("TEST_WAIT_ACQUIRE: %d\n" , result );
69+ assert (result );
70+ whichTest = TEST_RELEASE ;
71+ break ;
72+ case TEST_RELEASE :
73+ // Unlock, check the result
74+ emscripten_lock_release (& testLock );
75+ result = emscripten_lock_try_acquire (& testLock );
76+ printf ("TEST_RELEASE: %d\n" , result );
77+ assert (result );
78+ whichTest = TEST_WAIT_INFINTE_1 ;
79+ break ;
80+ case TEST_WAIT_INFINTE_1 :
81+ // Still locked when we enter here
82+ case TEST_GET_NOW :
83+ result = (int ) (emscripten_get_now () - startTime );
84+ printf ("TEST_GET_NOW: %d\n" , result );
85+ assert (result );
86+ whichTest = TEST_DONE ;
87+ default :
88+ break ;
89+ }
3690
37- return false ;
91+ return true ;
3892}
3993
4094EM_JS (void , InitHtmlUi , (EMSCRIPTEN_WEBAUDIO_T audioContext ), {
@@ -48,28 +102,35 @@ EM_JS(void, InitHtmlUi, (EMSCRIPTEN_WEBAUDIO_T audioContext), {
48102 };
49103});
50104
51- bool PollTestSuccess (double time , void * data ) {
52- if (testSuccess ) {
53- printf ("Test success!\n" );
54- #ifdef REPORT_RESULT
55- REPORT_RESULT (0 );
56- #endif
57- return false;
105+ bool MainLoop (double time , void * data ) {
106+ int result = 0 ;
107+ switch (whichTest ) {
108+ case TEST_WAIT_ACQUIRE :
109+ // Release here to acquire in process
110+ emscripten_lock_release (& testLock );
111+ break ;
112+ case TEST_WAIT_INFINTE_1 :
113+ // Spin here until released in process
114+ emscripten_lock_busyspin_waitinf_acquire (& testLock );
115+ whichTest = TEST_DONE ;
116+ break ;
117+ default :
118+ break ;
58119 }
59120 return true;
60121}
61122
62123void AudioWorkletProcessorCreated (EMSCRIPTEN_WEBAUDIO_T audioContext , bool success , void * userData ) {
63124 int outputChannelCounts [1 ] = { 1 };
64125 EmscriptenAudioWorkletNodeCreateOptions options = { .numberOfInputs = 0 , .numberOfOutputs = 1 , .outputChannelCounts = outputChannelCounts };
65- EMSCRIPTEN_AUDIO_WORKLET_NODE_T wasmAudioWorklet = emscripten_create_wasm_audio_worklet_node (audioContext , "noise-generator" , & options , & ProcessAudio , 0 );
126+ EMSCRIPTEN_AUDIO_WORKLET_NODE_T wasmAudioWorklet = emscripten_create_wasm_audio_worklet_node (audioContext , "noise-generator" , & options , & ProcessAudio , NULL );
66127 emscripten_audio_node_connect (wasmAudioWorklet , audioContext , 0 , 0 );
67128 InitHtmlUi (audioContext );
68129}
69130
70131void WebAudioWorkletThreadInitialized (EMSCRIPTEN_WEBAUDIO_T audioContext , bool success , void * userData ) {
71132 WebAudioWorkletProcessorCreateOptions opts = { .name = "noise-generator" };
72- emscripten_create_wasm_audio_worklet_processor_async (audioContext , & opts , AudioWorkletProcessorCreated , 0 );
133+ emscripten_create_wasm_audio_worklet_processor_async (audioContext , & opts , AudioWorkletProcessorCreated , NULL );
73134}
74135
75136uint8_t wasmAudioWorkletStack [4096 ];
@@ -80,7 +141,9 @@ int main() {
80141 int hasLock = emscripten_lock_busyspin_wait_acquire (& testLock , 0 );
81142 assert (hasLock );
82143
83- emscripten_set_timeout_loop (PollTestSuccess , 10 , 0 );
84- EMSCRIPTEN_WEBAUDIO_T context = emscripten_create_audio_context (0 );
85- emscripten_start_wasm_audio_worklet_thread_async (context , wasmAudioWorkletStack , sizeof (wasmAudioWorkletStack ), WebAudioWorkletThreadInitialized , 0 );
144+ startTime = emscripten_get_now ();
145+
146+ emscripten_set_timeout_loop (MainLoop , 10 , NULL );
147+ EMSCRIPTEN_WEBAUDIO_T context = emscripten_create_audio_context (NULL );
148+ emscripten_start_wasm_audio_worklet_thread_async (context , wasmAudioWorkletStack , sizeof (wasmAudioWorkletStack ), WebAudioWorkletThreadInitialized , NULL );
86149}
0 commit comments