5
5
#include <stdlib.h>
6
6
#include <assert.h>
7
7
8
- // Tests that these audio worklet compatible functions work:
8
+ // Tests that these audio worklet compatible functions work, details in comments below.
9
9
// - emscripten_thread_supports_atomics_wait()
10
10
// - emscripten_lock_init()
11
+ // - emscripten_lock_try_acquire()
11
12
// - emscripten_lock_busyspin_wait_acquire()
12
13
// - emscripten_lock_busyspin_waitinf_acquire()
13
- // - emscripten_lock_try_acquire()
14
14
// - 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 ;
16
37
17
38
emscripten_lock_t testLock = EMSCRIPTEN_LOCK_T_STATIC_INITIALIZER ;
18
- int testSuccess = 0 ;
39
+ _Atomic Test whichTest = TEST_HAS_WAIT ;
40
+ double startTime = 0 ;
19
41
20
42
bool 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
+ }
36
90
37
- return false ;
91
+ return true ;
38
92
}
39
93
40
94
EM_JS (void , InitHtmlUi , (EMSCRIPTEN_WEBAUDIO_T audioContext ), {
@@ -48,28 +102,35 @@ EM_JS(void, InitHtmlUi, (EMSCRIPTEN_WEBAUDIO_T audioContext), {
48
102
};
49
103
});
50
104
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 ;
58
119
}
59
120
return true;
60
121
}
61
122
62
123
void AudioWorkletProcessorCreated (EMSCRIPTEN_WEBAUDIO_T audioContext , bool success , void * userData ) {
63
124
int outputChannelCounts [1 ] = { 1 };
64
125
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 );
66
127
emscripten_audio_node_connect (wasmAudioWorklet , audioContext , 0 , 0 );
67
128
InitHtmlUi (audioContext );
68
129
}
69
130
70
131
void WebAudioWorkletThreadInitialized (EMSCRIPTEN_WEBAUDIO_T audioContext , bool success , void * userData ) {
71
132
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 );
73
134
}
74
135
75
136
uint8_t wasmAudioWorkletStack [4096 ];
@@ -80,7 +141,9 @@ int main() {
80
141
int hasLock = emscripten_lock_busyspin_wait_acquire (& testLock , 0 );
81
142
assert (hasLock );
82
143
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 );
86
149
}
0 commit comments