jevstrudel.git / website / src / pages / recipes / microrhythms.mdx
microrhythms.mdx74 lines · 2.0 KB · raw
1---
2title: Microrhythms
3layout: ../../layouts/MainLayout.astro
4---
5
6import { MiniRepl } from '../../docs/MiniRepl';
7
8see https://strudel.cc/?zMEo5kowGrFc
9
10# Microrhythms
11
12Inspired by this [Mini-Lecture on Microrhythm Notation](https://www.youtube.com/watch?v=or7B6vI3jOo), let's look at how we can express microrhythms with Strudel.
13
14The timestamps of the first rhythm are `0 1/5 1/2 2/3 1`. We could naively express this with a stack:
15
16<MiniRepl
17  client:idle
18  tune={`s("hh").struct(
19  stack(
20    "x", // 0
21    "~ x ~@3", // 1/5
22    "~ x", // 1/2
23    "~@2 x" // 2/3
24))`}
25/>
26
27While this works, it has two problems:
28
29- it is not very compact
30- the durations are wrong, e.g. the first note takes up the whole cycle
31
32In the video, the duration of a timestamp is calculated by subtracting it from the next timestamp:
33
34- 1/5 - 0 = 1/5 = 6/30
35- 1/2 - 1/5 = 3/10 = 9/30
36- 2/3 - 1/2 = 1/6 = 5/30
37- 1 - 2/3 = 1/3 = 10/30
38
39Using those, we can now express the rhythm much shorter:
40
41<MiniRepl client:idle tune={`s("hh").struct("x@6 x@9 x@5 x@10")`} />
42
43The problems of the first notation are now fixed: it is much shorter and the durations are correct.
44Still, this notation involved calculating the durations by hand, which could be automated:
45
46<MiniRepl
47  client:idle
48  tune={`Pattern.prototype.micro = function (...timestamps) {
49  const durations = timestamps.map((x, i, a) => {
50    const next = i < a.length-1 ? a[i+1] : 1;
51    return next - a[i]
52  })
53  return this.struct(timeCat(...durations.map(d => [d, 1]))).late(timestamps[0])
54}
55s('hh').micro(0, 1/5, 1/2, 2/3)`}
56/>
57
58This notation is even shorter and it allows directly filling in the timestamps!
59
60This is the second example of the video:
61
62<MiniRepl
63  client:idle
64  tune={`Pattern.prototype.micro = function (...timestamps) {
65  const durations = timestamps.map((x, i, a) => {
66    const next = i < a.length-1 ? a[i+1] : 1;
67    return next - a[i]
68  })
69  return this.struct(timeCat(...durations.map(d => [d, 1]))).late(timestamps[0])
70}
71s('hh').micro(0, 1/6, 2/5, 2/3, 3/4)`}
72/>
73
74with bass: https://strudel.cc/?sTglgJJCPIeY