mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-11 05:38:34 +00:00
Merge pull request #1053 from tidalcycles/workshop-edits
improve tutorial + custom samples doc
This commit is contained in:
commit
e0c4997f1e
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@strudel/sampler",
|
||||
"version": "0.0.8",
|
||||
"version": "0.0.9",
|
||||
"description": "",
|
||||
"keywords": [
|
||||
"tidalcycles",
|
||||
|
||||
BIN
website/public/img/drumset.png
Normal file
BIN
website/public/img/drumset.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 338 KiB |
@ -146,15 +146,13 @@ Wir schauen uns später noch mehr Möglichkeiten an wie man patterns kombiniert.
|
||||
|
||||
**Sequenzen verlangsamen mit `/`**
|
||||
|
||||
{/* [c2 bb1 f2 eb2] */}
|
||||
|
||||
<MiniRepl client:visible tune={`note("[36 34 41 39]/4").sound("gm_acoustic_bass")`} punchcard />
|
||||
|
||||
<Box>
|
||||
|
||||
Das `/4` spielt die Sequenz 4 mal so langsam, also insgesamt 4 cycles = 4s.
|
||||
Das `/4` spielt die Sequenz 4 mal so langsam, also insgesamt 4 cycles = 8s.
|
||||
|
||||
Jede Note ist nun also 1s lang.
|
||||
Jede Note ist nun also 2s lang.
|
||||
|
||||
Schreib noch mehr Töne in die Klammern und achte darauf dass es schneller wird.
|
||||
|
||||
@ -164,6 +162,9 @@ Wenn eine Sequenz unabhängig von ihrem Inhalt immer gleich schnell bleiben soll
|
||||
|
||||
**Eins pro Cycle per \< \>**
|
||||
|
||||
Im letzten Kapitel haben wir schon gelernt dass `< ... >` (angle brackets) nur ein Element pro Cycle spielt.
|
||||
Das ist für Melodien auch sehr nützlich:
|
||||
|
||||
<MiniRepl client:visible tune={`note("<36 34 41 39>").sound("gm_acoustic_bass")`} punchcard />
|
||||
|
||||
<Box>
|
||||
|
||||
@ -78,13 +78,24 @@ Strudel kommt von Haus aus mit einer breiten Auswahl an Drum Sounds:
|
||||
|
||||
<Box>
|
||||
|
||||
Diese 2-Buchstaben Kombinationen stehen für verschiedene Teile eines Schlagzeugs:
|
||||
Diese Kombinationen von Buchstaben stehen für verschiedene Teile eines Schlagzeugs:
|
||||
|
||||
<img src="/img/drumset.png" />
|
||||
|
||||
<a class="text-right text-xs" href="https://de.wikipedia.org/wiki/Schlagzeug#/media/Datei:Drum_set.svg" target="_blank">
|
||||
original von Pbroks13
|
||||
</a>
|
||||
|
||||
- `bd` = **b**ass **d**rum - Basstrommel
|
||||
- `sd` = **s**nare **d**rum - Schnarrtrommel
|
||||
- `rim` = **rim**shot - Rahmenschlag
|
||||
- `hh` = **h**i**h**at - Hallo Hut
|
||||
- `oh` = **o**pen **h**ihat - Offener Hallo Hut
|
||||
- `lt` = **l**ow tom
|
||||
- `mt` = **m**iddle tom
|
||||
- `ht` = **h**igh tom
|
||||
- `rd` = **r**i**d**e cymbal
|
||||
- `rd` = **cr**ash cymbal
|
||||
|
||||
Probier verschiedene Sounds aus!
|
||||
|
||||
@ -131,34 +142,58 @@ Versuch noch mehr Sounds hinzuzfügen!
|
||||
|
||||
<MiniRepl client:visible tune={`sound("bd bd hh bd rim bd hh bd")`} punchcard />
|
||||
|
||||
Der Inhalt einer Sequence wird in einen sogenannten Cycle (=Zyklus) zusammengequetscht.
|
||||
Der Inhalt einer Sequence wird in einen sogenannten Cycle (=Zyklus) zusammengequetscht. Ein Cycle ist standardmäßig 2 Sekunden lang.
|
||||
|
||||
**Eins pro Cycle mit `< .. >`**
|
||||
|
||||
Hier ist die gleiche Sequence, aber dieses mal umgeben von `< .. >` (angle brackets):
|
||||
|
||||
<MiniRepl client:visible tune={`sound("<bd bd hh bd rim bd hh bd>")`} punchcard />
|
||||
|
||||
Jetzt spielt nur ein Sound pro Cycle. Mit diesen Klammern bleibt das Tempo immer gleich, ganz egal wieviele Elemente enhalten sind!
|
||||
|
||||
Das ist jetzt aber etwas langsam, machen wir es schneller mit `*`:
|
||||
|
||||
<MiniRepl client:visible tune={`sound("<bd bd hh bd rim bd hh bd>*8")`} punchcard />
|
||||
|
||||
Die `*8` macht die ganze Sequenz 8 mal so schnell.
|
||||
|
||||
<Box>
|
||||
|
||||
Warte mal, ist das jetzt nicht das gleiche Ergebnis wie ohne `< ... >*8`? Wofür ist das dann gut?
|
||||
|
||||
Korrekt, der echte Vorteil dieser Schreibweise zeigt sich wenn du Elemente entfernst oder hinzufügst. Versuch es mal!
|
||||
|
||||
Ändere auch mal die Zahl am Ende um das Tempo zu verändern.
|
||||
|
||||
</Box>
|
||||
|
||||
**Tempo ändern mit `cpm`**
|
||||
|
||||
<MiniRepl client:visible tune={`sound("bd bd hh bd rim bd hh bd").cpm(40)`} punchcard />
|
||||
<MiniRepl client:visible tune={`sound("<bd hh rim hh>*8").cpm(90/4)`} punchcard />
|
||||
|
||||
<Box>
|
||||
|
||||
cpm = **c**ycles per **m**inute = Cycles pro Minute
|
||||
|
||||
Das Tempo ist standardmäßig auf 60cpm eingestellt, also 1 Cycle pro Sekunde.
|
||||
Das Tempo is standardmäßig is 30 Cycles pro Minute = 120/4 = 1 Cycle alle 2 Sekunden
|
||||
|
||||
`cpm` ist angelehnt an `bpm` (=beats per minute).
|
||||
In taditioneller Musik-Terminologie könnte man sagen, das Pattern oben besteht aus 8tel Noten auf 90bpm im 4/4 Takt.
|
||||
|
||||
Kein Sorge wenn dir diese Begriffe nichts sagen, das ist nicht notwendig um mit Strudel Musik zu machen.
|
||||
|
||||
</Box>
|
||||
|
||||
Wir werden später noch mehr Möglichkeiten kennen lernen das Tempo zu verändern.
|
||||
|
||||
**Pausen mit '~'**
|
||||
**Pausen mit '-' oder '~'**
|
||||
|
||||
<MiniRepl client:visible tune={`sound("bd hh ~ rim")`} punchcard />
|
||||
<MiniRepl client:visible tune={`sound("bd hh - rim")`} punchcard />
|
||||
|
||||
<Box>
|
||||
|
||||
Tilde tippen:
|
||||
|
||||
- Windows / Linux: `Alt Gr` + `~`
|
||||
- Mac: `option` + `N`
|
||||
Du siehst wahrscheinlich auch Patterns von anderen Leuten mit '~' als Pausensymbol.
|
||||
Besonders für deutsche Tastaturen ist `-` eine Alternative zum schwer tippbaren `~`.
|
||||
|
||||
</Box>
|
||||
|
||||
@ -219,7 +254,7 @@ Du kannst so tief verschachteln wie du willst!
|
||||
|
||||
Du kannst so viele Kommas benutzen wie du möchtest:
|
||||
|
||||
<MiniRepl client:visible tune={`sound("hh hh hh, bd bd, ~ casio")`} punchcard />
|
||||
<MiniRepl client:visible tune={`sound("hh hh hh, bd bd, - casio")`} punchcard />
|
||||
|
||||
Kommas können auch in Unter-Sequenzen verwendet werden:
|
||||
|
||||
@ -237,9 +272,9 @@ Es kommt öfter vor, dass man die gleiche Idee auf verschiedene Arten ausdrücke
|
||||
|
||||
<MiniRepl
|
||||
client:visible
|
||||
tune={`sound(\`bd*2, ~ cp,
|
||||
~ ~ ~ oh, hh*4,
|
||||
[~ casio]*2\`)`}
|
||||
tune={`sound(\`bd*2, - cp,
|
||||
- - - oh, hh*4,
|
||||
[- casio]*2\`)`}
|
||||
punchcard
|
||||
/>
|
||||
|
||||
@ -269,7 +304,7 @@ Das haben wir bisher gelernt:
|
||||
| --------------------- | ----------- | --------------------------------------------------------------------- |
|
||||
| Sequenz | Leerzeichen | <MiniRepl client:visible tune={`sound("bd bd sd hh")`} /> |
|
||||
| Sound Nummer | :x | <MiniRepl client:visible tune={`sound("hh:0 hh:1 hh:2 hh:3")`} /> |
|
||||
| Pausen | ~ | <MiniRepl client:visible tune={`sound("metal ~ jazz jazz:1")`} /> |
|
||||
| Pausen | - | <MiniRepl client:visible tune={`sound("metal - jazz jazz:1")`} /> |
|
||||
| Unter-Sequenzen | \[\] | <MiniRepl client:visible tune={`sound("bd wind [metal jazz] hh")`} /> |
|
||||
| Unter-Unter-Sequenzen | \[\[\]\] | <MiniRepl client:visible tune={`sound("bd [metal [jazz sd]]")`} /> |
|
||||
| Schneller | \* | <MiniRepl client:visible tune={`sound("bd sd*2 cp*3")`} /> |
|
||||
@ -293,7 +328,7 @@ Die folgenden Funktionen haben wir bereits gesehen:
|
||||
|
||||
**Klassischer House**
|
||||
|
||||
<MiniRepl client:visible tune={`sound("bd*2, ~ cp, [~ hh]*2").bank("RolandTR909")`} punchcard />
|
||||
<MiniRepl client:visible tune={`sound("bd*2, - cp, [- hh]*2").bank("RolandTR909")`} punchcard />
|
||||
|
||||
<Box>
|
||||
|
||||
@ -310,7 +345,7 @@ We Will Rock you
|
||||
|
||||
<MiniRepl
|
||||
client:visible
|
||||
tune={`sound("bd sd, ~ ~ ~ hh ~ hh ~ ~, ~ perc ~ perc:1*2")
|
||||
tune={`sound("bd sd, - - - hh - hh - -, - perc - perc:1*2")
|
||||
.bank("RolandCompurhythm1000")`}
|
||||
punchcard
|
||||
/>
|
||||
@ -320,10 +355,10 @@ We Will Rock you
|
||||
<MiniRepl
|
||||
client:visible
|
||||
tune={`sound(\`
|
||||
[~ ~ oh ~ ] [~ ~ ~ ~ ] [~ ~ ~ ~ ] [~ ~ ~ ~ ],
|
||||
[hh hh ~ ~ ] [hh ~ hh ~ ] [hh ~ hh ~ ] [hh ~ hh ~ ],
|
||||
[~ ~ ~ ~ ] [cp ~ ~ ~ ] [~ ~ ~ ~ ] [cp ~ ~ ~ ],
|
||||
[bd ~ ~ ~ ] [~ ~ ~ bd] [~ ~ bd ~ ] [~ ~ ~ bd]
|
||||
[- - oh - ] [- - - - ] [- - - - ] [- - - - ],
|
||||
[hh hh - - ] [hh - hh - ] [hh - hh - ] [hh - hh - ],
|
||||
[- - - - ] [cp - - - ] [- - - - ] [cp - - - ],
|
||||
[bd - - - ] [- - - bd] [- - bd - ] [- - - bd]
|
||||
\`).cpm(90/4)`}
|
||||
punchcard
|
||||
/>
|
||||
@ -333,10 +368,10 @@ We Will Rock you
|
||||
<MiniRepl
|
||||
client:visible
|
||||
tune={`sound(\`
|
||||
[~ ~ ~ ~ ] [~ ~ ~ ~ ] [~ ~ ~ ~ ] [~ ~ oh:1 ~ ],
|
||||
[hh hh hh hh] [hh hh hh hh] [hh hh hh hh] [hh hh ~ ~ ],
|
||||
[~ ~ ~ ~ ] [cp ~ ~ ~ ] [~ ~ ~ ~ ] [~ cp ~ ~ ],
|
||||
[bd bd ~ ~ ] [~ ~ bd ~ ] [bd bd ~ bd ] [~ ~ ~ ~ ]
|
||||
[- - - - ] [- - - - ] [- - - - ] [- - oh:1 - ],
|
||||
[hh hh hh hh] [hh hh hh hh] [hh hh hh hh] [hh hh - - ],
|
||||
[- - - - ] [cp - - - ] [- - - - ] [- cp - - ],
|
||||
[bd bd - - ] [- - bd - ] [bd bd - bd ] [- - - - ]
|
||||
\`).bank("RolandTR808").cpm(88/4)`}
|
||||
punchcard
|
||||
/>
|
||||
@ -346,9 +381,9 @@ We Will Rock you
|
||||
<MiniRepl
|
||||
client:visible
|
||||
tune={`s(\`jazz*2,
|
||||
insect [crow metal] ~ ~,
|
||||
~ space:4 ~ space:1,
|
||||
~ wind\`)
|
||||
insect [crow metal] - -,
|
||||
- space:4 - space:1,
|
||||
- wind\`)
|
||||
.cpm(100/2)`}
|
||||
punchcard
|
||||
/>
|
||||
|
||||
@ -24,20 +24,31 @@ Here, we are using the `s` function to play back different default samples (`bd`
|
||||
|
||||
For drum sounds, strudel uses the comprehensive [tidal-drum-machines](https://github.com/ritchse/tidal-drum-machines) library, with the following naming convention:
|
||||
|
||||
| Drum | Abbreviation |
|
||||
| Drum | Abbreviation |
|
||||
| -------------------- | ------------ |
|
||||
| Bass drum, Kick drum | bd |
|
||||
| Snare drum | sd |
|
||||
| Rimshot | rim |
|
||||
| Clap | cp |
|
||||
| Closed hi-hat | hh |
|
||||
| Open hi-hat | oh |
|
||||
| Crash | cr |
|
||||
| Ride | rd |
|
||||
| High tom | ht |
|
||||
| Medium tom | mt |
|
||||
| Low tom | lt |
|
||||
|
||||
<img src="/img/drumset.png" />
|
||||
|
||||
<a class="text-right text-xs" href="https://de.wikipedia.org/wiki/Schlagzeug#/media/Datei:Drum_set.svg" target="_blank">
|
||||
original von Pbroks13
|
||||
</a>
|
||||
|
||||
More percussive sounds:
|
||||
|
||||
| Source | Abbreviation |
|
||||
| ----------------------------------- | ------------ |
|
||||
| Bass drum, Kick drum | bd |
|
||||
| Snare drum | sd |
|
||||
| Rimshot | rim |
|
||||
| Clap | cp |
|
||||
| Closed hi-hat | hh |
|
||||
| Open hi-hat | oh |
|
||||
| Crash | cr |
|
||||
| Ride | rd |
|
||||
| Shakers (and maracas, cabasas, etc) | sh |
|
||||
| High tom | ht |
|
||||
| Medium tom | mt |
|
||||
| Low tom | lt |
|
||||
| Cowbell | cb |
|
||||
| Tambourine | tb |
|
||||
| Other percussions | perc |
|
||||
@ -63,11 +74,11 @@ We _could_ use them like this:
|
||||
|
||||
... but thats obviously a bit much to write. Using the `bank` function, we can shorten this to:
|
||||
|
||||
<MiniRepl client:idle tune={`s("bd sd bd sd,hh*16").bank("RolandTR808")`} />
|
||||
<MiniRepl client:idle tune={`s("bd sd,hh*16").bank("RolandTR808")`} />
|
||||
|
||||
You could even pattern the bank to switch between different drum machines:
|
||||
|
||||
<MiniRepl client:idle tune={`s("bd sd bd sd,hh*16").bank("RolandTR808 RolandTR909")`} />
|
||||
<MiniRepl client:idle tune={`s("bd sd,hh*16").bank("<RolandTR808 RolandTR909>")`} />
|
||||
|
||||
Behind the scenes, `bank` will just prepend the drum machine name to the sample name with `_` to get the full name.
|
||||
This of course only works because the name after `_` (`bd`, `sd` etc..) is standardized.
|
||||
@ -97,159 +108,128 @@ Selecting sounds also works inside the mini notation, using "`:`" like this:
|
||||
|
||||
# Loading Custom Samples
|
||||
|
||||
You can load your own sample map using the `samples` function.
|
||||
In this example we create a map using sounds from the default sample map:
|
||||
You can load a non-standard sample map using the `samples` function.
|
||||
|
||||
<MiniRepl
|
||||
client:idle
|
||||
tune={`samples({
|
||||
bd: 'bd/BT0AADA.wav',
|
||||
sd: 'sd/rytm-01-classic.wav',
|
||||
hh: 'hh27/000_hh27closedhh.wav',
|
||||
}, 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/');
|
||||
s("bd sd bd sd,hh*16")`}
|
||||
/>
|
||||
## Loading samples from file URLs
|
||||
|
||||
When you load your own samples, you can choose the names that you will then refer to in your pattern string inside the `s` function.
|
||||
Compare with this example which uses the same samples, but with different names.
|
||||
In this example we assign names `bassdrum`, `hihat` and `snaredrum` to specific audio files on a server:
|
||||
|
||||
<MiniRepl
|
||||
client:idle
|
||||
tune={`samples({
|
||||
bassdrum: 'bd/BT0AADA.wav',
|
||||
snaredrum: 'sd/rytm-01-classic.wav',
|
||||
hihat: 'hh27/000_hh27closedhh.wav',
|
||||
snaredrum: ['sd/rytm-01-classic.wav', 'sd/rytm-00-hard.wav'],
|
||||
}, 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/');
|
||||
s("bassdrum snaredrum bassdrum snaredrum, hihat*16")`}
|
||||
|
||||
s("bassdrum snaredrum:0 bassdrum snaredrum:1, hihat*16")`}
|
||||
/>
|
||||
|
||||
Here we have changed the "map" to include longer sample names.
|
||||
You can freely choose any combination of letters for each sample name. It is even possible to override the default sounds.
|
||||
The names you pick will be made available in the `s` function.
|
||||
Make sure that the URL and each sample path form a correct URL!
|
||||
|
||||
## The `samples` function
|
||||
In the above example, `bassdrum` will load:
|
||||
|
||||
The `samples` function has two arguments:
|
||||
```
|
||||
https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/bd/BT0AADA.wav
|
||||
|----------------------base path --------------------------------|--sample path-|
|
||||
```
|
||||
|
||||
- A [JavaScript object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) that maps sound names to audio file paths.
|
||||
- A base URL that comes before each path describing where the sample folder can be found online.
|
||||
- Make sure your base URL ends with a slash, while your sample paths do **not** begin with one!
|
||||
Note that we can either load a single file, like for `bassdrum` and `hihat`, or a list of files like for `snaredrum`!
|
||||
As soon as you run the code, your chosen sample names will be listed in `sounds` -> `user`.
|
||||
|
||||
To see how this looks in practice, compare the [DirtSamples GitHub repo](https://github.com/tidalcycles/Dirt-Samples) with the previous sample map example.
|
||||
## Loading Samples from a strudel.json file
|
||||
|
||||
Because GitHub is a popular place for uploading open source samples, it has its own shortcut:
|
||||
The above way to load samples might be tedious to write out / copy paste each time you write a new pattern.
|
||||
To avoid that, you can simply pass a URL to a `strudel.json` file somewhere on the internet:
|
||||
|
||||
<MiniRepl
|
||||
client:idle
|
||||
tune={`samples({
|
||||
bd: 'bd/BT0AADA.wav',
|
||||
sd: 'sd/rytm-01-classic.wav',
|
||||
hh: 'hh27/000_hh27closedhh.wav',
|
||||
}, 'github:tidalcycles/dirt-samples');
|
||||
tune={`samples('https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/strudel.json')
|
||||
s("bd sd bd sd,hh*16")`}
|
||||
/>
|
||||
|
||||
The format is `github:user/repo/branch/`.
|
||||
The file is expected to define a sample map using JSON, in the same format as described above.
|
||||
Additionally, the base path can be defined with the `_base` key.
|
||||
The last section could be written as:
|
||||
|
||||
Let's see another example, this time based on the following GitHub repo: https://github.com/jarmitage/jarmitage.github.io.
|
||||
We can see there are some guitar samples inside the `/samples` folder, so let's try to load them:
|
||||
```json
|
||||
{
|
||||
"_base": "https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/",
|
||||
"bassdrum": "bd/BT0AADA.wav",
|
||||
"snaredrum": "sd/rytm-01-classic.wav",
|
||||
"hihat": "hh27/000_hh27closedhh.wav"
|
||||
}
|
||||
```
|
||||
|
||||
## Github Shortcut
|
||||
|
||||
Because loading samples from github is common, there is a shortcut:
|
||||
|
||||
<MiniRepl
|
||||
client:idle
|
||||
tune={`samples({
|
||||
g0: 'samples/guitar/guitar_0.wav',
|
||||
g1: 'samples/guitar/guitar_1.wav',
|
||||
g2: 'samples/guitar/guitar_2.wav',
|
||||
g3: 'samples/guitar/guitar_3.wav',
|
||||
g4: 'samples/guitar/guitar_4.wav'
|
||||
}, 'github:jarmitage/jarmitage.github.io/master/');
|
||||
s("<g0 g1 g2 g3 g4>/2")`}
|
||||
tune={`samples('github:tidalcycles/dirt-samples')
|
||||
s("bd sd bd sd,hh*16")`}
|
||||
/>
|
||||
|
||||
## Multiple Samples per Sound
|
||||
The format is `samples('github:<user>/<repo>/<branch>')`. If you omit `branch` (like above), the `main` branch will be used.
|
||||
It assumes a `strudel.json` file to be present at the root of the repository:
|
||||
|
||||
It is also possible, to declare multiple files for one sound, using the array notation:
|
||||
```
|
||||
https://raw.githubusercontent.com/<user>/<repo>/<branch>/strudel.json
|
||||
```
|
||||
|
||||
## From Disk via "Import Sounds"
|
||||
|
||||
If you don't want to upload your samples to the internet, you can also load them from your local disk.
|
||||
Go to the `sounds` tab in the REPL and press "import sounds".
|
||||
Then you can select a folder that contains audio files. The folder you select can also contain subfolders with audio files.
|
||||
Example:
|
||||
|
||||
```
|
||||
└─ samples
|
||||
├─ swoop
|
||||
│ ├─ swoopshort.wav
|
||||
│ ├─ swooplong.wav
|
||||
│ └─ swooptight.wav
|
||||
└─ smash
|
||||
├─ smashhigh.wav
|
||||
├─ smashlow.wav
|
||||
└─ smashmiddle.wav
|
||||
```
|
||||
|
||||
In the above example the folder `samples` contains 2 subfolders `swoop` and `smash`, which contain audio files.
|
||||
If you select that `samples` folder, the `user` tab (next to the import sounds button) will then contain 2 new sounds: `swoop(3) smash(3)`
|
||||
The individual samples can the be played normally like `s("swoop:0 swoop:1 smash:2")`.
|
||||
|
||||
## From Disk via @strudel/sampler
|
||||
|
||||
Instead of loading your samples into your browser with the "import sounds" button, you can also serve the samples from a local file server.
|
||||
The easiest way to do this is using [@strudel/sampler](https://www.npmjs.com/package/@strudel/sampler):
|
||||
|
||||
```sh
|
||||
cd samples
|
||||
npx @strudel/sampler
|
||||
```
|
||||
|
||||
Then you can load it via:
|
||||
|
||||
<MiniRepl
|
||||
client:idle
|
||||
tune={`samples({
|
||||
bd: ['bd/BT0AADA.wav','bd/BT0AAD0.wav'],
|
||||
sd: ['sd/rytm-01-classic.wav','sd/rytm-00-hard.wav'],
|
||||
hh: ['hh27/000_hh27closedhh.wav','hh/000_hh3closedhh.wav'],
|
||||
}, 'github:tidalcycles/dirt-samples');
|
||||
s("bd:0 bd:1,~ <sd:0 sd:1> ~ sd:0,[hh:0 hh:1]*4")`}
|
||||
tune={`samples('http://localhost:5432/');
|
||||
|
||||
n("<0 1 2>").s("swoop smash")`}
|
||||
/>
|
||||
|
||||
The `:0` `:1` etc. are the indices of the array.
|
||||
The sample number can also be set using `n`:
|
||||
The handy thing about `@strudel/sampler` is that it auto-generates the `strudel.json` file based on your folder structure.
|
||||
You can see what it generated by going to `http://localhost:5432` with your browser.
|
||||
|
||||
<MiniRepl
|
||||
client:idle
|
||||
tune={`samples({
|
||||
bd: ['bd/BT0AADA.wav','bd/BT0AAD0.wav'],
|
||||
sd: ['sd/rytm-01-classic.wav','sd/rytm-00-hard.wav'],
|
||||
hh: ['hh27/000_hh27closedhh.wav','hh/000_hh3closedhh.wav'],
|
||||
}, 'github:tidalcycles/dirt-samples');
|
||||
s("bd bd,~ sd ~ sd,hh*8").n("<0 1>")`}
|
||||
/>
|
||||
Note: You need [NodeJS](https://nodejs.org/) installed on your system for this to work.
|
||||
|
||||
In that case, we might load our guitar sample map a different way:
|
||||
## Specifying Pitch
|
||||
|
||||
<MiniRepl
|
||||
client:idle
|
||||
tune={`samples({
|
||||
guitar: [
|
||||
'samples/guitar/guitar_0.wav',
|
||||
'samples/guitar/guitar_1.wav',
|
||||
'samples/guitar/guitar_2.wav',
|
||||
'samples/guitar/guitar_3.wav',
|
||||
'samples/guitar/guitar_4.wav'
|
||||
]
|
||||
}, 'github:jarmitage/jarmitage.github.io/master/');
|
||||
s("<guitar:0 guitar:1 guitar:2 guitar:3 guitar:4>*2")`}
|
||||
/>
|
||||
|
||||
And as above, we can choose the sample number using `n` for even more flexibility:
|
||||
|
||||
<MiniRepl
|
||||
client:idle
|
||||
tune={`samples({
|
||||
guitar: [
|
||||
'samples/guitar/guitar_0.wav',
|
||||
'samples/guitar/guitar_1.wav',
|
||||
'samples/guitar/guitar_2.wav',
|
||||
'samples/guitar/guitar_3.wav',
|
||||
'samples/guitar/guitar_4.wav'
|
||||
]
|
||||
}, 'github:jarmitage/jarmitage.github.io/master/');
|
||||
n("<0 1 2 3 4>*2").s("guitar")`}
|
||||
/>
|
||||
|
||||
## Pitched Sounds
|
||||
|
||||
For pitched sounds, you can use `note`, just like with synths:
|
||||
|
||||
<MiniRepl
|
||||
client:idle
|
||||
tune={`samples({
|
||||
'gtr': 'gtr/0001_cleanC.wav',
|
||||
}, 'github:tidalcycles/dirt-samples');
|
||||
note("g3 [bb3 c4] <g4 f4 eb4 f3>@2").s('gtr').gain(.5)`}
|
||||
/>
|
||||
|
||||
Here, the guitar samples will overlap, because they always play till the end.
|
||||
If we want them to behave more like a synth, we can add `clip(1)`:
|
||||
|
||||
<MiniRepl
|
||||
client:idle
|
||||
tune={`samples({
|
||||
'gtr': 'gtr/0001_cleanC.wav',
|
||||
}, 'github:tidalcycles/dirt-samples');
|
||||
note("g3 [bb3 c4] <g4 f4 eb4 f3>@2").s('gtr').clip(1)
|
||||
.gain(.5)`}
|
||||
/>
|
||||
|
||||
## Base Pitch
|
||||
|
||||
If we have 2 samples with different base pitches, we can make them in tune by specifying the pitch like this:
|
||||
To make sure your samples are in tune when playing them with `note`, you can specify a base pitch like this:
|
||||
|
||||
<MiniRepl
|
||||
client:idle
|
||||
@ -261,8 +241,6 @@ note("g3 [bb3 c4] <g4 f4 eb4 f3>@2").s("gtr,moog").clip(1)
|
||||
.gain(.5)`}
|
||||
/>
|
||||
|
||||
If a sample has no pitch set, `c3` is the default.
|
||||
|
||||
We can also declare different samples for different regions of the keyboard:
|
||||
|
||||
<MiniRepl
|
||||
@ -280,6 +258,8 @@ note("g2!2 <bb2 c3>!2, <c4@3 [<eb4 bb3> g4 f4]>")
|
||||
|
||||
The sampler will always pick the closest matching sample for the current note!
|
||||
|
||||
Note that this notation for pitched sounds also works inside a `strudel.json` file.
|
||||
|
||||
## Shabda
|
||||
|
||||
If you don't want to select samples by hand, there is also the wonderful tool called [shabda](https://shabda.ndre.gr/).
|
||||
|
||||
@ -147,35 +147,43 @@ We will see more ways to combine patterns later..
|
||||
|
||||
**Divide sequences with `/` to slow them down**
|
||||
|
||||
{/* [c2 bb1 f2 eb2] */}
|
||||
|
||||
<MiniRepl client:visible tune={`note("[36 34 41 39]/4").sound("gm_acoustic_bass")`} punchcard />
|
||||
|
||||
<Box>
|
||||
|
||||
The `/4` plays the sequence in brackets over 4 cycles (=4s).
|
||||
The `/4` plays the sequence in brackets over 4 cycles (=8s).
|
||||
|
||||
So each of the 4 notes is 1s long.
|
||||
So each of the 4 notes is 2s long.
|
||||
|
||||
Try adding more notes inside the brackets and notice how it gets faster.
|
||||
|
||||
</Box>
|
||||
|
||||
Because it is so common to just play one thing per cycle, you can..
|
||||
**Play one per cycle with `< ... >`**
|
||||
|
||||
**Play one per cycle with \< \>**
|
||||
In the last section, we learned that `< ... >` (angle brackets) can be used to play only one thing per cycle,
|
||||
which is useful for longer melodies too:
|
||||
|
||||
<MiniRepl client:visible tune={`note("<36 34 41 39>").sound("gm_acoustic_bass")`} punchcard />
|
||||
|
||||
<Box>
|
||||
|
||||
Try adding more notes inside the brackets and notice how it does **not** get faster.
|
||||
Try adding more notes inside the brackets and notice how the tempo stays the same.
|
||||
|
||||
The angle brackets are actually just a shortcut:
|
||||
|
||||
`<a b c>` = `[a b c]/3`
|
||||
|
||||
`<a b c d>` = `[a b c d]/4`
|
||||
|
||||
...
|
||||
|
||||
</Box>
|
||||
|
||||
**Play one sequence per cycle**
|
||||
|
||||
{/* <[c2 c3]*4 [bb1 bb2]*4 [f2 f3]*4 [eb2 eb3]*4> */}
|
||||
We can combine the 2 types of brackets in all sorts of different ways.
|
||||
Here is an example of a repetitive bassline:
|
||||
|
||||
<MiniRepl
|
||||
client:visible
|
||||
|
||||
@ -78,11 +78,22 @@ By default, Strudel comes with a wide selection of drum sounds:
|
||||
|
||||
These letter combinations stand for different parts of a drum set:
|
||||
|
||||
<img src="/img/drumset.png" />
|
||||
|
||||
<a class="text-right text-xs" href="https://de.wikipedia.org/wiki/Schlagzeug#/media/Datei:Drum_set.svg" target="_blank">
|
||||
original image by Pbroks13
|
||||
</a>
|
||||
|
||||
- `bd` = **b**ass **d**rum
|
||||
- `sd` = **s**nare **d**rum
|
||||
- `rim` = **rim**shot
|
||||
- `hh` = **h**i**h**at
|
||||
- `oh` = **o**pen **h**ihat
|
||||
- `lt` = **l**ow tom
|
||||
- `mt` = **m**iddle tom
|
||||
- `ht` = **h**igh tom
|
||||
- `rd` = **r**i**d**e cymbal
|
||||
- `rd` = **cr**ash cymbal
|
||||
|
||||
Try out different drum sounds!
|
||||
|
||||
@ -129,29 +140,54 @@ Try adding more sounds to the sequence!
|
||||
|
||||
<MiniRepl client:visible tune={`sound("bd bd hh bd rim bd hh bd")`} punchcard />
|
||||
|
||||
The content of a sequence will be squished into what's called a cycle.
|
||||
The content of a sequence will be squished into what's called a cycle. A cycle is 2s long by default.
|
||||
|
||||
**One way to change the tempo is using `cpm`**
|
||||
**One per cycle with `< .. >`**
|
||||
|
||||
<MiniRepl client:visible tune={`sound("bd bd hh bd rim bd hh bd").cpm(40)`} punchcard />
|
||||
Here is the same sequence, but this time sourrounded with `< .. >` (angle brackets):
|
||||
|
||||
<MiniRepl client:visible tune={`sound("<bd bd hh bd rim bd hh bd>")`} punchcard />
|
||||
|
||||
This will play only one sound per cycle. With these brackets, the tempo doesn't change when we add or remove elements!
|
||||
|
||||
Because this is now very slow, we can speed it up again like this:
|
||||
|
||||
<MiniRepl client:visible tune={`sound("<bd bd hh bd rim bd hh bd>*8")`} punchcard />
|
||||
|
||||
Here, the `*8` means we make the whole thing 8 times faster.
|
||||
|
||||
<Box>
|
||||
|
||||
Wait a minute, isn't this the same as without `< ... >*8`? Why do we need it then?
|
||||
|
||||
That's true, the special thing about this notation is that the tempo won't change when you add or remove elements, try it!
|
||||
|
||||
Try also changing the number at the end to change the tempo!
|
||||
|
||||
</Box>
|
||||
|
||||
**changing the tempo with cpm**
|
||||
|
||||
<MiniRepl client:visible tune={`sound("<bd hh rim hh>*8").cpm(90/4)`} punchcard />
|
||||
|
||||
<Box>
|
||||
|
||||
cpm = cycles per minute
|
||||
|
||||
By default, the tempo is 30 cycles per minute = 1 half cycle per second.
|
||||
By default, the tempo is 30 cycles per minute = 120/4 = 1 cycle every 2 seconds
|
||||
|
||||
In western music terms, you could say the above are 8ths notes at 90bpm in 4/4 time.
|
||||
But don't worry if you don't know these terms, as they are not required to make music with Strudel.
|
||||
|
||||
</Box>
|
||||
|
||||
We will look at other ways to change the tempo later!
|
||||
**Add a rests in a sequence with '-' or '~'**
|
||||
|
||||
**Add a rests in a sequence with '~'**
|
||||
|
||||
<MiniRepl client:visible tune={`sound("bd hh ~ rim ~ bd hh rim")`} punchcard />
|
||||
<MiniRepl client:visible tune={`sound("bd hh - rim - bd hh rim")`} punchcard />
|
||||
|
||||
**Sub-Sequences with [brackets]**
|
||||
|
||||
<MiniRepl client:visible tune={`sound("bd [hh hh] sd [hh bd] bd ~ [hh sd] cp")`} punchcard />
|
||||
<MiniRepl client:visible tune={`sound("bd [hh hh] sd [hh bd] bd - [hh sd] cp")`} punchcard />
|
||||
|
||||
<Box>
|
||||
|
||||
@ -163,7 +199,7 @@ Similar to the whole sequence, the content of a sub-sequence will be squished to
|
||||
|
||||
**Multiplication: Speed things up**
|
||||
|
||||
<MiniRepl client:visible tune={`sound("bd hh*2 rim hh*3 bd [~ hh*2] rim hh*2")`} punchcard />
|
||||
<MiniRepl client:visible tune={`sound("bd hh*2 rim hh*3 bd [- hh*2] rim hh*2")`} punchcard />
|
||||
|
||||
**Multiplication: Speed up subsequences**
|
||||
|
||||
@ -195,7 +231,7 @@ You can go as deep as you want!
|
||||
|
||||
You can use as many commas as you want:
|
||||
|
||||
<MiniRepl client:visible tune={`sound("hh hh hh, bd bd, ~ casio")`} punchcard />
|
||||
<MiniRepl client:visible tune={`sound("hh hh hh, bd bd, - casio")`} punchcard />
|
||||
|
||||
Commas can also be used inside sub-sequences:
|
||||
|
||||
@ -213,9 +249,9 @@ It is quite common that there are many ways to express the same idea.
|
||||
|
||||
<MiniRepl
|
||||
client:visible
|
||||
tune={`sound(\`bd*2, ~ cp,
|
||||
~ ~ ~ oh, hh*4,
|
||||
[~ casio]*2\`)`}
|
||||
tune={`sound(\`bd*2, - cp,
|
||||
- - - oh, hh*4,
|
||||
[- casio]*2\`)`}
|
||||
punchcard
|
||||
/>
|
||||
|
||||
@ -238,7 +274,7 @@ This is what we've leared so far:
|
||||
| ----------------- | -------- | ----------------------------------------------------------------------- |
|
||||
| Sequence | space | <MiniRepl client:visible tune={`sound("bd bd sd hh")`} /> |
|
||||
| Sample Number | :x | <MiniRepl client:visible tune={`sound("hh:0 hh:1 hh:2 hh:3")`} /> |
|
||||
| Rests | ~ | <MiniRepl client:visible tune={`sound("metal ~ jazz jazz:1")`} /> |
|
||||
| Rests | - or ~ | <MiniRepl client:visible tune={`sound("metal - jazz jazz:1")`} /> |
|
||||
| Sub-Sequences | \[\] | <MiniRepl client:visible tune={`sound("bd wind [metal jazz] hh")`} /> |
|
||||
| Sub-Sub-Sequences | \[\[\]\] | <MiniRepl client:visible tune={`sound("bd [metal [jazz [sd cp]]]")`} /> |
|
||||
| Speed up | \* | <MiniRepl client:visible tune={`sound("bd sd*2 cp*3")`} /> |
|
||||
@ -248,9 +284,9 @@ The Mini-Notation is usually used inside some function. These are the functions
|
||||
|
||||
| Name | Description | Example |
|
||||
| ----- | ----------------------------------- | --------------------------------------------------------------------------------- |
|
||||
| sound | plays the sound of the given name | <MiniRepl client:visible tune={`sound("bd sd [~ bd] sd")`} /> |
|
||||
| bank | selects the sound bank | <MiniRepl client:visible tune={`sound("bd sd [~ bd] sd").bank("RolandTR909")`} /> |
|
||||
| cpm | sets the tempo in cycles per minute | <MiniRepl client:visible tune={`sound("bd sd [~ bd] sd").cpm(45)`} /> |
|
||||
| sound | plays the sound of the given name | <MiniRepl client:visible tune={`sound("bd sd [- bd] sd")`} /> |
|
||||
| bank | selects the sound bank | <MiniRepl client:visible tune={`sound("bd sd [- bd] sd").bank("RolandTR909")`} /> |
|
||||
| cpm | sets the tempo in cycles per minute | <MiniRepl client:visible tune={`sound("bd sd [- bd] sd").cpm(45)`} /> |
|
||||
| n | select sample number | <MiniRepl client:visible tune={`n("0 1 4 2 0 6 3 2").sound("jazz")`} /> |
|
||||
|
||||
## Examples
|
||||
@ -266,7 +302,7 @@ The Mini-Notation is usually used inside some function. These are the functions
|
||||
|
||||
**Classic house**
|
||||
|
||||
<MiniRepl client:visible tune={`sound("bd*4, [~ cp]*2, [~ hh]*4").bank("RolandTR909")`} punchcard />
|
||||
<MiniRepl client:visible tune={`sound("bd*4, [- cp]*2, [- hh]*4").bank("RolandTR909")`} punchcard />
|
||||
|
||||
<Box>
|
||||
|
||||
@ -283,7 +319,7 @@ We Will Rock you
|
||||
|
||||
<MiniRepl
|
||||
client:visible
|
||||
tune={`sound("bd sd, ~ ~ ~ hh ~ hh ~ ~, ~ perc ~ perc:1*2")
|
||||
tune={`sound("bd sd, - - - hh - hh - -, - perc - perc:1*2")
|
||||
.bank("RolandCompurhythm1000").cpm(120/2)`}
|
||||
punchcard
|
||||
/>
|
||||
@ -293,10 +329,10 @@ We Will Rock you
|
||||
<MiniRepl
|
||||
client:visible
|
||||
tune={`sound(\`
|
||||
[~ ~ oh ~ ] [~ ~ ~ ~ ] [~ ~ ~ ~ ] [~ ~ ~ ~ ],
|
||||
[hh hh ~ ~ ] [hh ~ hh ~ ] [hh ~ hh ~ ] [hh ~ hh ~ ],
|
||||
[~ ~ ~ ~ ] [cp ~ ~ ~ ] [~ ~ ~ ~ ] [cp ~ ~ ~ ],
|
||||
[bd ~ ~ ~ ] [~ ~ ~ bd] [~ ~ bd ~ ] [~ ~ ~ bd]
|
||||
[- - oh - ] [- - - - ] [- - - - ] [- - - - ],
|
||||
[hh hh - - ] [hh - hh - ] [hh - hh - ] [hh - hh - ],
|
||||
[- - - - ] [cp - - - ] [- - - - ] [cp - - - ],
|
||||
[bd - - - ] [- - - bd] [- - bd - ] [- - - bd]
|
||||
\`).cpm(90/4)`}
|
||||
punchcard
|
||||
/>
|
||||
@ -306,10 +342,10 @@ We Will Rock you
|
||||
<MiniRepl
|
||||
client:visible
|
||||
tune={`sound(\`
|
||||
[~ ~ ~ ~ ] [~ ~ ~ ~ ] [~ ~ ~ ~ ] [~ ~ oh:1 ~ ],
|
||||
[hh hh hh hh] [hh hh hh hh] [hh hh hh hh] [hh hh ~ ~ ],
|
||||
[~ ~ ~ ~ ] [cp ~ ~ ~ ] [~ ~ ~ ~ ] [~ cp ~ ~ ],
|
||||
[bd bd ~ ~ ] [~ ~ bd ~ ] [bd bd ~ bd ] [~ ~ ~ ~ ]
|
||||
[- - - - ] [- - - - ] [- - - - ] [- - oh:1 - ],
|
||||
[hh hh hh hh] [hh hh hh hh] [hh hh hh hh] [hh hh - - ],
|
||||
[- - - - ] [cp - - - ] [- - - - ] [~ cp - - ],
|
||||
[bd bd - - ] [- - bd - ] [bd bd - bd ] [- - - - ]
|
||||
\`).bank("RolandTR808").cpm(88/4)`}
|
||||
punchcard
|
||||
/>
|
||||
@ -319,9 +355,9 @@ We Will Rock you
|
||||
<MiniRepl
|
||||
client:visible
|
||||
tune={`s(\`jazz*2,
|
||||
insect [crow metal] ~ ~,
|
||||
~ space:4 ~ space:1,
|
||||
~ wind\`)
|
||||
insect [crow metal] - -,
|
||||
- space:4 - space:1,
|
||||
- wind\`)
|
||||
.cpm(100/2)`}
|
||||
punchcard
|
||||
/>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user