diff --git a/packages/tone/pianoroll.mjs b/packages/tone/pianoroll.mjs
index 9233b0407..a74effa91 100644
--- a/packages/tone/pianoroll.mjs
+++ b/packages/tone/pianoroll.mjs
@@ -90,6 +90,7 @@ Pattern.prototype.pianoroll = function ({
barThickness - 2, // height
];
}
+ coords = coords.map((c) => Math.round(c));
isActive ? ctx.strokeRect(...coords) : ctx.fillRect(...coords);
});
const playheadPosition = scale(-from / timeExtent, ...timeRange);
diff --git a/talk/deck.mdx b/talk/deck.mdx
index 64e79b701..08a065c7f 100644
--- a/talk/deck.mdx
+++ b/talk/deck.mdx
@@ -10,12 +10,24 @@ import ImgTile from './ImgTile';
Algorithmic Patterns for the Web
+
+ "The Analytical Engine weaves algebraic patterns, just as the Jacquard loom weaves flowers and leaves." - Ada
+ Lovelace
+
- "The Analytical Engine weaves algebraic patterns, just as the Jacquard loom weaves flowers and leaves."
+ “[The Analytical Engine] might act upon other things besides number, were objects found whose
+ mutual fundamental relations could be expressed by those of the abstract science of operations{' '}
+ [...]
+
+ , and which should be also susceptible of adaptations to the action of the operating notation and mechanism of the
+ engine.{' '}
+
- “Supposing, for instance, that the fundamental relations of pitched sounds in the science of harmony and of musical
- composition were susceptible of such expression and adaptations, the [Analytical] Engine might compose elaborate and
- scientific pieces of music of any degree of complexity or extent." - Ada Lovelace
+ Supposing, for instance, that the fundamental relations of pitched sounds in the science of harmony and of musical composition
+ were susceptible of such expression and adaptations, the [Analytical] Engine might compose elaborate and scientific pieces
+ of music of any degree of complexity or extent."
+
+ -- Ada Lovelace, (1815 - 1852)
@@ -29,10 +41,11 @@ import ImgTile from './ImgTile';
- How to represent and control music with code?
- How to leverage unique features of computing?
- How to break loose from old conventions?
+- Answer: Live Coding?
-
+
## About Me
@@ -94,7 +107,7 @@ import ImgTile from './ImgTile';
- A very popular software for live coding music
-- a powerful pattern language for time-based art
+- a powerful pattern language, inspired by konnakol and weaving
- find out more at
tidalcycles.org
@@ -266,13 +279,13 @@ stack(
- Embedded Domain Specific Language
-- PEG.js grammar based on krill by Marc Resibois
+- PEG grammar based on [krill](https://github.com/Mdashdotdashn/krill/) by Marc Resibois
\`
.legato(.5)
).fast(2).pianoroll({fold:1,cycles:8,overscan:8})`,
+ `stack(
+"c2 ",
+"<[e3,[g3 a3 bb3 a3]]!11 [e3,g3]>".slow(2)
+ .struct("<[[x@2 x]*4]!11 [[~@2 x] [[x@2 ~]*9]@3]>".slow(2))
+)
+ .velocity("[.9@2 .6]*2".add(rand.range(-.1,.1)))
+ .transpose("<1 6 1@2 6@2 1@2 8 6 1 8>/2")
+ .tone((await piano()).toDestination())`,
]}
/>
+## Parsing Expression Grammars
+
+
+
+1. write [peg](https://github.com/tidalcycles/strudel/blob/main/packages/mini/krill.pegjs), generate [parser](https://github.com/tidalcycles/strudel/blob/main/packages/mini/krill-parser.js) with [parser generator](https://peggyjs.org/)
+2. pass string (e.g. `c3 [e3 g3]`) to generated parser
+3. obtain Abstract Syntax Tree (AST)
+4. [transform](https://github.com/tidalcycles/strudel/blob/main/packages/mini/mini.mjs#L76) AST into Pattern
+
+
+
+
+
+[OhmJS Editor](https://ohmjs.org/editor/)
+
+
+
+## AST of `c3 [e3 g3]`
+
+
+
+```js
+{
+ "type_": "pattern",
+ "arguments_": { "alignment": "h" },
+ "source_": [
+ {
+ "type_": "element", "source_": "c3",
+ "location_": { "start": { "offset": 1, "line": 1, "column": 2 }, "end": { "offset": 4, "line": 1, "column": 5 } }
+ },
+ {
+ "type_": "element",
+ "location_": { "start": { "offset": 4, "line": 1, "column": 5 }, "end": { "offset": 11, "line": 1, "column": 12 } }
+ "source_": {
+ "type_": "pattern", "arguments_": { "alignment": "h" },
+ "source_": [
+ {
+ "type_": "element", "source_": "e3",
+ "location_": { "start": { "offset": 5, "line": 1, "column": 6 }, "end": { "offset": 8, "line": 1, "column": 9 } }
+ },
+ {
+ "type_": "element", "source_": "g3",
+ "location_": { "start": { "offset": 8, "line": 1, "column": 9 }, "end": { "offset": 10, "line": 1, "column": 11 } }
+ }
+ ]
+ },
+ }
+ ]
+}
+```
+
+
+
+= `seq(c3, seq(e3, g3))`
+
+
+
## Pattern Factories
seq, cat, stack
@@ -352,7 +430,7 @@ seq, cat, stack
## Time Control
-fast / slow, early / late, rev
+fast / slow, early / late, rev, palindrome
".early(.16)).late(.16)
- .tone((await piano()).toDestination())
- .pianoroll()`,
+ `stack(
+ "c3 e3".color('steelblue'),
+ "".early(.16)
+).late(.16)
+ .tone((await piano()).toDestination())
+ .pianoroll()`,
`"c3 e3 g3 bb3".rev()
.tone((await piano()).toDestination())
.pianoroll()`,
@@ -373,6 +454,35 @@ fast / slow, early / late, rev
+## JavaScript Transpilation
+
+
+
+- [converting](https://github.com/tidalcycles/strudel/blob/main/packages/eval/shapeshifter.mjs#L40) valid JavaScript to valid JavaScript
+
+

+
+
+
+
+
Before (User Code)
+
After (Ready to Eval)
+
+
{`"c3 e3"
+ .fast(2)`}
+
+
{`mini('c3 e3')
+ .withMiniLocation([1,0,0],[1,7,7])
+ .fast(2)`}
+
+
+
+
+
+[Blog Post](https://loophole-letters.vercel.app/shift-ast), [AST Explorer](https://astexplorer.net/)
+
+
+
## Arithmetic & Patternified Params
add, sub, mul, div
@@ -381,7 +491,7 @@ add, sub, mul, div
code={[
`"30,42 45 49 54".add(0)
.tone((await piano()).toDestination())
- .pianoroll({autorange:0,minMidi:30,maxMidi:56})`,
+ .pianoroll({autorange:0,minMidi:28,maxMidi:56})`,
`"30,42 45 49 54".add("<0 1 2 1>/2")
.tone((await piano()).toDestination())
.pianoroll({fold:1,cycles:8})`,
@@ -440,6 +550,14 @@ sine / saw / tri / square / rand / perlin, range, segment
.range(42,54).slow(4).segment(8)
.pianoroll({ minMidi:42, maxMidi: 54, autorange:0,
cycles:8,fold:0,inactive:'orange'})`,
+ `s("hh*8").speed(sine.range(.5,2).slow(4))
+ .webdirt()`,
+ `sine.range(42,50).color('#00ff0050')
+ .superimpose(x=>x.fast(3/2).color('#ff00ff50'))
+ .fast(1)
+ .segment(64)
+ .pianoroll({fold:0,vertical:0,cycles:2})
+// strudel disable-highlighting`,
]}
/>
@@ -461,7 +579,7 @@ sine / saw / tri / square / rand / perlin, range, segment
]}
/>
-
+
## Shuffling
@@ -531,32 +649,20 @@ s("cp").struct("x!3 ~ x!2 ~ x ~ x!2 ~").speed(.8)
-## Continuous Signals
+## Chord Voicings
+
+chord dictionaries + smooth voice leading (blog post)
x.fast(3/2).color('#ff00ff50'))
- .fast(1)
- .segment(64)
- .pianoroll({fold:0,vertical:0,cycles:2})
-// strudel disable-highlighting`,
- ]}
-/>
-
-
-
-
-
-## Chords and Scales
-
-] E2")
+ .slow(4)
+ .tone((await piano()).toDestination())
+ .pianoroll({cycles:8,fold:1,inactive:'orange'})`,
+ `// froos - giant steps, stride version
stack(
// melody
seq(
@@ -582,7 +688,60 @@ stack(
"[B2 F#2] [F2 Bb2] [Eb2 Bb2] [C#2 F#2]"
)
.struct("x ~".fast(4*8))
-).slow(25)`]}/>
+).slow(25)
+ .tone((await piano()).toDestination())
+ .pianoroll({cycles:8,fold:1,inactive:'orange'})`]}/>
+
+
+## Strudel Packages
+
+`npm i @strudel.cycles/*`, where \* is one of:
+
+
+
+- core: tidal pattern engine
+- mini: mini notation parser + core binding
+- eval: user code evaluator. syntax sugar + highlighting
+- tone: bindings for Tone.js instruments and effects
+- osc: bindings to communicate via OSC
+- midi: webmidi bindings
+- serial: webserial bindings
+- tonal: tonal functions
+- xen: microtonal / xenharmonic functions
+- ... there are [more](https://github.com/tidalcycles/strudel/tree/main/packages)
+
+
+
+
+
+## Workflow
+
+
+
+- Everything is in one [monorepo](https://github.com/tidalcycles/strudel)
+- Development via npm workspaces
+- Packages are published with lerna
+- REPL is Deployed to github pages
+- Features are added with Pull Requests
+- Automated tests run for every PR
+- Snapshot tests
+
+
+
+
+
+## Tech Stack
+
+
+
+- REPL: Codemirror 6 + react + tailwind
+- Everything is built with vite
+- In source documentation with jsdoc
+- Tutorial written with MDX
+- jsdoc is inserted into MDX with nunjucks
+
+
+
diff --git a/talk/public/pegflow.png b/talk/public/pegflow.png
new file mode 100644
index 000000000..615d48180
Binary files /dev/null and b/talk/public/pegflow.png differ
diff --git a/talk/public/shiftflow.png b/talk/public/shiftflow.png
new file mode 100644
index 000000000..8d91658dc
Binary files /dev/null and b/talk/public/shiftflow.png differ