From 8052e10f0c1d0ebf7c3b64adeb6f2f8a339a28ca Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 21 Jan 2024 00:39:26 +0100 Subject: [PATCH 1/7] implement fit with pat state --- packages/core/pattern.mjs | 16 +++++++++------- packages/core/repl.mjs | 11 ----------- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index 408b5398..e98c4f2b 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -427,7 +427,7 @@ export class Pattern { * @noAutocomplete */ withHaps(func) { - return new Pattern((state) => func(this.query(state))); + return new Pattern((state) => func(this.query(state), state)); } /** @@ -2377,12 +2377,14 @@ export const { loopAt, loopat } = register(['loopAt', 'loopat'], function (facto * s("rhodes/4").fit() */ export const fit = register('fit', (pat) => - pat.withHap((hap) => - hap.withValue((v) => ({ - ...v, - speed: 1 / hap.whole.duration, - unit: 'c', - })), + pat.withHaps((haps, state) => + haps.map((hap) => + hap.withValue((v) => ({ + ...v, + speed: (state.controls._cps || 1) / hap.whole.duration, + unit: 'c', + })), + ), ), ); diff --git a/packages/core/repl.mjs b/packages/core/repl.mjs index 9fb6b4b9..65a9ba01 100644 --- a/packages/core/repl.mjs +++ b/packages/core/repl.mjs @@ -142,19 +142,8 @@ export function repl({ // already defined.. } - const fit = register('fit', (pat) => - pat.withHap((hap) => - hap.withValue((v) => ({ - ...v, - speed: scheduler.cps / hap.whole.duration, // overwrite speed completely? - unit: 'c', - })), - ), - ); - evalScope({ loopAt, - fit, all, hush, setCps, From 0a82471112d43e1186ae131d55e7a1490ed5166e Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 21 Jan 2024 00:45:40 +0100 Subject: [PATCH 2/7] implement loopAt with pat state --- packages/core/pattern.mjs | 7 +------ packages/core/repl.mjs | 6 ------ 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index e98c4f2b..fc9dae04 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -2359,15 +2359,10 @@ export const splice = register( false, // turns off auto-patternification ); -// this function will be redefined in repl.mjs to use the correct cps value. -// It is still here to work in cases where repl.mjs is not used - export const { loopAt, loopat } = register(['loopAt', 'loopat'], function (factor, pat) { - return _loopAt(factor, pat, 1); + return new Pattern((state) => _loopAt(factor, pat, state.controls._cps).query(state)); }); -// the fit function will be redefined in repl.mjs to use the correct cps value. -// It is still here to work in cases where repl.mjs is not used /** * Makes the sample fit its event duration. Good for rhythmical loops like drum breaks. * Similar to `loopAt`. diff --git a/packages/core/repl.mjs b/packages/core/repl.mjs index 65a9ba01..27c95c70 100644 --- a/packages/core/repl.mjs +++ b/packages/core/repl.mjs @@ -107,11 +107,6 @@ export function repl({ const setCps = (cps) => scheduler.setCps(cps); const setCpm = (cpm) => scheduler.setCps(cpm / 60); - // the following functions use the cps value, which is why they are defined here.. - const loopAt = register('loopAt', (cycles, pat) => { - return pat.loopAtCps(cycles, scheduler.cps); - }); - Pattern.prototype.p = function (id) { pPatterns[id] = this; return this; @@ -143,7 +138,6 @@ export function repl({ } evalScope({ - loopAt, all, hush, setCps, From aa1b9d11dc0ee35004dd6bdcbb87927b0e6a5dc7 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 21 Jan 2024 00:59:31 +0100 Subject: [PATCH 3/7] inject scheduler into Pattern methods right before eval --- packages/core/repl.mjs | 95 ++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 45 deletions(-) diff --git a/packages/core/repl.mjs b/packages/core/repl.mjs index 27c95c70..9f3731c8 100644 --- a/packages/core/repl.mjs +++ b/packages/core/repl.mjs @@ -61,12 +61,62 @@ export function repl({ scheduler.setPattern(pattern, autostart); }; setTime(() => scheduler.now()); // TODO: refactor? + + const stop = () => scheduler.stop(); + const start = () => scheduler.start(); + const pause = () => scheduler.pause(); + const toggle = () => scheduler.toggle(); + const setCps = (cps) => scheduler.setCps(cps); + const setCpm = (cpm) => scheduler.setCps(cpm / 60); + + const injectPatternMethods = () => { + Pattern.prototype.p = function (id) { + pPatterns[id] = this; + return this; + }; + Pattern.prototype.q = function (id) { + return silence; + }; + + const all = function (transform) { + allTransform = transform; + return silence; + }; + try { + for (let i = 1; i < 10; ++i) { + Object.defineProperty(Pattern.prototype, `d${i}`, { + get() { + return this.p(i); + }, + }); + Object.defineProperty(Pattern.prototype, `p${i}`, { + get() { + return this.p(i); + }, + }); + Pattern.prototype[`q${i}`] = silence; + } + } catch (err) { + // already defined.. + } + + evalScope({ + all, + hush, + setCps, + setcps: setCps, + setCpm, + setcpm: setCpm, + }); + }; + const evaluate = async (code, autostart = true, shouldHush = true) => { if (!code) { throw new Error('no code to evaluate'); } try { updateState({ code, pending: true }); + injectPatternMethods(); await beforeEval?.({ code }); shouldHush && hush(); let { pattern, meta } = await _evaluate(code, transpiler); @@ -100,51 +150,6 @@ export function repl({ onEvalError?.(err); } }; - const stop = () => scheduler.stop(); - const start = () => scheduler.start(); - const pause = () => scheduler.pause(); - const toggle = () => scheduler.toggle(); - const setCps = (cps) => scheduler.setCps(cps); - const setCpm = (cpm) => scheduler.setCps(cpm / 60); - - Pattern.prototype.p = function (id) { - pPatterns[id] = this; - return this; - }; - Pattern.prototype.q = function (id) { - return silence; - }; - - const all = function (transform) { - allTransform = transform; - return silence; - }; - try { - for (let i = 1; i < 10; ++i) { - Object.defineProperty(Pattern.prototype, `d${i}`, { - get() { - return this.p(i); - }, - }); - Object.defineProperty(Pattern.prototype, `p${i}`, { - get() { - return this.p(i); - }, - }); - Pattern.prototype[`q${i}`] = silence; - } - } catch (err) { - // already defined.. - } - - evalScope({ - all, - hush, - setCps, - setcps: setCps, - setCpm, - setcpm: setCpm, - }); const setCode = (code) => updateState({ code }); return { scheduler, evaluate, start, stop, pause, setCps, setPattern, setCode, toggle, state }; } From 18ae82174dfa9f370e3f4dc76eb371742f1aaf2f Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 21 Jan 2024 01:13:32 +0100 Subject: [PATCH 4/7] fix: "can't redefine non-configurable property" --- packages/core/repl.mjs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/core/repl.mjs b/packages/core/repl.mjs index 9f3731c8..d040787d 100644 --- a/packages/core/repl.mjs +++ b/packages/core/repl.mjs @@ -88,16 +88,18 @@ export function repl({ get() { return this.p(i); }, + configurable: true, }); Object.defineProperty(Pattern.prototype, `p${i}`, { get() { return this.p(i); }, + configurable: true, }); Pattern.prototype[`q${i}`] = silence; } } catch (err) { - // already defined.. + console.warn('injectPatternMethods: error:', err); } evalScope({ From 6224cd40d44b8d434c10cae1e49389d7824057ba Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 21 Jan 2024 01:21:13 +0100 Subject: [PATCH 5/7] mini repl max height option --- website/src/docs/MiniRepl.jsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/website/src/docs/MiniRepl.jsx b/website/src/docs/MiniRepl.jsx index 10eff483..3afb609e 100644 --- a/website/src/docs/MiniRepl.jsx +++ b/website/src/docs/MiniRepl.jsx @@ -27,6 +27,7 @@ export function MiniRepl({ punchcardLabels = true, claviature, claviatureLabels, + maxHeight, }) { const code = tunes ? tunes[0] : tune; const id = useMemo(() => s4(), []); @@ -154,7 +155,7 @@ export function MiniRepl({ )} )} -
+
{ if (!editorRef.current) { From 0cfec3a7bd06e3d89ac6434f44f1c62211aa7c59 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 21 Jan 2024 01:21:21 +0100 Subject: [PATCH 6/7] show repls in community bakery --- website/src/components/Oven/Oven.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/src/components/Oven/Oven.jsx b/website/src/components/Oven/Oven.jsx index 7cb2e7a7..30822d6c 100644 --- a/website/src/components/Oven/Oven.jsx +++ b/website/src/components/Oven/Oven.jsx @@ -6,6 +6,7 @@ import { PatternLabel } from '@src/repl/panel/PatternsTab'; function PatternList({ patterns }) { return (
+ {/* pat.code.trim())} /> */} {patterns.map((pat) => (
@@ -15,8 +16,7 @@ function PatternList({ patterns }) {
- {/* */} - {/*
{JSON.stringify(pat)}
*/} +
))}
From 0695b4bee99edfd2574d6cee6675bb1ec494bc4a Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 21 Jan 2024 01:29:31 +0100 Subject: [PATCH 7/7] clean + comment --- packages/core/repl.mjs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/core/repl.mjs b/packages/core/repl.mjs index d040787d..490ac98c 100644 --- a/packages/core/repl.mjs +++ b/packages/core/repl.mjs @@ -68,7 +68,12 @@ export function repl({ const toggle = () => scheduler.toggle(); const setCps = (cps) => scheduler.setCps(cps); const setCpm = (cpm) => scheduler.setCps(cpm / 60); + const all = function (transform) { + allTransform = transform; + return silence; + }; + // set pattern methods that use this repl via closure const injectPatternMethods = () => { Pattern.prototype.p = function (id) { pPatterns[id] = this; @@ -77,11 +82,6 @@ export function repl({ Pattern.prototype.q = function (id) { return silence; }; - - const all = function (transform) { - allTransform = transform; - return silence; - }; try { for (let i = 1; i < 10; ++i) { Object.defineProperty(Pattern.prototype, `d${i}`, { @@ -101,7 +101,6 @@ export function repl({ } catch (err) { console.warn('injectPatternMethods: error:', err); } - evalScope({ all, hush,