mirror of
https://codeberg.org/uzu/strudel
synced 2026-08-04 22:31:04 -04:00
Merge pull request 'mondo notation' (#1311) from uzu into main
Reviewed-on: https://codeberg.org/uzu/strudel/pulls/1311
This commit is contained in:
@@ -81,6 +81,7 @@ export const SIDEBAR: Sidebar = {
|
||||
{ text: 'Visual Feedback', link: 'learn/visual-feedback' },
|
||||
{ text: 'Offline', link: 'learn/pwa' },
|
||||
{ text: 'Patterns', link: 'technical-manual/patterns' },
|
||||
{ text: 'Mondo Notation', link: 'learn/mondo-notation' },
|
||||
{ text: 'Music metadata', link: 'learn/metadata' },
|
||||
{ text: 'CSound', link: 'learn/csound' },
|
||||
{ text: 'Hydra', link: 'learn/hydra' },
|
||||
|
||||
@@ -30,6 +30,7 @@ export function MiniRepl({
|
||||
maxHeight,
|
||||
autodraw,
|
||||
drawTime,
|
||||
mondo = false,
|
||||
}) {
|
||||
const code = tunes ? tunes[0] : tune;
|
||||
const id = useMemo(() => s4(), []);
|
||||
@@ -85,6 +86,7 @@ export function MiniRepl({
|
||||
},
|
||||
beforeStart: () => audioReady,
|
||||
afterEval: ({ code }) => setVersionDefaultsFrom(code),
|
||||
mondo,
|
||||
});
|
||||
// init settings
|
||||
editor.setCode(code);
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
---
|
||||
title: Mondo Notation
|
||||
layout: ../../layouts/MainLayout.astro
|
||||
---
|
||||
|
||||
import { MiniRepl } from '../../docs/MiniRepl';
|
||||
import { JsDoc } from '../../docs/JsDoc';
|
||||
|
||||
# Mondo Notation
|
||||
|
||||
"Mondo Notation" is a new kind of notation that is similar to [Mini Notation](/learn/mini-notation/), but with enough abilities to make it work as a standalone pattern language.
|
||||
Here's an example:
|
||||
|
||||
<MiniRepl
|
||||
mondo
|
||||
client:idle
|
||||
tune={`$ note (c2 # euclid <3 6 3> <8 16>) # *2
|
||||
# s "sine" # add (note [0 <12 24>]*2)
|
||||
# dec(sine # range .2 2)
|
||||
# room .5
|
||||
# lpf (sine/3 # range 120 400)
|
||||
# lpenv (rand # range .5 4)
|
||||
# lpq (perlin # range 5 12 # * 2)
|
||||
# dist 1 # fm 4 # fmh 5.01 # fmdecay <.1 .2>
|
||||
# postgain .6 # delay .1 # clip 5
|
||||
|
||||
$ s [bd bd bd bd] # bank tr909 # clip .5
|
||||
|
||||
# ply <1 [1 [2 4]]>
|
||||
|
||||
$ s oh\*4 # press # bank tr909 # speed.8
|
||||
|
||||
# dec (<.02 .05>\*2 # add (saw/8 # range 0 1))
|
||||
|
||||
`}
|
||||
/>
|
||||
|
||||
## Mondo in the REPL
|
||||
|
||||
For now, you can only use mondo in the repl like this:
|
||||
|
||||
<MiniRepl client:idle tune={'mondo`s hh*8`'} />
|
||||
|
||||
The rest of this site will only use the mondo notation itself.
|
||||
In the future, the REPL might get a way to use mondo notation directly.
|
||||
|
||||
## Calling Functions
|
||||
|
||||
Compared to Mini Notation, the most notable feature of Mondo Notation is the ability to call functions using round brackets:
|
||||
|
||||
<MiniRepl mondo client:idle tune={`(s hh*8)`} />
|
||||
|
||||
The first element inside the brackets is the function name. In JS, this would look like:
|
||||
|
||||
<MiniRepl client:idle tune={`s("hh*8")`} />
|
||||
|
||||
The outermost parens are not needed, so we can drop them:
|
||||
|
||||
<MiniRepl mondo client:idle tune={`s hh*8`} />
|
||||
|
||||
## Mini Notation Features
|
||||
|
||||
Besides function calling with round parens, Mondo Notation has a lot in common with Mini Notation:
|
||||
|
||||
### Brackets
|
||||
|
||||
- `[]` for 1-cycle sequences
|
||||
- `<>` for multi-cycle sequences
|
||||
- `{}` for stepped sequences (more on that later)
|
||||
|
||||
### Infix Operators
|
||||
|
||||
- \* => [fast](/learn/time-modifiers/#fast)
|
||||
- / => [slow](/learn/time-modifiers/#slow)
|
||||
- ! => [extend](/learn/stepwise/#extend)
|
||||
- @ => [expand](/learn/stepwise/#expand)
|
||||
- % => [pace](/learn/stepwise/#pace)
|
||||
- ? => [degradeBy](/learn/random-modifiers/#degradeby) (currently requires right operand)
|
||||
- : => tail (creates a list)
|
||||
- .. => range (between numbers)
|
||||
- , => [stack](/learn/factories/#stack)
|
||||
- | => [chooseIn](/learn/random-modifiers/#choose)
|
||||
|
||||
### Example
|
||||
|
||||
<MiniRepl
|
||||
mondo
|
||||
client:idle
|
||||
tune={`note <
|
||||
[e5 [b4 c5] d5 [c5 b4]]
|
||||
[a4 [a4 c5] e5 [d5 c5]]
|
||||
[b4 [~ c5] d5 e5]
|
||||
[c5 a4 a4 ~]
|
||||
[[~ d5] [~ f5] a5 [g5 f5]]
|
||||
[e5 [~ c5] e5 [d5 c5]]
|
||||
[b4 [b4 c5] d5 e5]
|
||||
[c5 a4 a4 ~]
|
||||
>`}
|
||||
/>
|
||||
|
||||
## Chaining Functions
|
||||
|
||||
Similar to how "." works in javascript (JS), we can chain functions calls with the "#" operator:
|
||||
|
||||
<MiniRepl
|
||||
mondo
|
||||
client:idle
|
||||
tune={`n <0 2 4 [3 1] -1>*4
|
||||
# scale C4:minor
|
||||
# jux rev
|
||||
# dec .2
|
||||
# delay .5`}
|
||||
/>
|
||||
|
||||
Here's the same written in JS:
|
||||
|
||||
<MiniRepl
|
||||
client:idle
|
||||
tune={`n("<0 2 4 [3 1] -1>*4")
|
||||
.scale("C4:minor")
|
||||
.jux(rev)
|
||||
.dec(.2)
|
||||
.delay(.5)`}
|
||||
/>
|
||||
|
||||
### Chaining Functions Locally
|
||||
|
||||
A function can be applied to a single element by wrapping it in round parens:
|
||||
|
||||
<MiniRepl mondo client:idle tune={`s [bd hh bd (cp # delay .6)] # bank tr909`} />
|
||||
|
||||
in this case, `delay .6` will only be applied to `cp`. compare this with the JS version:
|
||||
|
||||
<MiniRepl client:idle tune={`s(seq("bd", "hh", "bd", "cp".delay(.6))).bank('tr909')`} />
|
||||
|
||||
here we can see how much we can save when there's no boundary between mini notation and function calls!
|
||||
|
||||
### Chaining Infix Operators
|
||||
|
||||
Infix operators exist as regular functions, so they can be chained as well:
|
||||
|
||||
<MiniRepl client:idle mondo tune={`s [bd hh] # bank tr909 # *2`} />
|
||||
|
||||
In this case, the \*2 will be applied to the whole pattern.
|
||||
|
||||
### Lambda Functions
|
||||
|
||||
Some functions in strudel expect a function as input, for example:
|
||||
|
||||
<MiniRepl client:idle tune={`n("0 .. 7").scale("C:minor").sometimes(x=>x.dec(.1))`} />
|
||||
|
||||
in mondo, the `x=>x.` can be shortened to:
|
||||
|
||||
<MiniRepl client:idle mondo tune={`n 0..7 # scale C:minor # sometimes (# dec .1)`} />
|
||||
|
||||
chaining works as expected:
|
||||
|
||||
<MiniRepl client:idle mondo tune={`n 0..7 # scale C:minor # sometimes (# dec .1 # jux rev)`} />
|
||||
|
||||
## Strings
|
||||
|
||||
You can use "double quotes" and 'single quotes' to get a string:
|
||||
|
||||
<MiniRepl client:idle mondo tune={`n 0..7 # scale 'C minor'`} />
|
||||
|
||||
## Multiple Patterns
|
||||
|
||||
The `$` sign can be used to separate multiple patterns:
|
||||
|
||||
<MiniRepl
|
||||
client:idle
|
||||
mondo
|
||||
tune={`$ s [bd rim [~ bd] rim] # bank tr707
|
||||
$ chord <Dm9!3 Db7> # voicing
|
||||
# struct[x ~ ~ x ~ x ~ ~] # delay .5`}
|
||||
/>
|
||||
|
||||
The `$` sign is an alias for `,` so it will create a stack behind the scenes.
|
||||
@@ -69,32 +69,32 @@ stack(
|
||||
|
||||
export const giantSteps = `// John Coltrane - Giant Steps
|
||||
|
||||
let melody = note(
|
||||
let melody = seq(
|
||||
"[F#5 D5] [B4 G4] Bb4 [B4 A4]",
|
||||
"[D5 Bb4] [G4 Eb4] F#4 [G4 F4]",
|
||||
"Bb4 [B4 A4] D5 [D#5 C#5]",
|
||||
"F#5 [G5 F5] Bb5 [F#5 F#5]",
|
||||
)
|
||||
).note()
|
||||
|
||||
stack(
|
||||
// melody
|
||||
melody.color('#F8E71C'),
|
||||
// chords
|
||||
chord(
|
||||
seq(
|
||||
"[B^7 D7] [G^7 Bb7] Eb^7 [Am7 D7]",
|
||||
"[G^7 Bb7] [Eb^7 F#7] B^7 [Fm7 Bb7]",
|
||||
"Eb^7 [Am7 D7] G^7 [C#m7 F#7]",
|
||||
"B^7 [Fm7 Bb7] Eb^7 [C#m7 F#7]"
|
||||
).dict('lefthand')
|
||||
).chord().dict('lefthand')
|
||||
.anchor(melody).mode('duck')
|
||||
.voicing().color('#7ED321'),
|
||||
// bass
|
||||
note(
|
||||
seq(
|
||||
"[B2 D2] [G2 Bb2] [Eb2 Bb3] [A2 D2]",
|
||||
"[G2 Bb2] [Eb2 F#2] [B2 F#2] [F2 Bb2]",
|
||||
"[Eb2 Bb2] [A2 D2] [G2 D2] [C#2 F#2]",
|
||||
"[B2 F#2] [F2 Bb2] [Eb2 Bb3] [C#2 F#2]"
|
||||
).color('#00B8D4')
|
||||
).note().color('#00B8D4')
|
||||
).slow(20)
|
||||
.pianoroll({fold:1})`;
|
||||
|
||||
|
||||
@@ -84,6 +84,7 @@ export function loadModules() {
|
||||
import('@strudel/gamepad'),
|
||||
import('@strudel/motion'),
|
||||
import('@strudel/mqtt'),
|
||||
import('@strudel/mondo'),
|
||||
];
|
||||
if (isTauri()) {
|
||||
modules = modules.concat([
|
||||
|
||||
Reference in New Issue
Block a user