From 08ab06c9cc45e2f2ff41ce97517b989621271a64 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 25 Feb 2022 20:43:38 +0100 Subject: [PATCH] use context for tone --- repl/src/tone.ts | 47 +++++++++++++++++++++------------------------ repl/src/useRepl.ts | 6 +++--- 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/repl/src/tone.ts b/repl/src/tone.ts index 7636f173..da59deb4 100644 --- a/repl/src/tone.ts +++ b/repl/src/tone.ts @@ -26,18 +26,17 @@ const Pattern = _Pattern as any; // with this function, you can play the pattern with any tone synth Pattern.prototype.tone = function (instrument) { // instrument.toDestination(); - return this.fmap((value: any) => { - value = typeof value !== 'object' && !Array.isArray(value) ? { value } : value; + return this._withEvent((event) => { const onTrigger = (time, event) => { if (instrument.constructor.name === 'PluckSynth') { - instrument.triggerAttack(value.value, time); + instrument.triggerAttack(event.value, time); } else if (instrument.constructor.name === 'NoiseSynth') { instrument.triggerAttackRelease(event.duration, time); // noise has no value } else { - instrument.triggerAttackRelease(value.value, event.duration, time); + instrument.triggerAttackRelease(event.value, event.duration, time); } }; - return { ...value, instrument, onTrigger }; + return event.setContext({ ...event.context, instrument, onTrigger }); }); }; @@ -105,13 +104,12 @@ Pattern.prototype._poly = function (type: any = 'triangle') { // this.instrument = new PolySynth(Synth, instrumentConfig).toDestination(); this.instrument = poly(type); } - return this.fmap((value: any) => { - value = typeof value !== 'object' && !Array.isArray(value) ? { value } : value; + return this._withEvent((event: any) => { const onTrigger = (time, event) => { this.instrument.set(instrumentConfig); - this.instrument.triggerAttackRelease(value.value, event.duration, time); + this.instrument.triggerAttackRelease(event.value, event.duration, time); }; - return { ...value, instrumentConfig, onTrigger }; + return event.setContext({ ...event.context, instrumentConfig, onTrigger }); }); }; @@ -138,8 +136,7 @@ const getTrigger = (getChain: any, value: any) => (time: number, event: any) => }; Pattern.prototype._synth = function (type: any = 'triangle') { - return this.fmap((value: any) => { - value = typeof value !== 'object' && !Array.isArray(value) ? { value } : value; + return this._withEvent((event: any) => { const instrumentConfig: any = { oscillator: { type }, envelope: { attack: 0.01, decay: 0.01, sustain: 0.6, release: 0.01 }, @@ -149,39 +146,39 @@ Pattern.prototype._synth = function (type: any = 'triangle') { instrument.set(instrumentConfig); return instrument; }; - const onTrigger = getTrigger(() => getInstrument().toDestination(), value.value); - return { ...value, getInstrument, instrumentConfig, onTrigger }; + const onTrigger = getTrigger(() => getInstrument().toDestination(), event.value); + return event.setContext({ ...event.context, getInstrument, instrumentConfig, onTrigger }); }); }; Pattern.prototype.adsr = function (attack = 0.01, decay = 0.01, sustain = 0.6, release = 0.01) { - return this.fmap((value: any) => { - if (!value?.getInstrument) { + return this._withEvent((event: any) => { + if (!event.context.getInstrument) { throw new Error('cannot chain adsr: need instrument first (like synth)'); } - const instrumentConfig = { ...value.instrumentConfig, envelope: { attack, decay, sustain, release } }; + const instrumentConfig = { ...event.context.instrumentConfig, envelope: { attack, decay, sustain, release } }; const getInstrument = () => { - const instrument = value.getInstrument(); + const instrument = event.context.getInstrument(); instrument.set(instrumentConfig); return instrument; }; - const onTrigger = getTrigger(() => getInstrument().toDestination(), value.value); - return { ...value, getInstrument, instrumentConfig, onTrigger }; + const onTrigger = getTrigger(() => getInstrument().toDestination(), event.value); + return event.setContext({ ...event.context, getInstrument, instrumentConfig, onTrigger }); }); }; Pattern.prototype.chain = function (...effectGetters: any) { - return this.fmap((value: any) => { - if (!value?.getInstrument) { + return this._withEvent((event: any) => { + if (!event.context?.getInstrument) { throw new Error('cannot chain: need instrument first (like synth)'); } - const chain = (value.chain || []).concat(effectGetters); + const chain = (event.context.chain || []).concat(effectGetters); const getChain = () => { const effects = chain.map((getEffect: any) => getEffect()); - return value.getInstrument().chain(...effects, Destination); + return event.context.getInstrument().chain(...effects, Destination); }; - const onTrigger = getTrigger(getChain, value.value); - return { ...value, getChain, onTrigger, chain }; + const onTrigger = getTrigger(getChain, event.value); + return event.setContext({ ...event.context, getChain, onTrigger, chain }); }); }; diff --git a/repl/src/useRepl.ts b/repl/src/useRepl.ts index fd742fac..4bf6b1b5 100644 --- a/repl/src/useRepl.ts +++ b/repl/src/useRepl.ts @@ -56,8 +56,9 @@ function useRepl({ tune, defaultSynth, autolink = true, onEvent }: any) { (time, event) => { try { onEvent?.(event); - if (!event.value?.onTrigger) { - const note = event.value?.value || event.value; + const { onTrigger } = event.context; + if (!onTrigger) { + const note = event.value; if (!isNote(note)) { throw new Error('not a note: ' + note); } @@ -69,7 +70,6 @@ function useRepl({ tune, defaultSynth, autolink = true, onEvent }: any) { /* console.warn('no instrument chosen', event); throw new Error(`no instrument chosen for ${JSON.stringify(event)}`); */ } else { - const { onTrigger } = event.value; onTrigger(time, event); } } catch (err: any) {