Add ack message for worklet death; remove max pool size
This commit is contained in:
parent
753dc48b69
commit
7c5f53f9ae
4 changed files with 34 additions and 9 deletions
|
|
@ -8,7 +8,6 @@ This program is free software: you can redistribute it and/or modify it under th
|
||||||
const nodePools = new Map();
|
const nodePools = new Map();
|
||||||
const POOL_KEY = Symbol('nodePoolKey');
|
const POOL_KEY = Symbol('nodePoolKey');
|
||||||
const IS_WORKLET_DEAD = Symbol('nodePoolIsWorkletDead');
|
const IS_WORKLET_DEAD = Symbol('nodePoolIsWorkletDead');
|
||||||
const MAX_POOL_SIZE = 64;
|
|
||||||
|
|
||||||
export const isPoolable = (node) => !!node[POOL_KEY];
|
export const isPoolable = (node) => !!node[POOL_KEY];
|
||||||
|
|
||||||
|
|
@ -47,10 +46,8 @@ export const releaseNodeToPool = (node) => {
|
||||||
const now = node.context?.currentTime ?? 0;
|
const now = node.context?.currentTime ?? 0;
|
||||||
getParams(node).forEach((param) => param.cancelScheduledValues(now));
|
getParams(node).forEach((param) => param.cancelScheduledValues(now));
|
||||||
const pool = nodePools.get(key) ?? [];
|
const pool = nodePools.get(key) ?? [];
|
||||||
if (pool.length < MAX_POOL_SIZE) {
|
|
||||||
pool.push(new WeakRef(node));
|
pool.push(new WeakRef(node));
|
||||||
nodePools.set(key, pool);
|
nodePools.set(key, pool);
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const markWorkletAsDead = (worklet) => (worklet[IS_WORKLET_DEAD] = true);
|
export const markWorkletAsDead = (worklet) => (worklet[IS_WORKLET_DEAD] = true);
|
||||||
|
|
|
||||||
|
|
@ -186,7 +186,10 @@ export function registerSynthSounds() {
|
||||||
});
|
});
|
||||||
o.port.postMessage({ type: 'initialize' });
|
o.port.postMessage({ type: 'initialize' });
|
||||||
o.port.onmessage = (e) => {
|
o.port.onmessage = (e) => {
|
||||||
if (e.data.type === 'died') markWorkletAsDead(o);
|
if (e.data.type === 'died') {
|
||||||
|
markWorkletAsDead(o);
|
||||||
|
o.port.postMessage({ type: 'diedACK' });
|
||||||
|
}
|
||||||
o.port.onmessage = null;
|
o.port.onmessage = null;
|
||||||
};
|
};
|
||||||
const gainAdjustment = 1 / Math.sqrt(voices);
|
const gainAdjustment = 1 / Math.sqrt(voices);
|
||||||
|
|
|
||||||
|
|
@ -252,7 +252,10 @@ export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) {
|
||||||
});
|
});
|
||||||
source.port.postMessage({ type: 'initialize', payload });
|
source.port.postMessage({ type: 'initialize', payload });
|
||||||
source.port.onmessage = (e) => {
|
source.port.onmessage = (e) => {
|
||||||
if (e.data.type === 'died') markWorkletAsDead(source);
|
if (e.data.type === 'died') {
|
||||||
|
markWorkletAsDead(source);
|
||||||
|
source.port.postMessage({ type: 'diedACK' });
|
||||||
|
}
|
||||||
source.port.onmessage = null;
|
source.port.onmessage = null;
|
||||||
};
|
};
|
||||||
if (ac.currentTime > t) {
|
if (ac.currentTime > t) {
|
||||||
|
|
|
||||||
|
|
@ -464,11 +464,19 @@ class SuperSawOscillatorProcessor extends AudioWorkletProcessor {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.isAlive = true; // used internally to prevent multiple death messages
|
this.isAlive = true; // used internally to prevent multiple death messages
|
||||||
|
// diedACK is used for the main thread to acknowledge that the worklet has died
|
||||||
|
// This is so that we don't risk simultaneously killing the worklet (`return false`)
|
||||||
|
// and pooling the worklet (main thread) before the async `died` message hits
|
||||||
|
// the main thread
|
||||||
|
this.diedACK = false;
|
||||||
this.port.onmessage = (e) => {
|
this.port.onmessage = (e) => {
|
||||||
const { type, payload } = e.data || {};
|
const { type, payload } = e.data || {};
|
||||||
if (type === 'initialize') {
|
if (type === 'initialize') {
|
||||||
this.initialize(payload);
|
this.initialize(payload);
|
||||||
}
|
}
|
||||||
|
if (type === 'diedACK') {
|
||||||
|
this.diedACK = true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
this.initialize();
|
this.initialize();
|
||||||
}
|
}
|
||||||
|
|
@ -529,8 +537,11 @@ class SuperSawOscillatorProcessor extends AudioWorkletProcessor {
|
||||||
this.port.postMessage({ type: 'died' });
|
this.port.postMessage({ type: 'died' });
|
||||||
this.isAlive = false;
|
this.isAlive = false;
|
||||||
}
|
}
|
||||||
|
if (this.diedACK || currentTime >= params.end[1] + 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (currentTime >= params.end[0] || currentTime <= params.begin[0]) {
|
if (currentTime >= params.end[0] || currentTime <= params.begin[0]) {
|
||||||
// Inside of grace period or not yet started
|
// Inside of grace period or not yet started
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1165,11 +1176,19 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
super(options);
|
super(options);
|
||||||
this.isAlive = true; // used internally to prevent multiple death messages
|
this.isAlive = true; // used internally to prevent multiple death messages
|
||||||
|
// diedACK is used for the main thread to acknowledge that the worklet has died
|
||||||
|
// This is so that we don't risk simultaneously killing the worklet (`return false`)
|
||||||
|
// and pooling the worklet (main thread) before the async `died` message hits
|
||||||
|
// the main thread
|
||||||
|
this.diedACK = false;
|
||||||
this.port.onmessage = (e) => {
|
this.port.onmessage = (e) => {
|
||||||
const { type, payload } = e.data || {};
|
const { type, payload } = e.data || {};
|
||||||
if (type === 'initialize') {
|
if (type === 'initialize') {
|
||||||
this.initialize(payload);
|
this.initialize(payload);
|
||||||
}
|
}
|
||||||
|
if (type === 'diedACK') {
|
||||||
|
this.diedACK = true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
this.initialize();
|
this.initialize();
|
||||||
}
|
}
|
||||||
|
|
@ -1338,8 +1357,11 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor {
|
||||||
this.port.postMessage({ type: 'died' });
|
this.port.postMessage({ type: 'died' });
|
||||||
this.isAlive = false;
|
this.isAlive = false;
|
||||||
}
|
}
|
||||||
|
if (this.diedACK || currentTime >= parameters.end[1] + 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (currentTime >= parameters.end[0] || currentTime <= parameters.begin[0]) {
|
if (currentTime >= parameters.end[0] || currentTime <= parameters.begin[0]) {
|
||||||
// Inside of grace period or not yet started
|
// Inside of grace period or not yet started
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue