Skip to content

Commit 69e804e

Browse files
authored
[AUDIO_WORKLET] Wait for Wasm instance to start using audio worklet. (#24778)
Fixes intermittent test failures where the AudioWorklet was used before the Wasm module was loaded in MINIMAL_RUNTIME.
1 parent dd19cf6 commit 69e804e

File tree

4 files changed

+102
-84
lines changed

4 files changed

+102
-84
lines changed

src/audio_worklet.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
// the node constructor's "processorOptions" field, we can share the necessary
1313
// bootstrap information from the main thread to the AudioWorkletGlobalScope.
1414

15+
#if MINIMAL_RUNTIME
16+
var instantiatePromise;
17+
#endif
18+
1519
if (ENVIRONMENT_IS_AUDIO_WORKLET) {
1620

1721
function createWasmAudioWorkletProcessor(audioParams) {
@@ -161,6 +165,10 @@ class BootstrapMessages extends AudioWorkletProcessor {
161165
messagePort = this.port;
162166
/** @suppress {checkTypes} */
163167
messagePort.onmessage = async (msg) => {
168+
#if MINIMAL_RUNTIME
169+
// Wait for the module instantiation before processing messages.
170+
await instantiatePromise;
171+
#endif
164172
let d = msg.data;
165173
if (d['_wpn']) {
166174
// '_wpn' is short for 'Worklet Processor Node', using an identifier

src/postamble_minimal.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ var imports = {
128128
// precompiled WebAssembly Module.
129129
assert(WebAssembly.instantiateStreaming || Module['wasm'], 'Must load WebAssembly Module in to variable Module.wasm before adding compiled output .js script to the DOM');
130130
#endif
131+
#if AUDIO_WORKLET
132+
instantiatePromise =
133+
#endif
131134
(WebAssembly.instantiateStreaming
132135
#if ENVIRONMENT_MAY_BE_NODE
133136
// Node's fetch API cannot be used for local files, so we cannot use instantiateStreaming
@@ -136,6 +139,9 @@ assert(WebAssembly.instantiateStreaming || Module['wasm'], 'Must load WebAssembl
136139
? WebAssembly.instantiateStreaming(fetch('{{{ TARGET_BASENAME }}}.wasm'), imports)
137140
: WebAssembly.instantiate(Module['wasm'], imports)).then((output) => {
138141
#else
142+
#if AUDIO_WORKLET
143+
instantiatePromise =
144+
#endif
139145
WebAssembly.instantiateStreaming(fetch('{{{ TARGET_BASENAME }}}.wasm'), imports).then((output) => {
140146
#endif
141147

@@ -152,6 +158,9 @@ assert(Module['wasm'], 'Must load WebAssembly Module in to variable Module.wasm
152158

153159
// Add missingProperties supression here because closure compiler doesn't know that
154160
// WebAssembly.instantiate is polymorphic in its return value.
161+
#if AUDIO_WORKLET
162+
instantiatePromise =
163+
#endif
155164
WebAssembly.instantiate(Module['wasm'], imports).then(/** @suppress {missingProperties} */ (output) => {
156165
#endif
157166

test/code_size/audio_worklet_wasm.js

Lines changed: 81 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
var l = globalThis.Module || "undefined" != typeof Module ? Module : {}, n = "em-ww" == globalThis.name, q = "undefined" !== typeof AudioWorkletGlobalScope, t, v, J, K, E, F, A, X, H, C, B, Y, Z;
1+
var l = globalThis.Module || "undefined" != typeof Module ? Module : {}, n = "em-ww" == globalThis.name, q = "undefined" !== typeof AudioWorkletGlobalScope, t, A, v, K, L, F, H, B, X, I, E, C, Y, Z;
22

33
q && (n = !0);
44

@@ -23,7 +23,7 @@ if (q) {
2323
constructor(d) {
2424
super();
2525
d = d.processorOptions;
26-
this.u = A.get(d.u);
26+
this.u = B.get(d.u);
2727
this.v = d.v;
2828
this.s = d.s;
2929
}
@@ -35,47 +35,48 @@ if (q) {
3535
for (k of d) f += k.length * x;
3636
for (k of g) f += k.length * x;
3737
for (k in h) f += h[k].byteLength + 8, ++D;
38-
var V = B(), G = C(f);
38+
var W = C(), G = E(f);
3939
f = G;
4040
var m = G + 12 * p;
4141
for (k of d) {
42-
E[f >> 2] = k.length;
43-
E[f + 4 >> 2] = this.s;
44-
E[f + 8 >> 2] = m;
42+
F[f >> 2] = k.length;
43+
F[f + 4 >> 2] = this.s;
44+
F[f + 8 >> 2] = m;
4545
f += 12;
46-
for (r of k) F.set(r, m >> 2), m += x;
46+
for (r of k) H.set(r, m >> 2), m += x;
4747
}
48-
var O = m;
49-
f = O;
48+
var P = m;
49+
f = P;
5050
d = m += 12 * w;
51-
for (k of g) E[f >> 2] = k.length, E[f + 4 >> 2] = this.s, E[f + 8 >> 2] = m, f += 12,
51+
for (k of g) F[f >> 2] = k.length, F[f + 4 >> 2] = this.s, F[f + 8 >> 2] = m, f += 12,
5252
m += x * k.length;
5353
f = x = m;
5454
m += 8 * D;
55-
for (k = 0; r = h[k++]; ) E[f >> 2] = r.length, E[f + 4 >> 2] = m, f += 8, F.set(r, m >> 2),
55+
for (k = 0; r = h[k++]; ) F[f >> 2] = r.length, F[f + 4 >> 2] = m, f += 8, H.set(r, m >> 2),
5656
m += 4 * r.length;
57-
if (h = this.u(p, G, w, O, D, x, this.v)) {
57+
if (h = this.u(p, G, w, P, D, x, this.v)) {
5858
d >>= 2;
59-
for (k of g) for (r of k) for (f = 0; f < this.s; ++f) r[f] = F[d++];
59+
for (k of g) for (r of k) for (f = 0; f < this.s; ++f) r[f] = H[d++];
6060
}
61-
H(V);
61+
I(W);
6262
return !!h;
6363
}
6464
}
6565
return e;
6666
}
67-
var I;
67+
var J;
6868
class b extends AudioWorkletProcessor {
6969
constructor(c) {
7070
super();
7171
u(c.processorOptions);
72-
I = this.port;
73-
I.onmessage = async e => {
72+
J = this.port;
73+
J.onmessage = async e => {
74+
await A;
7475
e = e.data;
75-
e._wpn ? (registerProcessor(e._wpn, a(e.D)), I.postMessage({
76+
e._wpn ? (registerProcessor(e._wpn, a(e.D)), J.postMessage({
7677
_wsc: e.u,
7778
A: [ e.F, 1, e.v ]
78-
})) : e._wsc && A.get(e._wsc)(...e.A);
79+
})) : e._wsc && B.get(e._wsc)(...e.A);
7980
};
8081
}
8182
process() {}
@@ -85,10 +86,10 @@ if (q) {
8586

8687
function y() {
8788
var a = v.buffer;
88-
J = new Uint8Array(a);
89-
K = new Int32Array(a);
90-
E = new Uint32Array(a);
91-
F = new Float32Array(a);
89+
K = new Uint8Array(a);
90+
L = new Int32Array(a);
91+
F = new Uint32Array(a);
92+
H = new Float32Array(a);
9293
}
9394

9495
n || (v = l.mem || new WebAssembly.Memory({
@@ -97,17 +98,17 @@ n || (v = l.mem || new WebAssembly.Memory({
9798
shared: !0
9899
}), y());
99100

100-
var L = [], M = a => {
101+
var M = [], N = a => {
101102
a = a.data;
102103
let b = a._wsc;
103-
b && A.get(b)(...a.x);
104-
}, N = a => {
105-
L.push(a);
106-
}, P = a => H(a), Q = () => B(), S = (a, b, c, e) => {
107-
b = R[b];
108-
R[a].connect(b.destination || b, c, e);
109-
}, R = {}, T = 0, U = "undefined" != typeof TextDecoder ? new TextDecoder : void 0, W = (a = 0) => {
110-
for (var b = J, c = a, e = c + void 0; b[c] && !(c >= e); ) ++c;
104+
b && B.get(b)(...a.x);
105+
}, O = a => {
106+
M.push(a);
107+
}, Q = a => I(a), R = () => C(), aa = (a, b, c, e) => {
108+
b = S[b];
109+
S[a].connect(b.destination || b, c, e);
110+
}, S = {}, T = 0, U = "undefined" != typeof TextDecoder ? new TextDecoder : void 0, V = (a = 0) => {
111+
for (var b = K, c = a, e = c + void 0; b[c] && !(c >= e); ) ++c;
111112
if (16 < c - a && b.buffer && U) return U.decode(b.slice(a, c));
112113
for (e = ""; a < c; ) {
113114
var d = b[a++];
@@ -121,26 +122,26 @@ var L = [], M = a => {
121122
} else e += String.fromCharCode(d);
122123
}
123124
return e;
124-
}, aa = a => {
125+
}, ba = a => {
125126
var b = window.AudioContext || window.webkitAudioContext;
126127
if (a) {
127-
var c = E[a >> 2];
128+
var c = F[a >> 2];
128129
a = {
129-
latencyHint: (c ? W(c) : "") || void 0,
130-
sampleRate: E[a + 4 >> 2] || void 0
130+
latencyHint: (c ? V(c) : "") || void 0,
131+
sampleRate: F[a + 4 >> 2] || void 0
131132
};
132133
} else a = void 0;
133-
if (c = b) b = new b(a), R[++T] = b, c = T;
134+
if (c = b) b = new b(a), S[++T] = b, c = T;
134135
return c;
135-
}, ba = (a, b, c, e, d) => {
136-
var g = c ? K[c + 4 >> 2] : 0;
136+
}, ca = (a, b, c, e, d) => {
137+
var g = c ? L[c + 4 >> 2] : 0;
137138
if (c) {
138-
var h = K[c >> 2];
139-
c = E[c + 8 >> 2];
139+
var h = L[c >> 2];
140+
c = F[c + 8 >> 2];
140141
var p = g;
141142
if (c) {
142143
c >>= 2;
143-
for (var w = []; p--; ) w.push(E[c++]);
144+
for (var w = []; p--; ) w.push(F[c++]);
144145
c = w;
145146
} else c = void 0;
146147
e = {
@@ -154,87 +155,87 @@ var L = [], M = a => {
154155
}
155156
};
156157
} else e = void 0;
157-
a = new AudioWorkletNode(R[a], b ? W(b) : "", e);
158-
R[++T] = a;
158+
a = new AudioWorkletNode(S[a], b ? V(b) : "", e);
159+
S[++T] = a;
159160
return T;
160-
}, ca = (a, b, c, e) => {
161-
var d = [], g = (g = E[b >> 2]) ? W(g) : "", h = K[b + 4 >> 2];
162-
b = E[b + 8 >> 2];
161+
}, da = (a, b, c, e) => {
162+
var d = [], g = (g = F[b >> 2]) ? V(g) : "", h = L[b + 4 >> 2];
163+
b = F[b + 8 >> 2];
163164
for (var p = 0; h--; ) d.push({
164165
name: p++,
165-
defaultValue: F[b >> 2],
166-
minValue: F[b + 4 >> 2],
167-
maxValue: F[b + 8 >> 2],
168-
automationRate: (K[b + 12 >> 2] ? "k" : "a") + "-rate"
166+
defaultValue: H[b >> 2],
167+
minValue: H[b + 4 >> 2],
168+
maxValue: H[b + 8 >> 2],
169+
automationRate: (L[b + 12 >> 2] ? "k" : "a") + "-rate"
169170
}), b += 16;
170-
R[a].audioWorklet.B.port.postMessage({
171+
S[a].audioWorklet.B.port.postMessage({
171172
_wpn: g,
172173
D: d,
173174
F: a,
174175
u: c,
175176
v: e
176177
});
177-
}, da = () => !1, ea = 1, fa = a => {
178+
}, ea = () => !1, fa = 1, ha = a => {
178179
a = a.data;
179180
var b = a._wsc;
180-
b && A.get(b)(...a.A);
181-
}, ha = a => C(a), ia = (a, b, c, e, d) => {
182-
var g = R[a], h = g.audioWorklet, p = () => {
183-
A.get(e)(a, 0, d);
181+
b && B.get(b)(...a.A);
182+
}, ia = a => E(a), ja = (a, b, c, e, d) => {
183+
var g = S[a], h = g.audioWorklet, p = () => {
184+
B.get(e)(a, 0, d);
184185
};
185186
if (!h) return p();
186187
h.addModule(l.js).then((() => {
187188
h.B = new AudioWorkletNode(g, "em-bootstrap", {
188189
processorOptions: {
189-
K: ea++,
190+
K: fa++,
190191
C: l.wasm,
191192
I: v,
192193
G: b,
193194
H: c
194195
}
195196
});
196-
h.B.port.onmessage = fa;
197-
A.get(e)(a, 1, d);
197+
h.B.port.onmessage = ha;
198+
B.get(e)(a, 1, d);
198199
})).catch(p);
199200
};
200201

201-
function ja(a) {
202+
function ka(a) {
202203
let b = document.createElement("button");
203204
b.innerHTML = "Toggle playback";
204205
document.body.appendChild(b);
205-
a = R[a];
206+
a = S[a];
206207
b.onclick = () => {
207208
"running" != a.state ? a.resume() : a.suspend();
208209
};
209210
}
210211

211212
function z() {
212213
Z = {
213-
f: ja,
214-
g: S,
215-
d: aa,
216-
h: ba,
217-
e: ca,
218-
b: da,
219-
c: ia,
214+
f: ka,
215+
g: aa,
216+
d: ba,
217+
h: ca,
218+
e: da,
219+
b: ea,
220+
c: ja,
220221
a: v
221222
};
222-
WebAssembly.instantiate(l.wasm, {
223+
A = WebAssembly.instantiate(l.wasm, {
223224
a: Z
224225
}).then((a => {
225226
a = (a.instance || a).exports;
226227
X = a.j;
227-
H = a.l;
228-
C = a.m;
229-
B = a.n;
228+
I = a.l;
229+
E = a.m;
230+
C = a.n;
230231
Y = a.o;
231-
A = a.k;
232-
l.stackSave = Q;
233-
l.stackAlloc = ha;
234-
l.stackRestore = P;
235-
l.wasmTable = A;
236-
n ? (Y(t.G, t.H), "undefined" === typeof AudioWorkletGlobalScope && (removeEventListener("message", N),
237-
L = L.forEach(M), addEventListener("message", M))) : a.i();
232+
B = a.k;
233+
l.stackSave = R;
234+
l.stackAlloc = ia;
235+
l.stackRestore = Q;
236+
l.wasmTable = B;
237+
n ? (Y(t.G, t.H), "undefined" === typeof AudioWorkletGlobalScope && (removeEventListener("message", O),
238+
M = M.forEach(N), addEventListener("message", N))) : a.i();
238239
n || X();
239240
}));
240241
}
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
22
"a.html": 519,
33
"a.html.gz": 357,
4-
"a.js": 3882,
5-
"a.js.gz": 2038,
4+
"a.js": 3896,
5+
"a.js.gz": 2049,
66
"a.wasm": 1288,
77
"a.wasm.gz": 860,
8-
"total": 5689,
9-
"total_gz": 3255
8+
"total": 5703,
9+
"total_gz": 3266
1010
}

0 commit comments

Comments
 (0)