diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 1df00f1a..79dc33ab 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -766,6 +766,15 @@ export const { bprelease, bpr } = registerControl('bprelease', 'bpr'); * .ftype("") */ export const { ftype } = registerControl('ftype'); + +/** + * controls the center of the filter envelope. 0 is unipolar positive, .5 is bipolar, 1 is unipolar negative + * @name fanchor + * @param {number | Pattern} center 0 to 1 + * @example + * note("{f g g c d a a#}%8").s("sawtooth").lpf("{1000}%2") + * .lpenv(8).fanchor("<0 .5 1>") + */ export const { fanchor } = registerControl('fanchor'); /** * Applies the cutoff frequency of the **h**igh-**p**ass **f**ilter. diff --git a/packages/superdough/superdough.mjs b/packages/superdough/superdough.mjs index 018caa9a..5488b404 100644 --- a/packages/superdough/superdough.mjs +++ b/packages/superdough/superdough.mjs @@ -24,6 +24,52 @@ export function getSound(s) { return soundMap.get()[s]; } +const defaultDefaultValues = { + s: 'triangle', + gain: 0.8, + postgain: 1, + density: '.03', + ftype: '12db', + fanchor: 0, + resonance: 1, + hresonance: 1, + bandq: 1, + channels: [1, 2], + phaserdepth: 0.75, + shapevol: 1, + distortvol: 1, + delay: 0, + delayfeedback: 0.5, + delaytime: 0.25, + orbit: 1, + i: 1, + velocity: 1, + fft: 8, +}; + +let defaultControls = new Map(Object.entries(defaultDefaultValues)); + +export function setDefaultValue(key, value) { + defaultControls.set(key, value); +} +export function getDefaultValue(key) { + return defaultControls.get(key); +} +export function setDefaultValues(defaultsobj) { + Object.keys(defaultsobj).forEach((key) => { + setDefaultValue(key, defaultsobj[key]); + }); +} +export function resetDefaultValues() { + defaultControls = new Map(Object.entries(defaultDefaultValues)); +} +export function setVersionDefaults(version) { + resetDefaultValues(); + if (version === '1.0') { + setDefaultValue('fanchor', 0.5); + } +} + export const resetLoadedSounds = () => soundMap.set({}); let audioContext; @@ -276,15 +322,14 @@ export const superdough = async (value, t, hapDuration) => { } // destructure let { - s = 'triangle', + s = getDefaultValue('s'), bank, source, - gain = 0.8, - postgain = 1, - density = 0.03, + gain = getDefaultValue('gain'), + postgain = getDefaultValue('postgain'), + density = getDefaultValue('density'), // filters - - fanchor = 0.5, + fanchor = getDefaultValue('fanchor'), drive = 0.69, // low pass cutoff, @@ -293,7 +338,7 @@ export const superdough = async (value, t, hapDuration) => { lpdecay, lpsustain, lprelease, - resonance = 1, + resonance = getDefaultValue('resonance'), // high pass hpenv, hcutoff, @@ -301,7 +346,7 @@ export const superdough = async (value, t, hapDuration) => { hpdecay, hpsustain, hprelease, - hresonance = 1, + hresonance = getDefaultValue('hresonance'), // band pass bpenv, bandf, @@ -309,36 +354,36 @@ export const superdough = async (value, t, hapDuration) => { bpdecay, bpsustain, bprelease, - bandq = 1, - channels = [1, 2], + bandq = getDefaultValue('bandq'), + channels = getDefaultValue('channels'), //phaser phaser, - phaserdepth = 0.75, + phaserdepth = getDefaultValue('phaserdepth'), phasersweep, phasercenter, // coarse, crush, shape, - shapevol = 1, + shapevol = getDefaultValue('shapevol'), distort, - distortvol = 1, + distortvol = getDefaultValue('distortvol'), pan, vowel, - delay = 0, - delayfeedback = 0.5, - delaytime = 0.25, - orbit = 1, + delay = getDefaultValue('delay'), + delayfeedback = getDefaultValue('delayfeedback'), + delaytime = getDefaultValue('delaytime'), + orbit = getDefaultValue('orbit'), room, roomfade, roomlp, roomdim, roomsize, ir, - i = 0, - velocity = 1, + i = getDefaultValue('i'), + velocity = getDefaultValue('velocity'), analyze, // analyser wet - fft = 8, // fftSize 0 - 10 + fft = getDefaultValue('fft'), // fftSize 0 - 10 compressor: compressorThreshold, compressorRatio, compressorKnee, diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index ddbb6f91..efc5dda0 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -2562,6 +2562,43 @@ exports[`runs examples > example "every" example index 0 1`] = ` ] `; +exports[`runs examples > example "fanchor" example index 0 1`] = ` +[ + "[ 0/1 → 1/8 | note:f s:sawtooth cutoff:1000 lpenv:8 fanchor:0 ]", + "[ 1/8 → 1/4 | note:g s:sawtooth cutoff:1000 lpenv:8 fanchor:0 ]", + "[ 1/4 → 3/8 | note:g s:sawtooth cutoff:1000 lpenv:8 fanchor:0 ]", + "[ 3/8 → 1/2 | note:c s:sawtooth cutoff:1000 lpenv:8 fanchor:0 ]", + "[ 1/2 → 5/8 | note:d s:sawtooth cutoff:1000 lpenv:8 fanchor:0 ]", + "[ 5/8 → 3/4 | note:a s:sawtooth cutoff:1000 lpenv:8 fanchor:0 ]", + "[ 3/4 → 7/8 | note:a# s:sawtooth cutoff:1000 lpenv:8 fanchor:0 ]", + "[ 7/8 → 1/1 | note:f s:sawtooth cutoff:1000 lpenv:8 fanchor:0 ]", + "[ 1/1 → 9/8 | note:g s:sawtooth cutoff:1000 lpenv:8 fanchor:0.5 ]", + "[ 9/8 → 5/4 | note:g s:sawtooth cutoff:1000 lpenv:8 fanchor:0.5 ]", + "[ 5/4 → 11/8 | note:c s:sawtooth cutoff:1000 lpenv:8 fanchor:0.5 ]", + "[ 11/8 → 3/2 | note:d s:sawtooth cutoff:1000 lpenv:8 fanchor:0.5 ]", + "[ 3/2 → 13/8 | note:a s:sawtooth cutoff:1000 lpenv:8 fanchor:0.5 ]", + "[ 13/8 → 7/4 | note:a# s:sawtooth cutoff:1000 lpenv:8 fanchor:0.5 ]", + "[ 7/4 → 15/8 | note:f s:sawtooth cutoff:1000 lpenv:8 fanchor:0.5 ]", + "[ 15/8 → 2/1 | note:g s:sawtooth cutoff:1000 lpenv:8 fanchor:0.5 ]", + "[ 2/1 → 17/8 | note:g s:sawtooth cutoff:1000 lpenv:8 fanchor:1 ]", + "[ 17/8 → 9/4 | note:c s:sawtooth cutoff:1000 lpenv:8 fanchor:1 ]", + "[ 9/4 → 19/8 | note:d s:sawtooth cutoff:1000 lpenv:8 fanchor:1 ]", + "[ 19/8 → 5/2 | note:a s:sawtooth cutoff:1000 lpenv:8 fanchor:1 ]", + "[ 5/2 → 21/8 | note:a# s:sawtooth cutoff:1000 lpenv:8 fanchor:1 ]", + "[ 21/8 → 11/4 | note:f s:sawtooth cutoff:1000 lpenv:8 fanchor:1 ]", + "[ 11/4 → 23/8 | note:g s:sawtooth cutoff:1000 lpenv:8 fanchor:1 ]", + "[ 23/8 → 3/1 | note:g s:sawtooth cutoff:1000 lpenv:8 fanchor:1 ]", + "[ 3/1 → 25/8 | note:c s:sawtooth cutoff:1000 lpenv:8 fanchor:0 ]", + "[ 25/8 → 13/4 | note:d s:sawtooth cutoff:1000 lpenv:8 fanchor:0 ]", + "[ 13/4 → 27/8 | note:a s:sawtooth cutoff:1000 lpenv:8 fanchor:0 ]", + "[ 27/8 → 7/2 | note:a# s:sawtooth cutoff:1000 lpenv:8 fanchor:0 ]", + "[ 7/2 → 29/8 | note:f s:sawtooth cutoff:1000 lpenv:8 fanchor:0 ]", + "[ 29/8 → 15/4 | note:g s:sawtooth cutoff:1000 lpenv:8 fanchor:0 ]", + "[ 15/4 → 31/8 | note:g s:sawtooth cutoff:1000 lpenv:8 fanchor:0 ]", + "[ 31/8 → 4/1 | note:c s:sawtooth cutoff:1000 lpenv:8 fanchor:0 ]", +] +`; + exports[`runs examples > example "fast" example index 0 1`] = ` [ "[ 0/1 → 1/8 | s:bd ]", diff --git a/website/src/repl/Repl.jsx b/website/src/repl/Repl.jsx index aabefcdc..b892005e 100644 --- a/website/src/repl/Repl.jsx +++ b/website/src/repl/Repl.jsx @@ -94,6 +94,13 @@ export function Repl({ embedded = false }) { window.location.hash = '#' + code2hash(code); setDocumentTitle(code); const viewingPatternData = getViewingPatternData(); + try { + const metadata = getMetadata(code); + setVersionDefaults(metadata.version); + } catch (err) { + console.error('Error parsing metadata..'); + console.error(err); + } const data = { ...viewingPatternData, code }; let id = data.id; const isExamplePattern = viewingPatternData.collection !== userPattern.collection;