Working version of supersaw, almost on wavetable

This commit is contained in:
Aria
2025-12-04 12:40:28 -06:00
parent 600ab0a83e
commit 6610713018
4 changed files with 22 additions and 5 deletions
+4
View File
@@ -38,6 +38,10 @@ export const releaseNodeToPool = (node) => {
// not reusable
return;
}
if (node[IS_WORKLET_DEAD]) {
// Worklet already terminated, don't pool it
return;
}
// Fallback to a type-based key if the node was not created via getNodeFromPool
const key = node[POOL_KEY];
if (key == null) return;
+2 -1
View File
@@ -181,8 +181,9 @@ export function registerSynthSounds() {
}
});
o.port.postMessage({ type: 'initialize' });
o.port.onMessage = (e) => {
o.port.onmessage = (e) => {
if (e.data.type === 'died') markWorkletAsDead(o);
o.port.onmessage = null;
};
const gainAdjustment = 1 / Math.sqrt(voices);
getPitchEnvelope(o.parameters.get('detune'), value, begin, holdend);
+2 -1
View File
@@ -244,8 +244,9 @@ export async function onTriggerSynth(t, value, onended, tables, cps, frameLen) {
}
});
source.port.postMessage({ type: 'initialize', payload });
source.port.onMessage = (e) => {
source.port.onmessage = (e) => {
if (e.data.type === 'died') markWorkletAsDead(source);
source.port.onmessage = null;
};
if (ac.currentTime > t) {
logger(`[wavetable] still loading sound "${s}:${n}"`, 'highlight');
+14 -3
View File
@@ -458,6 +458,7 @@ registerProcessor('distort-processor', DistortProcessor);
class SuperSawOscillatorProcessor extends AudioWorkletProcessor {
constructor() {
super();
this.isAlive = true; // used internally to prevent multiple death messages
this.port.onmessage = (e) => {
const { type, payload } = e.data || {};
if (type === 'initialize') {
@@ -519,6 +520,10 @@ class SuperSawOscillatorProcessor extends AudioWorkletProcessor {
process(_input, outputs, params) {
if (currentTime >= params.end[0]) {
// should terminate
if (this.isAlive) {
this.port.postMessage({ type: 'died' });
this.isAlive = false;
}
return false;
}
if (currentTime <= params.begin[0]) {
@@ -1144,6 +1149,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor {
constructor(options) {
super(options);
this.isAlive = true; // used internally to prevent multiple death messages
this.port.onmessage = (e) => {
const { type, payload } = e.data || {};
if (type === 'initialize') {
@@ -1153,8 +1159,9 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor {
this.initialize();
}
initialize(options) {
this.frameLen = 0;
this.numFrames = 0;
this.table = null;
this.frameLen = null;
this.numFrames = null;
this.phase = [];
if (options?.frames) {
const key = options.key;
@@ -1311,6 +1318,10 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor {
process(_inputs, outputs, parameters) {
if (currentTime >= parameters.end[0]) {
if (this.isAlive) {
this.port.postMessage({ type: 'died' });
this.isAlive = false;
}
return false;
}
if (currentTime <= parameters.begin[0]) {
@@ -1318,7 +1329,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor {
}
const outL = outputs[0][0];
const outR = outputs[0][1] || outputs[0][0];
if (!this.tables) {
if (!this.table) {
outL.fill(0);
if (outR !== outL) outR.set(outL);
return true;