Skip to content

Commit 54b97db

Browse files
authored
Add testing for audio worklets + pthreads. NFC (#26982)
This should have been part of #25930
1 parent 8672d43 commit 54b97db

5 files changed

Lines changed: 153 additions & 113 deletions

File tree

src/lib/libwebaudio.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,11 @@ var LibraryWebAudio = {
186186
assert(stackSize % 16 == 0, `AudioWorklet stack size should be a multiple of 16 bytes! (was ${stackSize} == ${stackSize%16} mod 16)`);
187187
assert(!audioContext.audioWorkletInitialized, `emscripten_create_wasm_audio_worklet() was already called for AudioContext ${contextHandle}! Only call this function once per AudioContext`);
188188
audioContext.audioWorkletInitialized = 1;
189+
#if PTHREADS
190+
assert(pthreadPtr);
191+
#else
192+
assert(!pthreadPtr);
193+
#endif
189194
#endif
190195

191196
#if WEBAUDIO_DEBUG

system/lib/wasm_worker/audio_worklet.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@
1414
// function that adds the _emscripten_get_next_tid() as arg0
1515
void emscripten_start_wasm_audio_worklet_thread_async(EMSCRIPTEN_WEBAUDIO_T audioContext, void *stackLowestAddress, uint32_t stackSize, EmscriptenStartWebAudioWorkletCallback callback, void *userData2) {
1616
emscripten_wasm_worker_t wwID = _emscripten_get_next_tid();
17-
void* pthreadPtr = stackLowestAddress;
1817
#ifdef __EMSCRIPTEN_PTHREADS__
18+
void* pthreadPtr = stackLowestAddress;
1919
size_t stackSize_ = stackSize;
2020
stackLowestAddress = _emscripten_init_pthread(stackLowestAddress, &stackSize_, wwID);
2121
stackSize = stackSize_;
22+
#else
23+
void* pthreadPtr = NULL;
2224
#endif
2325
_emscripten_create_audio_worklet(wwID, audioContext, stackLowestAddress, stackSize, pthreadPtr, callback, userData2);
2426
}
Lines changed: 115 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,36 @@
1-
var m = globalThis.Module || typeof Module != "undefined" ? Module : {}, r = !!globalThis.AudioWorkletGlobalScope, t = globalThis.name == "em-ww" || r, u, z, J, E, G, I, w, X, F, D, C, Y, A, Z;
1+
var m = globalThis.Module || typeof Module != "undefined" ? Module : {}, r = !!globalThis.WorkerGlobalScope, t = !!globalThis.AudioWorkletGlobalScope, u = globalThis.name == "em-ww" || t, v, A, K, F, H, J, x, W, O, G, E, D, X, C, Z;
22

3-
function v(a) {
4-
u = a;
5-
w = a.I;
6-
x();
3+
function w(a) {
4+
v = a;
5+
x = a.I;
6+
y();
77
m ||= {};
88
m.wasm = a.H;
9-
y();
9+
z();
1010
a.H = a.I = 0;
1111
}
1212

13-
t && !r && (onmessage = a => {
13+
u && !t && (onmessage = a => {
1414
onmessage = null;
15-
v(a.data);
15+
w(a.data);
1616
});
1717

18-
if (r) {
18+
if (t) {
1919
function a(c) {
2020
class k extends AudioWorkletProcessor {
2121
constructor(d) {
2222
super();
2323
d = d.processorOptions;
24-
this.A = A.get(d.A);
24+
this.A = C.get(d.A);
2525
this.B = d.B;
2626
this.u = d.u;
2727
this.v = this.u * 4;
28-
this.C = Array(Math.min((u.G - 16) / this.v | 0, 64));
28+
this.C = Array(Math.min((v.G - 16) / this.v | 0, 64));
2929
this.J();
3030
}
3131
J() {
32-
for (var d = C(), g = D(this.C.length * this.v) >> 2, f = this.C.length - 1; f >= 0; f--) this.C[f] = E.subarray(g, g += this.u);
33-
F(d);
32+
for (var d = D(), g = E(this.C.length * this.v) >> 2, f = this.C.length - 1; f >= 0; f--) this.C[f] = F.subarray(g, g += this.u);
33+
G(d);
3434
}
3535
static get parameterDescriptors() {
3636
return c;
@@ -39,30 +39,30 @@ if (r) {
3939
var l = d.length, n = g.length, e, q, h = (l + n) * 12, p = 0;
4040
for (e of d) p += e.length;
4141
p *= this.v;
42-
var H = 0;
43-
for (e of g) H += e.length;
44-
p += H * this.v;
45-
var O = 0;
46-
for (e in f) ++O, h += 8, p += f[e].byteLength;
47-
var V = C(), B = h + p + 15 & -16;
48-
h = D(B);
42+
var I = 0;
43+
for (e of g) I += e.length;
44+
p += I * this.v;
45+
var P = 0;
46+
for (e in f) ++P, h += 8, p += f[e].byteLength;
47+
var Y = D(), B = h + p + 15 & -16;
48+
h = E(B);
4949
p = h + (B - p);
5050
B = h;
5151
for (e of d) {
52-
G[h >> 2] = e.length;
53-
G[h + 4 >> 2] = this.u;
54-
G[h + 8 >> 2] = p;
52+
H[h >> 2] = e.length;
53+
H[h + 4 >> 2] = this.u;
54+
H[h + 8 >> 2] = p;
5555
h += 12;
56-
for (q of e) E.set(q, p >> 2), p += this.v;
56+
for (q of e) F.set(q, p >> 2), p += this.v;
5757
}
5858
d = h;
59-
for (e = 0; q = f[e++]; ) G[h >> 2] = q.length, G[h + 4 >> 2] = p, h += 8, E.set(q, p >> 2),
59+
for (e = 0; q = f[e++]; ) H[h >> 2] = q.length, H[h + 4 >> 2] = p, h += 8, F.set(q, p >> 2),
6060
p += q.length * 4;
6161
f = h;
62-
for (e of g) G[h >> 2] = e.length, G[h + 4 >> 2] = this.u, G[h + 8 >> 2] = p, h += 12,
62+
for (e of g) H[h >> 2] = e.length, H[h + 4 >> 2] = this.u, H[h + 8 >> 2] = p, h += 12,
6363
p += this.v * e.length;
64-
if (l = this.A(l, B, n, f, O, d, this.B)) for (e of g) for (q of e) q.set(this.C[--H]);
65-
F(V);
64+
if (l = this.A(l, B, n, f, P, d, this.B)) for (e of g) for (q of e) q.set(this.C[--I]);
65+
G(Y);
6666
return !!l;
6767
}
6868
}
@@ -72,50 +72,52 @@ if (r) {
7272
class b extends AudioWorkletProcessor {
7373
constructor(c) {
7474
super();
75-
v(c.processorOptions);
75+
w(c.processorOptions);
7676
port instanceof MessagePort || (this.port.onmessage = port.onmessage, port = this.port);
7777
}
7878
process() {}
7979
}
8080
registerProcessor("em-bootstrap", b);
8181
port.onmessage = async c => {
82-
await z;
82+
await A;
8383
c = c.data;
84-
c._boot ? v(c) : c._wpn ? (registerProcessor(c._wpn, a(c.K)), port.postMessage({
84+
c._boot ? w(c) : c._wpn ? (registerProcessor(c._wpn, a(c.K)), port.postMessage({
8585
_wsc: c.A,
8686
D: [ c.L, 1, c.B ]
87-
})) : c._wsc && A.get(c._wsc)(...c.D);
87+
})) : c._wsc && C.get(c._wsc)(...c.D);
8888
};
8989
}
9090

91-
function x() {
92-
var a = w.buffer;
93-
I = new Uint8Array(a);
94-
J = new Int32Array(a);
95-
G = new Uint32Array(a);
96-
E = new Float32Array(a);
91+
function y() {
92+
var a = x.buffer;
93+
J = new Uint8Array(a);
94+
K = new Int32Array(a);
95+
H = new Uint32Array(a);
96+
F = new Float32Array(a);
9797
}
9898

99-
t || (w = m.mem || new WebAssembly.Memory({
99+
u || (x = m.mem || new WebAssembly.Memory({
100100
initial: 256,
101101
maximum: 256,
102102
shared: !0
103-
}), x());
103+
}), y());
104104

105-
var K = [], L = a => {
105+
var L = [], M = a => {
106106
a = a.data;
107107
var b = a._wsc;
108-
b && A.get(b)(...a.x);
109-
}, M = a => {
110-
K.push(a);
108+
b && C.get(b)(...a.x);
111109
}, N = a => {
110+
L.push(a);
111+
}, aa = () => {
112+
O(0, !r && !t, !u, r && !t);
113+
}, ba = a => {
112114
a = a.data;
113115
var b = a._wsc;
114-
b && A.get(b)(...a.D);
115-
}, Q = (a, b, c, k, d, g, f) => {
116-
var l = P[b], n = l.audioWorklet;
116+
b && C.get(b)(...a.D);
117+
}, ca = (a, b, c, k, d, g, f) => {
118+
var l = Q[b], n = l.audioWorklet;
117119
d = () => {
118-
A.get(g)(b, 0, f);
120+
C.get(g)(b, 0, f);
119121
};
120122
if (!n) return d();
121123
n.addModule(m.js).then((() => {
@@ -132,19 +134,19 @@ var K = [], L = a => {
132134
_boot: 1,
133135
N: a,
134136
H: m.wasm,
135-
I: w,
137+
I: x,
136138
M: c,
137139
G: k
138140
});
139-
n.port.onmessage = N;
140-
A.get(g)(b, 1, f);
141+
n.port.onmessage = ba;
142+
C.get(g)(b, 1, f);
141143
})).catch(d);
142-
}, R = (a, b, c, k) => {
143-
b = P[b];
144-
P[a].connect(b.destination || b, c, k);
145-
}, P = {}, S = 0, T = globalThis.TextDecoder && new TextDecoder, U = (a = 0) => {
146-
for (var b = I, c = a, k = c + void 0; b[c] && !(c >= k); ) ++c;
147-
if (c - a > 16 && b.buffer && T) return T.decode(b.slice(a, c));
144+
}, da = (a, b, c, k) => {
145+
b = Q[b];
146+
Q[a].connect(b.destination || b, c, k);
147+
}, Q = {}, R = 0, S = globalThis.TextDecoder && new TextDecoder, T = (a = 0) => {
148+
for (var b = J, c = a, k = c + void 0; b[c] && !(c >= k); ) ++c;
149+
if (c - a > 16 && b.buffer && S) return S.decode(b.slice(a, c));
148150
for (k = ""; a < c; ) {
149151
var d = b[a++];
150152
if (d & 128) {
@@ -157,102 +159,109 @@ var K = [], L = a => {
157159
} else k += String.fromCharCode(d);
158160
}
159161
return k;
160-
}, aa = a => {
162+
}, ea = a => {
161163
if (a) {
162-
var b = G[a >> 2];
163-
b = (b ? U(b) : "") || void 0;
164-
var c = J[a + 8 >> 2];
164+
var b = H[a >> 2];
165+
b = (b ? T(b) : "") || void 0;
166+
var c = K[a + 8 >> 2];
165167
a = {
166168
latencyHint: b,
167-
sampleRate: G[a + 4 >> 2] || void 0,
169+
sampleRate: H[a + 4 >> 2] || void 0,
168170
O: c < 0 ? "hardware" : c || "default"
169171
};
170172
} else a = void 0;
171173
a = new AudioContext(a);
172-
P[++S] = a;
173-
return S;
174-
}, ba = (a, b, c, k, d) => {
175-
var g = c ? J[c + 4 >> 2] : 0;
174+
Q[++R] = a;
175+
return R;
176+
}, fa = (a, b, c, k, d) => {
177+
var g = c ? K[c + 4 >> 2] : 0;
176178
if (c) {
177-
var f = J[c >> 2], l = G[c + 8 >> 2], n = g;
179+
var f = K[c >> 2], l = H[c + 8 >> 2], n = g;
178180
if (l) {
179181
l >>= 2;
180-
for (var e = []; n--; ) e.push(G[l++]);
182+
for (var e = []; n--; ) e.push(H[l++]);
181183
l = e;
182184
} else l = void 0;
183185
c = {
184186
numberOfInputs: f,
185187
numberOfOutputs: g,
186188
outputChannelCount: l,
187-
channelCount: G[c + 12 >> 2] || void 0,
188-
channelCountMode: [ , "clamped-max", "explicit" ][J[c + 16 >> 2]],
189-
channelInterpretation: [ , "discrete" ][J[c + 20 >> 2]],
189+
channelCount: H[c + 12 >> 2] || void 0,
190+
channelCountMode: [ , "clamped-max", "explicit" ][K[c + 16 >> 2]],
191+
channelInterpretation: [ , "discrete" ][K[c + 20 >> 2]],
190192
processorOptions: {
191193
A: k,
192194
B: d,
193-
u: P[a].renderQuantumSize || 128
195+
u: Q[a].renderQuantumSize || 128
194196
}
195197
};
196198
} else c = void 0;
197-
a = new AudioWorkletNode(P[a], b ? U(b) : "", c);
198-
P[++S] = a;
199-
return S;
200-
}, ca = (a, b, c, k) => {
201-
var d = (d = G[b >> 2]) ? U(d) : "", g = J[b + 4 >> 2];
202-
b = G[b + 8 >> 2];
199+
a = new AudioWorkletNode(Q[a], b ? T(b) : "", c);
200+
Q[++R] = a;
201+
return R;
202+
}, ha = (a, b, c, k) => {
203+
var d = (d = H[b >> 2]) ? T(d) : "", g = K[b + 4 >> 2];
204+
b = H[b + 8 >> 2];
203205
for (var f = [], l = 0; g--; ) f.push({
204206
name: l++,
205-
defaultValue: E[b >> 2],
206-
minValue: E[b + 4 >> 2],
207-
maxValue: E[b + 8 >> 2],
208-
automationRate: (J[b + 12 >> 2] ? "k" : "a") + "-rate"
207+
defaultValue: F[b >> 2],
208+
minValue: F[b + 4 >> 2],
209+
maxValue: F[b + 8 >> 2],
210+
automationRate: (K[b + 12 >> 2] ? "k" : "a") + "-rate"
209211
}), b += 16;
210-
P[a].audioWorklet.port.postMessage({
212+
Q[a].audioWorklet.port.postMessage({
211213
_wpn: d,
212214
K: f,
213215
L: a,
214216
A: c,
215217
B: k
216218
});
217-
}, da = () => !1, ea = () => r ? () => 138 : a => (a.set(crypto.getRandomValues(new Uint8Array(a.byteLength))),
218-
0), W = a => (W = ea())(a), fa = (a, b) => W(I.subarray(a, a + b));
219+
}, U = globalThis.performance?.now ? () => performance.now() : Date.now, ia = a => {
220+
a = [ a ? T(a) : "" ];
221+
return console.log(...a);
222+
}, ja = () => !1, ka = () => t ? () => 138 : a => (a.set(crypto.getRandomValues(new Uint8Array(a.byteLength))),
223+
0), V = a => (V = ka())(a), la = (a, b) => V(J.subarray(a, a + b));
219224

220-
function ha(a) {
225+
function ma(a) {
221226
var b = document.createElement("button");
222227
b.innerHTML = "Toggle playback";
223228
document.body.appendChild(b);
224-
a = P[a];
229+
a = Q[a];
225230
b.onclick = () => {
226231
a.state != "running" ? a.resume() : a.suspend();
227232
};
228233
}
229234

230-
function y() {
235+
function z() {
231236
Z = {
232-
g: ha,
233-
c: Q,
234-
h: R,
237+
i: ma,
235238
e: aa,
236-
i: ba,
237-
f: ca,
238-
b: da,
239-
a: w,
240-
d: fa
239+
d: ca,
240+
k: da,
241+
g: ea,
242+
l: fa,
243+
h: ha,
244+
b: U,
245+
c: ia,
246+
j: ja,
247+
a: x,
248+
f: la
241249
};
242-
z = WebAssembly.instantiate(m.wasm, {
250+
A = WebAssembly.instantiate(m.wasm, {
243251
a: Z
244252
}).then((a => {
245253
a = (a.instance || a).exports;
246-
X = a.k;
247-
F = a.m;
248-
D = a.n;
254+
W = a.n;
255+
O = a.p;
256+
G = a.q;
257+
E = a.r;
258+
D = a.s;
259+
X = a.t;
249260
C = a.o;
250-
Y = a.p;
251-
A = a.l;
252-
t ? (Y(u.N, u.M, u.G), r || (removeEventListener("message", M), K = K.forEach(L),
253-
addEventListener("message", L))) : a.j();
254-
t || X();
261+
u ? (X(v.N, v.M, v.G), t || (removeEventListener("message", N), L = L.forEach(M),
262+
addEventListener("message", M))) : a.m();
263+
u || W();
255264
}));
256265
}
257266

258-
t || y();
267+
u || z();

0 commit comments

Comments
 (0)