diff --git a/packages/core/evaluate.mjs b/packages/core/evaluate.mjs index 340febe5..ea63d8df 100644 --- a/packages/core/evaluate.mjs +++ b/packages/core/evaluate.mjs @@ -22,6 +22,7 @@ export const evalScope = async (...args) => { globalThis[name] = value; }); }); + return modules; }; function safeEval(str, options = {}) { diff --git a/packages/tonal/index.mjs b/packages/tonal/index.mjs index fc1b7f97..a3c0cba3 100644 --- a/packages/tonal/index.mjs +++ b/packages/tonal/index.mjs @@ -5,3 +5,5 @@ export * from './tonal.mjs'; export * from './voicings.mjs'; import './ireal.mjs'; + +export const packageName = '@strudel/tonal'; diff --git a/packages/tonal/voicings.mjs b/packages/tonal/voicings.mjs index 39cea0ba..66fcd03c 100644 --- a/packages/tonal/voicings.mjs +++ b/packages/tonal/voicings.mjs @@ -77,8 +77,13 @@ export const voicingRegistry = { lefthand: { dictionary: lefthand, range: ['F3', 'A4'], mode: 'below', anchor: 'a4' }, triads: { dictionary: triads, mode: 'below', anchor: 'a4' }, guidetones: { dictionary: guidetones, mode: 'above', anchor: 'a4' }, - default: { dictionary: defaultDictionary, mode: 'below', anchor: 'a4' }, + legacy: { dictionary: defaultDictionary, mode: 'below', anchor: 'a4' }, }; + +let defaultDict = 'ireal'; +export const setDefaultVoicings = (dict) => (defaultDict = dict); +// e.g. typeof setDefaultVoicings !== 'undefined' && setDefaultVoicings('legacy'); + export const setVoicingRange = (name, range) => addVoicings(name, voicingRegistry[name].dictionary, range); /** @@ -193,7 +198,7 @@ export const voicing = register('voicing', function (pat) { .fmap((value) => { // destructure voicing controls out value = typeof value === 'string' ? { chord: value } : value; - let { dictionary = 'default', chord, anchor, offset, mode, n, octaves, ...rest } = value; + let { dictionary = defaultDict, chord, anchor, offset, mode, n, octaves, ...rest } = value; dictionary = typeof dictionary === 'string' ? voicingRegistry[dictionary] : { dictionary, mode: 'below', anchor: 'c5' }; try { @@ -234,3 +239,8 @@ Object.keys(simple).forEach((symbol) => { registerVoicings('ireal', simple); registerVoicings('ireal-ext', complex); + +export function resetVoicings() { + lastVoicing = undefined; + setDefaultVoicings('ireal'); +} diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index 075f4207..e9f46dab 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -7311,22 +7311,22 @@ exports[`runs examples > example "vibmod" example index 1 1`] = ` exports[`runs examples > example "voicing" example index 0 1`] = ` [ - "[ 0/1 → 1/4 | note:64 ]", - "[ 1/4 → 1/2 | note:67 ]", - "[ 1/2 → 3/4 | note:72 ]", - "[ 3/4 → 1/1 | note:76 ]", - "[ 1/1 → 5/4 | note:64 ]", - "[ 5/4 → 3/2 | note:69 ]", - "[ 3/2 → 7/4 | note:72 ]", - "[ 7/4 → 2/1 | note:76 ]", - "[ 2/1 → 9/4 | note:65 ]", - "[ 9/4 → 5/2 | note:69 ]", - "[ 5/2 → 11/4 | note:72 ]", - "[ 11/4 → 3/1 | note:77 ]", - "[ 3/1 → 13/4 | note:62 ]", - "[ 13/4 → 7/2 | note:67 ]", - "[ 7/2 → 15/4 | note:71 ]", - "[ 15/4 → 4/1 | note:74 ]", + "[ 0/1 → 1/4 | note:52 ]", + "[ 1/4 → 1/2 | note:60 ]", + "[ 1/2 → 3/4 | note:64 ]", + "[ 3/4 → 1/1 | note:67 ]", + "[ 1/1 → 5/4 | note:57 ]", + "[ 5/4 → 3/2 | note:60 ]", + "[ 3/2 → 7/4 | note:64 ]", + "[ 7/4 → 2/1 | note:69 ]", + "[ 2/1 → 9/4 | note:53 ]", + "[ 9/4 → 5/2 | note:60 ]", + "[ 5/2 → 11/4 | note:65 ]", + "[ 11/4 → 3/1 | note:69 ]", + "[ 3/1 → 13/4 | note:55 ]", + "[ 13/4 → 7/2 | note:62 ]", + "[ 7/2 → 15/4 | note:67 ]", + "[ 15/4 → 4/1 | note:71 ]", ] `; diff --git a/website/src/repl/Repl.jsx b/website/src/repl/Repl.jsx index fb73b5cc..31058ac0 100644 --- a/website/src/repl/Repl.jsx +++ b/website/src/repl/Repl.jsx @@ -50,6 +50,14 @@ if (typeof window !== 'undefined') { isIframe = window.location !== window.parent.location; } +async function getModule(name) { + if (!modulesLoading) { + return; + } + const modules = await modulesLoading; + return modules.find((m) => m.packageName === name); +} + export function Repl({ embedded = false }) { const isEmbedded = embedded || isIframe; const { panelPosition, isZen } = useSettings(); @@ -170,6 +178,7 @@ export function Repl({ embedded = false }) { }; const resetEditor = async () => { + (await getModule('@strudel/tonal'))?.resetVoicings(); resetGlobalEffects(); clearCanvas(); clearHydra(); @@ -196,11 +205,7 @@ export function Repl({ embedded = false }) { logger(`[repl] ✨ loading random tune "${patternData.id}"`); setActivePattern(patternData.id); setViewingPatternData(patternData); - clearCanvas(); - clearHydra(); - resetLoadedSounds(); - resetGlobalEffects(); - await prebake(); // declare default samples + await resetEditor(); editorRef.current.setCode(code); editorRef.current.repl.evaluate(code); };