Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/lib/libwebaudio.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,11 @@ var LibraryWebAudio = {
assert(stackSize % 16 == 0, `AudioWorklet stack size should be a multiple of 16 bytes! (was ${stackSize} == ${stackSize%16} mod 16)`);
assert(!audioContext.audioWorkletInitialized, `emscripten_create_wasm_audio_worklet() was already called for AudioContext ${contextHandle}! Only call this function once per AudioContext`);
audioContext.audioWorkletInitialized = 1;
#if PTHREADS
assert(pthreadPtr);
#else
assert(!pthreadPtr);
#endif
#endif

#if WEBAUDIO_DEBUG
Expand Down
4 changes: 3 additions & 1 deletion system/lib/wasm_worker/audio_worklet.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@
// function that adds the _emscripten_get_next_tid() as arg0
void emscripten_start_wasm_audio_worklet_thread_async(EMSCRIPTEN_WEBAUDIO_T audioContext, void *stackLowestAddress, uint32_t stackSize, EmscriptenStartWebAudioWorkletCallback callback, void *userData2) {
emscripten_wasm_worker_t wwID = _emscripten_get_next_tid();
void* pthreadPtr = stackLowestAddress;
#ifdef __EMSCRIPTEN_PTHREADS__
void* pthreadPtr = stackLowestAddress;
size_t stackSize_ = stackSize;
stackLowestAddress = _emscripten_init_pthread(stackLowestAddress, &stackSize_, wwID);
stackSize = stackSize_;
#else
void* pthreadPtr = NULL;
#endif
_emscripten_create_audio_worklet(wwID, audioContext, stackLowestAddress, stackSize, pthreadPtr, callback, userData2);
}
221 changes: 115 additions & 106 deletions test/codesize/audio_worklet_wasm.expected.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
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;
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;

function v(a) {
u = a;
w = a.I;
x();
function w(a) {
v = a;
x = a.I;
y();
m ||= {};
m.wasm = a.H;
y();
z();
a.H = a.I = 0;
}

t && !r && (onmessage = a => {
u && !t && (onmessage = a => {
onmessage = null;
v(a.data);
w(a.data);
});

if (r) {
if (t) {
function a(c) {
class k extends AudioWorkletProcessor {
constructor(d) {
super();
d = d.processorOptions;
this.A = A.get(d.A);
this.A = C.get(d.A);
this.B = d.B;
this.u = d.u;
this.v = this.u * 4;
this.C = Array(Math.min((u.G - 16) / this.v | 0, 64));
this.C = Array(Math.min((v.G - 16) / this.v | 0, 64));
this.J();
}
J() {
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);
F(d);
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);
G(d);
}
static get parameterDescriptors() {
return c;
Expand All @@ -39,30 +39,30 @@ if (r) {
var l = d.length, n = g.length, e, q, h = (l + n) * 12, p = 0;
for (e of d) p += e.length;
p *= this.v;
var H = 0;
for (e of g) H += e.length;
p += H * this.v;
var O = 0;
for (e in f) ++O, h += 8, p += f[e].byteLength;
var V = C(), B = h + p + 15 & -16;
h = D(B);
var I = 0;
for (e of g) I += e.length;
p += I * this.v;
var P = 0;
for (e in f) ++P, h += 8, p += f[e].byteLength;
var Y = D(), B = h + p + 15 & -16;
h = E(B);
p = h + (B - p);
B = h;
for (e of d) {
G[h >> 2] = e.length;
G[h + 4 >> 2] = this.u;
G[h + 8 >> 2] = p;
H[h >> 2] = e.length;
H[h + 4 >> 2] = this.u;
H[h + 8 >> 2] = p;
h += 12;
for (q of e) E.set(q, p >> 2), p += this.v;
for (q of e) F.set(q, p >> 2), p += this.v;
}
d = h;
for (e = 0; q = f[e++]; ) G[h >> 2] = q.length, G[h + 4 >> 2] = p, h += 8, E.set(q, p >> 2),
for (e = 0; q = f[e++]; ) H[h >> 2] = q.length, H[h + 4 >> 2] = p, h += 8, F.set(q, p >> 2),
p += q.length * 4;
f = h;
for (e of g) G[h >> 2] = e.length, G[h + 4 >> 2] = this.u, G[h + 8 >> 2] = p, h += 12,
for (e of g) H[h >> 2] = e.length, H[h + 4 >> 2] = this.u, H[h + 8 >> 2] = p, h += 12,
p += this.v * e.length;
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]);
F(V);
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]);
G(Y);
return !!l;
}
}
Expand All @@ -72,50 +72,52 @@ if (r) {
class b extends AudioWorkletProcessor {
constructor(c) {
super();
v(c.processorOptions);
w(c.processorOptions);
port instanceof MessagePort || (this.port.onmessage = port.onmessage, port = this.port);
}
process() {}
}
registerProcessor("em-bootstrap", b);
port.onmessage = async c => {
await z;
await A;
c = c.data;
c._boot ? v(c) : c._wpn ? (registerProcessor(c._wpn, a(c.K)), port.postMessage({
c._boot ? w(c) : c._wpn ? (registerProcessor(c._wpn, a(c.K)), port.postMessage({
_wsc: c.A,
D: [ c.L, 1, c.B ]
})) : c._wsc && A.get(c._wsc)(...c.D);
})) : c._wsc && C.get(c._wsc)(...c.D);
};
}

function x() {
var a = w.buffer;
I = new Uint8Array(a);
J = new Int32Array(a);
G = new Uint32Array(a);
E = new Float32Array(a);
function y() {
var a = x.buffer;
J = new Uint8Array(a);
K = new Int32Array(a);
H = new Uint32Array(a);
F = new Float32Array(a);
}

t || (w = m.mem || new WebAssembly.Memory({
u || (x = m.mem || new WebAssembly.Memory({
initial: 256,
maximum: 256,
shared: !0
}), x());
}), y());

var K = [], L = a => {
var L = [], M = a => {
a = a.data;
var b = a._wsc;
b && A.get(b)(...a.x);
}, M = a => {
K.push(a);
b && C.get(b)(...a.x);
}, N = a => {
L.push(a);
}, aa = () => {
O(0, !r && !t, !u, r && !t);
}, ba = a => {
a = a.data;
var b = a._wsc;
b && A.get(b)(...a.D);
}, Q = (a, b, c, k, d, g, f) => {
var l = P[b], n = l.audioWorklet;
b && C.get(b)(...a.D);
}, ca = (a, b, c, k, d, g, f) => {
var l = Q[b], n = l.audioWorklet;
d = () => {
A.get(g)(b, 0, f);
C.get(g)(b, 0, f);
};
if (!n) return d();
n.addModule(m.js).then((() => {
Expand All @@ -132,19 +134,19 @@ var K = [], L = a => {
_boot: 1,
N: a,
H: m.wasm,
I: w,
I: x,
M: c,
G: k
});
n.port.onmessage = N;
A.get(g)(b, 1, f);
n.port.onmessage = ba;
C.get(g)(b, 1, f);
})).catch(d);
}, R = (a, b, c, k) => {
b = P[b];
P[a].connect(b.destination || b, c, k);
}, P = {}, S = 0, T = globalThis.TextDecoder && new TextDecoder, U = (a = 0) => {
for (var b = I, c = a, k = c + void 0; b[c] && !(c >= k); ) ++c;
if (c - a > 16 && b.buffer && T) return T.decode(b.slice(a, c));
}, da = (a, b, c, k) => {
b = Q[b];
Q[a].connect(b.destination || b, c, k);
}, Q = {}, R = 0, S = globalThis.TextDecoder && new TextDecoder, T = (a = 0) => {
for (var b = J, c = a, k = c + void 0; b[c] && !(c >= k); ) ++c;
if (c - a > 16 && b.buffer && S) return S.decode(b.slice(a, c));
for (k = ""; a < c; ) {
var d = b[a++];
if (d & 128) {
Expand All @@ -157,102 +159,109 @@ var K = [], L = a => {
} else k += String.fromCharCode(d);
}
return k;
}, aa = a => {
}, ea = a => {
if (a) {
var b = G[a >> 2];
b = (b ? U(b) : "") || void 0;
var c = J[a + 8 >> 2];
var b = H[a >> 2];
b = (b ? T(b) : "") || void 0;
var c = K[a + 8 >> 2];
a = {
latencyHint: b,
sampleRate: G[a + 4 >> 2] || void 0,
sampleRate: H[a + 4 >> 2] || void 0,
O: c < 0 ? "hardware" : c || "default"
};
} else a = void 0;
a = new AudioContext(a);
P[++S] = a;
return S;
}, ba = (a, b, c, k, d) => {
var g = c ? J[c + 4 >> 2] : 0;
Q[++R] = a;
return R;
}, fa = (a, b, c, k, d) => {
var g = c ? K[c + 4 >> 2] : 0;
if (c) {
var f = J[c >> 2], l = G[c + 8 >> 2], n = g;
var f = K[c >> 2], l = H[c + 8 >> 2], n = g;
if (l) {
l >>= 2;
for (var e = []; n--; ) e.push(G[l++]);
for (var e = []; n--; ) e.push(H[l++]);
l = e;
} else l = void 0;
c = {
numberOfInputs: f,
numberOfOutputs: g,
outputChannelCount: l,
channelCount: G[c + 12 >> 2] || void 0,
channelCountMode: [ , "clamped-max", "explicit" ][J[c + 16 >> 2]],
channelInterpretation: [ , "discrete" ][J[c + 20 >> 2]],
channelCount: H[c + 12 >> 2] || void 0,
channelCountMode: [ , "clamped-max", "explicit" ][K[c + 16 >> 2]],
channelInterpretation: [ , "discrete" ][K[c + 20 >> 2]],
processorOptions: {
A: k,
B: d,
u: P[a].renderQuantumSize || 128
u: Q[a].renderQuantumSize || 128
}
};
} else c = void 0;
a = new AudioWorkletNode(P[a], b ? U(b) : "", c);
P[++S] = a;
return S;
}, ca = (a, b, c, k) => {
var d = (d = G[b >> 2]) ? U(d) : "", g = J[b + 4 >> 2];
b = G[b + 8 >> 2];
a = new AudioWorkletNode(Q[a], b ? T(b) : "", c);
Q[++R] = a;
return R;
}, ha = (a, b, c, k) => {
var d = (d = H[b >> 2]) ? T(d) : "", g = K[b + 4 >> 2];
b = H[b + 8 >> 2];
for (var f = [], l = 0; g--; ) f.push({
name: l++,
defaultValue: E[b >> 2],
minValue: E[b + 4 >> 2],
maxValue: E[b + 8 >> 2],
automationRate: (J[b + 12 >> 2] ? "k" : "a") + "-rate"
defaultValue: F[b >> 2],
minValue: F[b + 4 >> 2],
maxValue: F[b + 8 >> 2],
automationRate: (K[b + 12 >> 2] ? "k" : "a") + "-rate"
}), b += 16;
P[a].audioWorklet.port.postMessage({
Q[a].audioWorklet.port.postMessage({
_wpn: d,
K: f,
L: a,
A: c,
B: k
});
}, da = () => !1, ea = () => r ? () => 138 : a => (a.set(crypto.getRandomValues(new Uint8Array(a.byteLength))),
0), W = a => (W = ea())(a), fa = (a, b) => W(I.subarray(a, a + b));
}, U = globalThis.performance?.now ? () => performance.now() : Date.now, ia = a => {
a = [ a ? T(a) : "" ];
return console.log(...a);
}, ja = () => !1, ka = () => t ? () => 138 : a => (a.set(crypto.getRandomValues(new Uint8Array(a.byteLength))),
0), V = a => (V = ka())(a), la = (a, b) => V(J.subarray(a, a + b));

function ha(a) {
function ma(a) {
var b = document.createElement("button");
b.innerHTML = "Toggle playback";
document.body.appendChild(b);
a = P[a];
a = Q[a];
b.onclick = () => {
a.state != "running" ? a.resume() : a.suspend();
};
}

function y() {
function z() {
Z = {
g: ha,
c: Q,
h: R,
i: ma,
e: aa,
i: ba,
f: ca,
b: da,
a: w,
d: fa
d: ca,
k: da,
g: ea,
l: fa,
h: ha,
b: U,
c: ia,
j: ja,
a: x,
f: la
};
z = WebAssembly.instantiate(m.wasm, {
A = WebAssembly.instantiate(m.wasm, {
a: Z
}).then((a => {
a = (a.instance || a).exports;
X = a.k;
F = a.m;
D = a.n;
W = a.n;
O = a.p;
G = a.q;
E = a.r;
D = a.s;
X = a.t;
C = a.o;
Y = a.p;
A = a.l;
t ? (Y(u.N, u.M, u.G), r || (removeEventListener("message", M), K = K.forEach(L),
addEventListener("message", L))) : a.j();
t || X();
u ? (X(v.N, v.M, v.G), t || (removeEventListener("message", N), L = L.forEach(M),
addEventListener("message", M))) : a.m();
u || W();
}));
}

t || y();
u || z();
Loading
Loading