diff --git a/packages/superdough/synth.mjs b/packages/superdough/synth.mjs index 3707a342..3e511641 100644 --- a/packages/superdough/synth.mjs +++ b/packages/superdough/synth.mjs @@ -25,9 +25,9 @@ const waveforms = ['sine', 'square', 'triangle', 'sawtooth']; const noises = ['pink', 'white', 'brown', 'crackle']; export function registerSynthSounds() { - registerSound('bet', (t, value, onended) => { + registerSound('bet', (begin, value, onended) => { const ac = getAudioContext(); - let { note, freq, duration, cps } = value; + let { note, freq, duration } = value; note = note || 36; if (typeof note === 'string') { note = noteToMidi(note); // e.g. c3 => 48 @@ -40,7 +40,21 @@ export function registerSynthSounds() { // set frequency freq = Number(freq); - const node = getWorklet(ac, 'better-oscillator', { frequency: freq, start: t, end: t + duration * cps }); + const [attack, decay, sustain, release] = getADSRValues( + [value.attack, value.decay, value.sustain, value.release], + 'linear', + [0.001, 0.05, 0.6, 0.01], + ); + + const holdend = begin + duration; + const end = holdend + release + 0.01; + + let node = getWorklet(ac, 'better-oscillator', { frequency: freq, begin, end }); + + const envGain = gainNode(1); + node = node.connect(envGain); + + getParamADSR(node.gain, attack, decay, sustain, release, 0, 1, begin, holdend, 'exponential'); return { node, diff --git a/packages/superdough/worklets.mjs b/packages/superdough/worklets.mjs index f9a04bab..f8c21c5e 100644 --- a/packages/superdough/worklets.mjs +++ b/packages/superdough/worklets.mjs @@ -143,12 +143,27 @@ class BetterOscillatorProcessor extends AudioWorkletProcessor { } static get parameterDescriptors() { return [ + { + name: 'begin', + defaultValue: 0, + max: Number.POSITIVE_INFINITY, + min: 0, + }, + + { + name: 'end', + defaultValue: 0, + max: Number.POSITIVE_INFINITY, + min: 0, + }, + { name: 'phase', defaultValue: 0, max: 1, min: 0, }, + { name: 'duty', defaultValue: 0.5, @@ -174,6 +189,13 @@ class BetterOscillatorProcessor extends AudioWorkletProcessor { ]; } process(input, outputs, params) { + if (currentTime <= params.begin[0]) { + return true; + } + if (currentTime >= params.end[0]) { + return false; + } + for (let z = 0; z < outputs.length; z++) { const out = outputs[z][0]; const outlen = out.length;