mirror of
https://codeberg.org/uzu/strudel
synced 2026-09-05 14:58:03 -04:00
moar slides
This commit is contained in:
@@ -6,8 +6,10 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Slides</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<body style="background-color: black">
|
||||
<div id="root">
|
||||
<span style="color: white">loading... </span>
|
||||
</div>
|
||||
<script type="module" src="/src/main.jsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 42 KiB |
@@ -0,0 +1,41 @@
|
||||
import { useState } from 'react';
|
||||
import { SlideRepl } from './SlideRepl.jsx';
|
||||
|
||||
const snippets = [
|
||||
[`sound("bd [hh sd]")`, `sound(seq("bd", ["hh", "sd"]))`, 'Nested Sequences'], //
|
||||
[`sound("<bd sd>")`, `sound(cat("bd", "sd"))`, 'Cyclewise Sequences'], //
|
||||
[`sound("bd,hh")`, `sound(stack("bd", "hh"))`, 'Stack'], //
|
||||
[`sound("bd@3 sd@1")`, `sound(timeCat([3, "bd"], [1, "sd"]))`, 'Weighted Sequence'], //
|
||||
[`sound("{lt ht mt, bd sd}")`, `sound(polymeter(["lt","ht","mt"], ["bd", "sd"]))`, 'Polymeter'], //
|
||||
[`sound("{bd hh sd ht}%2")`, `sound(polymeterSteps(2, ["bd", "hh", "sd", "ht"]))`, 'Steps per Cycle'],
|
||||
];
|
||||
|
||||
function MiniComparison() {
|
||||
const [step, setStep] = useState(1);
|
||||
return (
|
||||
<>
|
||||
<h1>Mini Notation vs Regular JS</h1>
|
||||
<div className="not-prose">
|
||||
{snippets.slice(0, step).map(([a, b, label], i) => {
|
||||
const isActive = i === step - 1;
|
||||
return (
|
||||
<div key={i} className={`border-l-4 pl-8 border-gray-500 py-4 ${isActive ? 'p-4 border-yellow-500' : ''}`}>
|
||||
<h3 className="pb-4">{label}</h3>
|
||||
<div className="flex space-x-2">
|
||||
<img src="./img/tidalcycles.svg" className={`h-10 mt-2`} />
|
||||
<SlideRepl tune={a} hideHeader />
|
||||
</div>
|
||||
<div className="flex space-x-2">
|
||||
<img src="./img/js.jpg" className={`h-10 mt-2`} />
|
||||
<SlideRepl tune={b} hideHeader />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
{step < snippets.length && <button onClick={() => setStep((r) => r + 1)}>next</button>}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default MiniComparison;
|
||||
@@ -3,6 +3,7 @@ import { initAudioOnFirstClick } from '@strudel.cycles/webaudio';
|
||||
import { MiniRepl as _MiniRepl } from '@strudel.cycles/react';
|
||||
import { prebake } from './prebake';
|
||||
import { atomone } from '@uiw/codemirror-themes-all';
|
||||
import blackscreen from '@strudel.cycles/react/src/themes/blackscreen';
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
await evalScope(
|
||||
@@ -20,7 +21,15 @@ if (typeof window !== 'undefined') {
|
||||
prebake();
|
||||
}
|
||||
|
||||
export function SlideRepl({ tune, drawTime, punchcard, canvasHeight = 100, hideHeader = false, fontSize = 32 }) {
|
||||
export function SlideRepl({
|
||||
tune,
|
||||
drawTime,
|
||||
punchcard,
|
||||
canvasHeight = 100,
|
||||
hideHeader = false,
|
||||
fontSize = 32,
|
||||
disabled = false,
|
||||
}) {
|
||||
// const { theme } = useSettings();
|
||||
return (
|
||||
<div className="mb-4">
|
||||
@@ -32,7 +41,7 @@ export function SlideRepl({ tune, drawTime, punchcard, canvasHeight = 100, hideH
|
||||
punchcard={punchcard}
|
||||
canvasHeight={canvasHeight}
|
||||
fontSize={fontSize}
|
||||
theme={atomone}
|
||||
theme={disabled ? blackscreen : atomone}
|
||||
// theme={themes[theme]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -16,17 +16,18 @@ const loadedMDXFiles = await Promise.all(
|
||||
}),
|
||||
);
|
||||
|
||||
const order = ['01', '02-0', '02-1', '02-2', '03'];
|
||||
const order = ['01', '02-0', '02-1', '02-2', '03-0', '03-1', '04'];
|
||||
|
||||
const slideEntries = order.map((name) => loadedMDXFiles.find(([file]) => file === name));
|
||||
|
||||
// current slide index is persisted, so it's safe to refresh the browser
|
||||
export const slideIndex = persistentAtom('slideIndex', '0');
|
||||
|
||||
export const prev = () => slideIndex.set((parseInt(slideIndex.get()) - 1 + slideEntries.length) % slideEntries.length);
|
||||
export const next = () => slideIndex.set((parseInt(slideIndex.get()) + 1) % slideEntries.length);
|
||||
|
||||
function Slides() {
|
||||
const activeIndex = parseInt(useStore(slideIndex));
|
||||
const prev = () => slideIndex.set((activeIndex - 1 + slideEntries.length) % slideEntries.length);
|
||||
const next = () => slideIndex.set((activeIndex + 1) % slideEntries.length);
|
||||
|
||||
useEvent('click', (e) => {
|
||||
if (!e.ctrlKey) {
|
||||
|
||||
@@ -48,25 +48,31 @@ function SyntaxComparison() {
|
||||
<div>Tidal</div>
|
||||
<div>Strudel</div>
|
||||
</div> */}
|
||||
{snippets.slice(0, step).map(([hs, js, label], i) => (
|
||||
<div key={i} className={`border-t border-gray-500 py-4`}>
|
||||
<h3 className="pb-4">{label}</h3>
|
||||
<div>
|
||||
<div className="flex space-x-2">
|
||||
<img src="./img/haskell.png" className="h-10 mt-2" />
|
||||
<Highlight language="haskell" code={hs} />
|
||||
</div>
|
||||
{snippets.slice(0, step).map(([hs, js, label], i) => {
|
||||
const isActive = i === step - 1;
|
||||
return (
|
||||
<div
|
||||
key={i}
|
||||
className={`border-l-4 pl-8 border-gray-500 py-4 ${isActive ? 'p-4 border-yellow-500' : ''}`}
|
||||
>
|
||||
<h3 className="pb-4">{label}</h3>
|
||||
<div>
|
||||
{js.map((c, j) => (
|
||||
<div className="flex space-x-2" key={j}>
|
||||
<img src="./img/js.jpg" className="h-10 mt-2" />
|
||||
<SlideRepl tune={c} hideHeader />
|
||||
</div>
|
||||
))}
|
||||
<div className="flex space-x-4">
|
||||
<img src="./img/haskell.png" className="h-10 mt-2" />
|
||||
<Highlight language="haskell" code={hs} />
|
||||
</div>
|
||||
<div>
|
||||
{js.map((c, j) => (
|
||||
<div className="flex space-x-4" key={j}>
|
||||
<img src="./img/js.jpg" className={`h-10 mt-2`} />
|
||||
<SlideRepl tune={c} hideHeader />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
{step < snippets.length && <button onClick={() => setStep((r) => r + 1)}>next</button>}
|
||||
</>
|
||||
|
||||
@@ -12,8 +12,6 @@ import { SlideRepl } from '../SlideRepl.jsx';
|
||||
hideHeader
|
||||
fontSize={24}
|
||||
tune={`// froos - freakuency - 2023/03/29
|
||||
setcps(.5)
|
||||
//
|
||||
await samples('https://shabda.ndre.gr/speech/frequency,freaky.json?strudel=1')
|
||||
//
|
||||
stack(
|
||||
@@ -31,5 +29,5 @@ stack(
|
||||
.mask("<0 1>")
|
||||
).restart("<1@3 1*[4 [8 16]]>")
|
||||
.stack(s("<~ [[~@2.4 freaky] frequency]>/2").delay(.8)
|
||||
.echoWith(4,-.0125,(p,n)=>p.speed(1-n*.1).gain(n*.2)))`}
|
||||
.echoWith(4,-.0125,(p,n)=>p.speed(1-n*.1).gain(n*.2))).slow(2)`}
|
||||
/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import SyntaxComparison from '../SyntaxComparison.jsx';
|
||||
|
||||
# Syntax Comparison
|
||||
# Syntax Comparison: Haskell / JavaScript
|
||||
|
||||
<SyntaxComparison />
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# Systems Comparison
|
||||
|
||||
|
||||
tidal: keyboard -> editor -> tidal plugin -> superdirt -> supercollider -> speakers
|
||||
|
||||
strudel: keyboard -> repl -> speakers
|
||||
@@ -0,0 +1,18 @@
|
||||
import { SlideRepl } from '../SlideRepl.jsx';
|
||||
import Highlight from '../Highlight.jsx';
|
||||
|
||||
# Patterns
|
||||
|
||||
<SlideRepl tune={`sound("bd [hh sd]")`} hideHeader punchcard />
|
||||
|
||||
query = get events within time arc:
|
||||
|
||||
<Highlight code={`sound("bd [hh sd]").queryArc(0, 1)`} language="javascript" />
|
||||
|
||||
```plaintext
|
||||
[
|
||||
"0/1 -> 1/2 | sound:bd",
|
||||
"1/2 -> 3/4 | sound:hh",
|
||||
"3/4 -> 1/1 | sound:sd",
|
||||
]
|
||||
```
|
||||
@@ -0,0 +1,5 @@
|
||||
import { SlideRepl } from '../SlideRepl.jsx';
|
||||
import Highlight from '../Highlight.jsx';
|
||||
import MiniComparison from '../MiniComparison.jsx';
|
||||
|
||||
<MiniComparison />
|
||||
@@ -0,0 +1,15 @@
|
||||
import { SlideRepl } from '../SlideRepl.jsx';
|
||||
|
||||
# Pattern Example
|
||||
|
||||
<SlideRepl
|
||||
tune={`"<0 2 [4 6](3,4,1) 3>"
|
||||
.off(1/4, add(2))
|
||||
.off(1/2, add(6))
|
||||
.scale('D minor')
|
||||
.legato(.25)
|
||||
.note().s("sawtooth square")
|
||||
.delay(.8).delaytime(.125)`}
|
||||
hideHeader
|
||||
punchcard
|
||||
/>
|
||||
Reference in New Issue
Block a user