diff --git a/packages/webaudio/sampler.mjs b/packages/webaudio/sampler.mjs index 44fbef0b..eaaaf8dd 100644 --- a/packages/webaudio/sampler.mjs +++ b/packages/webaudio/sampler.mjs @@ -149,7 +149,7 @@ export const samples = async (sampleMap, baseUrl = sampleMap._base || '') => { }), ); } - setSound(key, (options) => onTriggerSample(options, value)); + setSound(key, (options) => onTriggerSample(options, value), { type: 'sample', samples: value }); }); }; diff --git a/packages/webaudio/synth.mjs b/packages/webaudio/synth.mjs index e43ed7a0..b840a6aa 100644 --- a/packages/webaudio/synth.mjs +++ b/packages/webaudio/synth.mjs @@ -4,31 +4,35 @@ import { getOscillator, gainNode, getADSR } from './helpers.mjs'; export function registerSynthSounds() { ['sine', 'square', 'triangle', 'sawtooth'].forEach((wave) => { - setSound(wave, ({ hap, duration, t }) => { - // destructure adsr here, because the default should be different for synths and samples - const { attack = 0.001, decay = 0.05, sustain = 0.6, release = 0.01 } = hap.value; - let { n, note, freq } = hap.value; - // with synths, n and note are the same thing - n = note || n || 36; - if (typeof n === 'string') { - n = toMidi(n); // e.g. c3 => 48 - } - // get frequency - if (!freq && typeof n === 'number') { - freq = fromMidi(n); // + 48); - } - // maybe pull out the above frequency resolution?? (there is also getFrequency but it has no default) - // make oscillator - const o = getOscillator({ t, s: wave, freq, duration, release }); - // chain.push(o); - // level down oscillators as they are really loud compared to samples i've tested - //chain.push(gainNode(0.3)); - const g = gainNode(0.3); - // TODO: make adsr work with samples without pops - // envelope - const adsr = getADSR(attack, decay, sustain, release, 1, t, t + duration); - //chain.push(adsr); - return o.connect(g).connect(adsr); - }); + setSound( + wave, + ({ hap, duration, t }) => { + // destructure adsr here, because the default should be different for synths and samples + const { attack = 0.001, decay = 0.05, sustain = 0.6, release = 0.01 } = hap.value; + let { n, note, freq } = hap.value; + // with synths, n and note are the same thing + n = note || n || 36; + if (typeof n === 'string') { + n = toMidi(n); // e.g. c3 => 48 + } + // get frequency + if (!freq && typeof n === 'number') { + freq = fromMidi(n); // + 48); + } + // maybe pull out the above frequency resolution?? (there is also getFrequency but it has no default) + // make oscillator + const o = getOscillator({ t, s: wave, freq, duration, release }); + // chain.push(o); + // level down oscillators as they are really loud compared to samples i've tested + //chain.push(gainNode(0.3)); + const g = gainNode(0.3); + // TODO: make adsr work with samples without pops + // envelope + const adsr = getADSR(attack, decay, sustain, release, 1, t, t + duration); + //chain.push(adsr); + return o.connect(g).connect(adsr); + }, + { type: 'synth' }, + ); }); } diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 0b83dd24..077a2de0 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -15,8 +15,8 @@ import { map } from 'nanostores'; export const soundMap = map(); // onTrigger = ({ hap: Hap, t: number, deadline: number, duration: number, cps: number }) => AudioNode -export function setSound(key, onTrigger) { - soundMap.setKey(key, onTrigger); +export function setSound(key, onTrigger, data = {}) { + soundMap.setKey(key, { onTrigger, data }); } export const resetLoadedSounds = () => soundMap.set({}); @@ -166,7 +166,8 @@ export const webaudioOutput = async (hap, deadline, hapDuration, cps) => { if (source) { node = source(options); } else if (soundMap.get()[s]) { - node = await soundMap.get()[s](options); + const { onTrigger } = soundMap.get()[s]; + node = await onTrigger(options); } else { throw new Error(`sound ${s} not found! Is it loaded?`); } diff --git a/website/src/repl/Footer.jsx b/website/src/repl/Footer.jsx index 9ce1d859..947b6b87 100644 --- a/website/src/repl/Footer.jsx +++ b/website/src/repl/Footer.jsx @@ -196,15 +196,15 @@ function ConsoleTab({ log }) { function SoundsTab() { const sounds = useStore(soundMap); + const getSamples = (samples) => + Array.isArray(samples) ? samples.length : typeof samples === 'object' ? Object.values(samples).length : 1; return (