This commit is contained in:
Felix Roos 2022-02-11 01:10:44 +01:00
parent f8a178c282
commit f15686ba0f
4 changed files with 116 additions and 24 deletions

View File

@ -354,9 +354,10 @@ class Pattern {
return stack([this, func(this._early(time_pat))]); return stack([this, func(this._early(time_pat))]);
} }
every(n, func) { every(n, func) {
const pats = Array(n - 1).fill(this); const pat = this;
pats.unshift(func(this)); const pats = Array(n - 1).fill(pat);
return slowcat(...pats); pats.unshift(func(pat));
return slowcatPrime(...pats);
} }
append(other) { append(other) {
return fastcat(...[this, other]); return fastcat(...[this, other]);
@ -422,6 +423,15 @@ function slowcat(...pats) {
}; };
return new Pattern(query2)._splitQueries(); return new Pattern(query2)._splitQueries();
} }
function slowcatPrime(...pats) {
pats = pats.map(reify);
const query2 = function(span) {
const pat_n = Math.floor(span.begin) % pats.length;
const pat = pats[pat_n];
return pat.query(span);
};
return new Pattern(query2)._splitQueries();
}
function fastcat(...pats) { function fastcat(...pats) {
return slowcat(...pats)._fast(pats.length); return slowcat(...pats)._fast(pats.length);
} }
@ -493,6 +503,16 @@ const slow = curry((a, pat) => pat.slow(a));
const early = curry((a, pat) => pat.early(a)); const early = curry((a, pat) => pat.early(a));
const late = curry((a, pat) => pat.late(a)); const late = curry((a, pat) => pat.late(a));
const rev = (pat) => pat.rev(); const rev = (pat) => pat.rev();
const add = curry((a, pat) => pat.add(a));
const sub = curry((a, pat) => pat.sub(a));
const mul = curry((a, pat) => pat.mul(a));
const div = curry((a, pat) => pat.div(a));
const union = curry((a, pat) => pat.union(a));
const every = curry((i, f, pat) => pat.every(i, f));
const when = curry((binary, f, pat) => pat.when(binary, f));
const off = curry((t, f, pat) => pat.off(t, f));
const jux = curry((f, pat) => pat.jux(f));
const append = curry((a, pat) => pat.append(a));
export { export {
Fraction, Fraction,
TimeSpan, TimeSpan,
@ -515,5 +535,15 @@ export {
slow, slow,
early, early,
late, late,
rev rev,
add,
sub,
mul,
div,
union,
every,
when,
off,
jux,
append
}; };

10
docs/dist/App.js vendored
View File

@ -126,7 +126,7 @@ function App() {
}, []) }, [])
}); });
return /* @__PURE__ */ React.createElement("div", { return /* @__PURE__ */ React.createElement("div", {
className: "h-screen bg-slate-900 flex flex-col" className: "min-h-screen bg-[#2A3236] flex flex-col"
}, /* @__PURE__ */ React.createElement("header", { }, /* @__PURE__ */ React.createElement("header", {
className: "flex-none w-full h-16 px-2 flex border-b border-gray-200 bg-white justify-between" className: "flex-none w-full h-16 px-2 flex border-b border-gray-200 bg-white justify-between"
}, /* @__PURE__ */ React.createElement("div", { }, /* @__PURE__ */ React.createElement("div", {
@ -144,11 +144,11 @@ function App() {
} }
} }
}, isHot ? "🔥" : " ", " toggle hot mode")), /* @__PURE__ */ React.createElement("section", { }, isHot ? "🔥" : " ", " toggle hot mode")), /* @__PURE__ */ React.createElement("section", {
className: "grow flex flex-col p-2 text-gray-100" className: "grow flex flex-col text-gray-100"
}, /* @__PURE__ */ React.createElement("div", { }, /* @__PURE__ */ React.createElement("div", {
className: "grow relative" className: "grow relative"
}, /* @__PURE__ */ React.createElement("div", { }, /* @__PURE__ */ React.createElement("div", {
className: cx("h-full bg-[#2A3236]", error ? "focus:ring-red-500" : "focus:ring-slate-800") className: cx("h-full bg-[#2A3236]", error ? "focus:ring-red-500" : "focus:ring-slate-800")
}, /* @__PURE__ */ React.createElement(CodeMirror, { }, /* @__PURE__ */ React.createElement(CodeMirror, {
value: code, value: code,
readOnly: isHot, readOnly: isHot,
@ -163,7 +163,7 @@ function App() {
} }
} }
}), /* @__PURE__ */ React.createElement("span", { }), /* @__PURE__ */ React.createElement("span", {
className: "p-4 absolute bottom-0 left-0 text-xs whitespace-pre" className: "p-4 absolute bottom-0 right-0 text-xs whitespace-pre text-right"
}, !cycle.started ? `press ctrl+enter to play }, !cycle.started ? `press ctrl+enter to play
` : !isHot && activePattern !== pattern ? `ctrl+enter to update ` : !isHot && activePattern !== pattern ? `ctrl+enter to update
` : "no changes\n", !isHot && /* @__PURE__ */ React.createElement(React.Fragment, null, {pegjs: "mini"}[mode] || mode, " mode"), isHot && "🔥 hot mode: go to hot.js to edit pattern, then save")), error && /* @__PURE__ */ React.createElement("div", { ` : "no changes\n", !isHot && /* @__PURE__ */ React.createElement(React.Fragment, null, {pegjs: "mini"}[mode] || mode, " mode"), isHot && "🔥 hot mode: go to hot.js to edit pattern, then save")), error && /* @__PURE__ */ React.createElement("div", {
@ -178,7 +178,7 @@ function App() {
} }
} }
}, cycle.started ? "pause" : "play"), /* @__PURE__ */ React.createElement("textarea", { }, cycle.started ? "pause" : "play"), /* @__PURE__ */ React.createElement("textarea", {
className: "grow bg-[#283237] border-0 text-xs", className: "grow bg-[#283237] border-0 text-xs min-h-[200px]",
value: log, value: log,
readOnly: true, readOnly: true,
ref: logBox, ref: logBox,

62
docs/dist/tunes.js vendored
View File

@ -171,4 +171,64 @@ export const whirlyStrudel = `mini("[e4 [b2 b3] c4]")
.every(3, x => x.slow(1.5)) .every(3, x => x.slow(1.5))
.fast(slowcat(1.25,1,1.5)) .fast(slowcat(1.25,1,1.5))
.every(2, _ => mini("e4 ~ e3 d4 ~"))`; .every(2, _ => mini("e4 ~ e3 d4 ~"))`;
export default shapeShifted; export const swimming = `stack(
mini(
'~',
'~',
'~',
'A5 [F5@2 C5] [D5@2 F5] F5',
'[C5@2 F5] [F5@2 C6] A5 G5',
'A5 [F5@2 C5] [D5@2 F5] F5',
'[C5@2 F5] [Bb5 A5 G5] F5@2',
'A5 [F5@2 C5] [D5@2 F5] F5',
'[C5@2 F5] [F5@2 C6] A5 G5',
'A5 [F5@2 C5] [D5@2 F5] F5',
'[C5@2 F5] [Bb5 A5 G5] F5@2',
'A5 [F5@2 C5] A5 F5',
'Ab5 [F5@2 Ab5] G5@2',
'A5 [F5@2 C5] A5 F5',
'Ab5 [F5@2 C5] C6@2',
'A5 [F5@2 C5] [D5@2 F5] F5',
'[C5@2 F5] [Bb5 A5 G5] F5@2'
),
mini(
'[F4,Bb4,D5] [[D4,G4,Bb4]@2 [Bb3,D4,F4]] [[G3,C4,E4]@2 [[Ab3,F4] [A3,Gb4]]] [Bb3,E4,G4]',
'[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, Bb3, Db3] [F3, Bb3, Db3]]',
'[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]',
'[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]',
'[~ [A3, C4, E4] [A3, C4, E4]] [~ [Ab3, C4, Eb4] [Ab3, C4, Eb4]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [G3, C4, E4] [G3, C4, E4]]',
'[~ [F3, A3, C4] [F3, A3, C4]] [~ [F3, A3, C4] [F3, A3, C4]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]',
'[~ [F3, Bb3, D4] [F3, Bb3, D4]] [~ [F3, Bb3, C4] [F3, Bb3, C4]] [~ [F3, A3, C4] [F3, A3, C4]] [~ [F3, A3, C4] [F3, A3, C4]]',
'[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]',
'[~ [A3, C4, E4] [A3, C4, E4]] [~ [Ab3, C4, Eb4] [Ab3, C4, Eb4]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [G3, C4, E4] [G3, C4, E4]]',
'[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]',
'[~ [F3, Bb3, D4] [F3, Bb3, D4]] [~ [F3, Bb3, C4] [F3, Bb3, C4]] [~ [F3, A3, C4] [F3, A3, C4]] [~ [F3, A3, C4] [F3, A3, C4]]',
'[~ [Bb3, D3, F4] [Bb3, D3, F4]] [~ [Bb3, D3, F4] [Bb3, D3, F4]] [~ [A3, C4, F4] [A3, C4, F4]] [~ [A3, C4, F4] [A3, C4, F4]]',
'[~ [Ab3, B3, F4] [Ab3, B3, F4]] [~ [Ab3, B3, F4] [Ab3, B3, F4]] [~ [G3, Bb3, F4] [G3, Bb3, F4]] [~ [G3, Bb3, E4] [G3, Bb3, E4]]',
'[~ [Bb3, D3, F4] [Bb3, D3, F4]] [~ [Bb3, D3, F4] [Bb3, D3, F4]] [~ [A3, C4, F4] [A3, C4, F4]] [~ [A3, C4, F4] [A3, C4, F4]]',
'[~ [Ab3, B3, F4] [Ab3, B3, F4]] [~ [Ab3, B3, F4] [Ab3, B3, F4]] [~ [G3, Bb3, F4] [G3, Bb3, F4]] [~ [G3, Bb3, E4] [G3, Bb3, E4]]',
'[~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, A3, C3] [F3, A3, C3]] [~ [F3, Bb3, D3] [F3, Bb3, D3]] [~ [F3, B3, D3] [F3, B3, D3]]',
'[~ [F3, Bb3, D4] [F3, Bb3, D4]] [~ [F3, Bb3, C4] [F3, Bb3, C4]] [~ [F3, A3, C4] [F3, A3, C4]] [~ [F3, A3, C4] [F3, A3, C4]]'
),
mini(
'[G3 G3 C3 E3]',
'[F2 D2 G2 C2]',
'[F2 D2 G2 C2]',
'[F2 A2 Bb2 B2]',
'[A2 Ab2 G2 C2]',
'[F2 A2 Bb2 B2]',
'[G2 C2 F2 F2]',
'[F2 A2 Bb2 B2]',
'[A2 Ab2 G2 C2]',
'[F2 A2 Bb2 B2]',
'[G2 C2 F2 F2]',
'[Bb2 Bb2 A2 A2]',
'[Ab2 Ab2 G2 [C2 D2 E2]]',
'[Bb2 Bb2 A2 A2]',
'[Ab2 Ab2 G2 [C2 D2 E2]]',
'[F2 A2 Bb2 B2]',
'[G2 C2 F2 F2]'
)
).slow(51);
`;
export default swimming;

View File

@ -606,8 +606,8 @@ select {
.bottom-0 { .bottom-0 {
bottom: 0px; bottom: 0px;
} }
.left-0 { .right-0 {
left: 0px; right: 0px;
} }
.right-2 { .right-2 {
right: 0.5rem; right: 0.5rem;
@ -621,15 +621,18 @@ select {
.flex { .flex {
display: flex; display: flex;
} }
.h-screen {
height: 100vh;
}
.h-16 { .h-16 {
height: 4rem; height: 4rem;
} }
.h-full { .h-full {
height: 100%; height: 100%;
} }
.min-h-screen {
min-height: 100vh;
}
.min-h-\[200px\] {
min-height: 200px;
}
.w-full { .w-full {
width: 100%; width: 100%;
} }
@ -676,18 +679,14 @@ select {
--tw-border-opacity: 1; --tw-border-opacity: 1;
border-color: rgb(55 65 81 / var(--tw-border-opacity)); border-color: rgb(55 65 81 / var(--tw-border-opacity));
} }
.bg-slate-900 { .bg-\[\#2A3236\] {
--tw-bg-opacity: 1; --tw-bg-opacity: 1;
background-color: rgb(15 23 42 / var(--tw-bg-opacity)); background-color: rgb(42 50 54 / var(--tw-bg-opacity));
} }
.bg-white { .bg-white {
--tw-bg-opacity: 1; --tw-bg-opacity: 1;
background-color: rgb(255 255 255 / var(--tw-bg-opacity)); background-color: rgb(255 255 255 / var(--tw-bg-opacity));
} }
.bg-\[\#2A3236\] {
--tw-bg-opacity: 1;
background-color: rgb(42 50 54 / var(--tw-bg-opacity));
}
.bg-slate-700 { .bg-slate-700 {
--tw-bg-opacity: 1; --tw-bg-opacity: 1;
background-color: rgb(51 65 85 / var(--tw-bg-opacity)); background-color: rgb(51 65 85 / var(--tw-bg-opacity));
@ -696,16 +695,19 @@ select {
--tw-bg-opacity: 1; --tw-bg-opacity: 1;
background-color: rgb(40 50 55 / var(--tw-bg-opacity)); background-color: rgb(40 50 55 / var(--tw-bg-opacity));
} }
.p-2 {
padding: 0.5rem;
}
.p-4 { .p-4 {
padding: 1rem; padding: 1rem;
} }
.p-2 {
padding: 0.5rem;
}
.px-2 { .px-2 {
padding-left: 0.5rem; padding-left: 0.5rem;
padding-right: 0.5rem; padding-right: 0.5rem;
} }
.text-right {
text-align: right;
}
.text-2xl { .text-2xl {
font-size: 1.5rem; font-size: 1.5rem;
line-height: 2rem; line-height: 2rem;