use labels instead of stacks
This commit is contained in:
parent
c05bbf3422
commit
771eb31d3f
10 changed files with 103 additions and 130 deletions
|
|
@ -1163,10 +1163,8 @@ export const { octave } = registerControl('octave');
|
||||||
* @name orbit
|
* @name orbit
|
||||||
* @param {number | Pattern} number
|
* @param {number | Pattern} number
|
||||||
* @example
|
* @example
|
||||||
* stack(
|
* $: s("hh*6").delay(.5).delaytime(.25).orbit(1)
|
||||||
* s("hh*6").delay(.5).delaytime(.25).orbit(1),
|
* $: s("~ sd ~ sd").delay(.5).delaytime(.125).orbit(2)
|
||||||
* s("~ sd ~ sd").delay(.5).delaytime(.125).orbit(2)
|
|
||||||
* )
|
|
||||||
*/
|
*/
|
||||||
export const { orbit } = registerControl('orbit');
|
export const { orbit } = registerControl('orbit');
|
||||||
// TODO: what is this? not found in tidal doc Answer: gain is limited to maximum of 2. This allows you to go over that
|
// TODO: what is this? not found in tidal doc Answer: gain is limited to maximum of 2. This allows you to go over that
|
||||||
|
|
|
||||||
|
|
@ -90,11 +90,13 @@ src(s0).kaleid(H("<4 5 6>"))
|
||||||
.modulateScale(osc(2,-0.25,1))
|
.modulateScale(osc(2,-0.25,1))
|
||||||
.out()
|
.out()
|
||||||
//
|
//
|
||||||
stack(
|
|
||||||
s("bd*4,[hh:0:<.5 1>]*8,~ rim").bank("RolandTR909").speed(.9),
|
$: s("bd*4,[hh:0:<.5 1>]*8,~ rim").bank("RolandTR909").speed(.9)
|
||||||
note("[<g1!3 <bb1 <f1 d1>>>]*3").s("sawtooth")
|
|
||||||
.room(.75).sometimes(add(note(12))).clip(.3)
|
$: note("[<g1!3 <bb1 <f1 d1>>>]\*3").s("sawtooth")
|
||||||
.lpa(.05).lpenv(-4).lpf(2000).lpq(8).ftype('24db')
|
|
||||||
).fft(4)
|
.room(.75).sometimes(add(note(12))).clip(.3)
|
||||||
.scope({pos:0,smear:.95})`}
|
.lpa(.05).lpenv(-4).lpf(2000).lpq(8).ftype('24db')
|
||||||
|
|
||||||
|
all(x=>x.fft(4).scope({pos:0,smear:.95}))`}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,7 @@ Strudel also supports midi via [webmidi](https://npmjs.com/package/webmidi).
|
||||||
Either connect a midi device or use the IAC Driver (Mac) or Midi Through Port (Linux) for internal midi messages.
|
Either connect a midi device or use the IAC Driver (Mac) or Midi Through Port (Linux) for internal midi messages.
|
||||||
If no outputName is given, it uses the first midi output it finds.
|
If no outputName is given, it uses the first midi output it finds.
|
||||||
|
|
||||||
<MiniRepl
|
<MiniRepl client:idle tune={`chord("<C^7 A7 Dm7 G7>").voicing().midi()`} />
|
||||||
client:idle
|
|
||||||
tune={`stack("<C^7 A7 Dm7 G7>".voicings('lefthand'), "<C3 A2 D3 G2>").note()
|
|
||||||
.midi()`}
|
|
||||||
/>
|
|
||||||
|
|
||||||
In the console, you will see a log of the available MIDI devices as soon as you run the code, e.g. `Midi connected! Using "Midi Through Port-0".`
|
In the console, you will see a log of the available MIDI devices as soon as you run the code, e.g. `Midi connected! Using "Midi Through Port-0".`
|
||||||
|
|
||||||
|
|
@ -45,10 +41,8 @@ But you can also control cc messages separately like this:
|
||||||
|
|
||||||
<MiniRepl
|
<MiniRepl
|
||||||
client:idle
|
client:idle
|
||||||
tune={`stack(
|
tune={`$: note("c a f e").midi()
|
||||||
note("c a f e"),
|
$: ccv(sine.segment(16).slow(4)).ccn(74).midi()`}
|
||||||
ccv(sine.segment(16).slow(4)).ccn(74)
|
|
||||||
).midi()`}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
# SuperDirt API
|
# SuperDirt API
|
||||||
|
|
|
||||||
|
|
@ -268,11 +268,10 @@ With it, you can enter any sample name(s) to query from [freesound.org](https://
|
||||||
<MiniRepl
|
<MiniRepl
|
||||||
client:idle
|
client:idle
|
||||||
tune={`samples('shabda:bass:4,hihat:4,rimshot:2')
|
tune={`samples('shabda:bass:4,hihat:4,rimshot:2')
|
||||||
stack(
|
|
||||||
n("0 1 2 3 0 1 2 3").s('bass'),
|
$: n("0 1 2 3 0 1 2 3").s('bass')
|
||||||
n("0 1*2 2 3*2").s('hihat'),
|
$: n("0 1*2 2 3*2").s('hihat').clip(1)
|
||||||
n("~ 0 ~ 1 ~ 0 0 1").s('rimshot')
|
$: n("~ 0 ~ 1 ~ 0 0 1").s('rimshot')`}
|
||||||
).clip(1)`}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
You can also generate artificial voice samples with any text, in multiple languages.
|
You can also generate artificial voice samples with any text, in multiple languages.
|
||||||
|
|
@ -282,10 +281,9 @@ Note that the language code and the gender parameters are optional and default t
|
||||||
client:idle
|
client:idle
|
||||||
tune={`samples('shabda/speech:the_drum,forever')
|
tune={`samples('shabda/speech:the_drum,forever')
|
||||||
samples('shabda/speech/fr-FR/m:magnifique')
|
samples('shabda/speech/fr-FR/m:magnifique')
|
||||||
stack(
|
|
||||||
s("the_drum*2").chop(16).speed(rand.range(0.85,1.1)),
|
$: s("the_drum*2").chop(16).speed(rand.range(0.85,1.1))
|
||||||
s("forever magnifique").slow(4).late(0.125)
|
$: s("forever magnifique").slow(4).late(0.125)`}
|
||||||
)`}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
# Sampler Effects
|
# Sampler Effects
|
||||||
|
|
|
||||||
|
|
@ -112,29 +112,14 @@ Also, samples are always loaded from a URL rather than from the disk, although [
|
||||||
## Evaluation
|
## Evaluation
|
||||||
|
|
||||||
The Strudel REPL does not support [block based evaluation](https://github.com/tidalcycles/strudel/issues/34) yet.
|
The Strudel REPL does not support [block based evaluation](https://github.com/tidalcycles/strudel/issues/34) yet.
|
||||||
You can use the following "workaround" to create multiple patterns that can be turned on and off:
|
You can use labeled statements and `_` to mute:
|
||||||
|
|
||||||
```
|
<MiniRepl
|
||||||
let a = note("c a f e")
|
client:visible
|
||||||
|
tune={`$: n("[0 .. 8]*8/9").scale("C:minor:pentatonic")
|
||||||
|
|
||||||
let b = s("bd sd")
|
\_$: s("bd\*4").bank('RolandTR909')`}
|
||||||
|
/>
|
||||||
stack(
|
|
||||||
a,
|
|
||||||
// b
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
Alternatively, you could write everything as one `stack` and use `.hush()` to silence a pattern:
|
|
||||||
|
|
||||||
```
|
|
||||||
stack(
|
|
||||||
note("c a f e"),
|
|
||||||
s("bd sd").hush()
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that strudel will always use the last statement in your code as the pattern for querying
|
|
||||||
|
|
||||||
## Tempo
|
## Tempo
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,20 +55,6 @@ Transposes notes inside the scale by the number of steps:
|
||||||
.note()`}
|
.note()`}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
### voicings(range?)
|
|
||||||
|
|
||||||
Turns chord symbols into voicings, using the smoothest voice leading possible:
|
|
||||||
|
|
||||||
<MiniRepl
|
|
||||||
client:only="react"
|
|
||||||
tune={`stack(
|
|
||||||
"<C^7 A7 Dm7 G7>".voicings('lefthand'),
|
|
||||||
"<C3 A2 D3 G2>"
|
|
||||||
).note()`}
|
|
||||||
/>
|
|
||||||
|
|
||||||
Note: This function might be removed, as `voicing` (without s) is a newer implementation.
|
|
||||||
|
|
||||||
### rootNotes(octave = 2)
|
### rootNotes(octave = 2)
|
||||||
|
|
||||||
Turns chord symbols into root notes of chords in given octave.
|
Turns chord symbols into root notes of chords in given octave.
|
||||||
|
|
|
||||||
|
|
@ -60,11 +60,10 @@ We will learn how to automate with waves later...
|
||||||
|
|
||||||
<MiniRepl
|
<MiniRepl
|
||||||
client:visible
|
client:visible
|
||||||
tune={`stack(
|
tune={`$: sound("hh*16").gain("[.25 1]*4")
|
||||||
sound("hh*16").gain("[.25 1]*4"),
|
|
||||||
sound("bd*4,[~ sd:1]*2")
|
$: sound("bd*4,[~ sd:1]*2")`}
|
||||||
) `}
|
punchcard
|
||||||
punchcard
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Box>
|
<Box>
|
||||||
|
|
@ -76,31 +75,21 @@ Rhythm is all about dynamics!
|
||||||
|
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
**stacks within stacks**
|
|
||||||
|
|
||||||
Let's combine all of the above into a little tune:
|
Let's combine all of the above into a little tune:
|
||||||
|
|
||||||
<MiniRepl
|
<MiniRepl
|
||||||
client:visible
|
client:visible
|
||||||
tune={`stack(
|
tune={`$: sound("hh*8").gain("[.25 1]*4")
|
||||||
stack(
|
|
||||||
sound("hh*8").gain("[.25 1]*4"),
|
$: sound("bd*4,[~ sd:1]*2")
|
||||||
sound("bd*4,[~ sd:1]*2")
|
|
||||||
),
|
$: note("<[c2 c3]*4 [bb1 bb2]*4 [f2 f3]*4 [eb2 eb3]*4>")
|
||||||
note("<[c2 c3]*4 [bb1 bb2]*4 [f2 f3]*4 [eb2 eb3]*4>")
|
.sound("sawtooth").lpf("200 1000 200 1000")
|
||||||
.sound("sawtooth").lpf("200 1000 200 1000"),
|
|
||||||
note("<[c3,g3,e4] [bb2,f3,d4] [a2,f3,c4] [bb2,g3,eb4]>")
|
$: note("<[c3,g3,e4] [bb2,f3,d4] [a2,f3,c4] [bb2,g3,eb4]>")
|
||||||
.sound("sawtooth").vowel("<a e i o>")
|
.sound("sawtooth").vowel("<a e i o>")`}
|
||||||
)`}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Box>
|
|
||||||
|
|
||||||
Try to identify the individual parts of the stacks, pay attention to where the commas are.
|
|
||||||
The 3 parts (drums, bassline, chords) are exactly as earlier, just stacked together, separated by comma.
|
|
||||||
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
**shape the sound with an adsr envelope**
|
**shape the sound with an adsr envelope**
|
||||||
|
|
||||||
<MiniRepl
|
<MiniRepl
|
||||||
|
|
@ -151,11 +140,10 @@ Can you guess what they do?
|
||||||
|
|
||||||
<MiniRepl
|
<MiniRepl
|
||||||
client:visible
|
client:visible
|
||||||
tune={`stack(
|
tune={`$: note("[~ [<[d3,a3,f4]!2 [d3,bb3,g4]!2> ~]]*2")
|
||||||
note("[~ [<[d3,a3,f4]!2 [d3,bb3,g4]!2> ~]]*2")
|
.sound("gm_electric_guitar_muted").delay(.5)
|
||||||
.sound("gm_electric_guitar_muted"),
|
|
||||||
sound("bd rim").bank("RolandTR707")
|
$: sound("bd rim").bank("RolandTR707").delay(".5")`}
|
||||||
).delay(".5")`}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Box>
|
<Box>
|
||||||
|
|
@ -199,31 +187,32 @@ Add a delay too!
|
||||||
|
|
||||||
<MiniRepl
|
<MiniRepl
|
||||||
client:visible
|
client:visible
|
||||||
tune={`stack(
|
tune={`$: note("[~ [<[d3,a3,f4]!2 [d3,bb3,g4]!2> ~]]*2")
|
||||||
note("[~ [<[d3,a3,f4]!2 [d3,bb3,g4]!2> ~]]*2")
|
.sound("gm_electric_guitar_muted").delay(.5)
|
||||||
.sound("gm_electric_guitar_muted").delay(.5),
|
|
||||||
sound("bd rim").bank("RolandTR707").delay(.5),
|
$: sound("bd rim").bank("RolandTR707").delay(.5)
|
||||||
n("<4 [3@3 4] [<2 0> ~@16] ~>")
|
|
||||||
|
$: n("<4 [3@3 4] [<2 0> ~@16] ~>")
|
||||||
.scale("D4:minor").sound("gm_accordion:2")
|
.scale("D4:minor").sound("gm_accordion:2")
|
||||||
.room(2).gain(.5)
|
.room(2).gain(.5)`}
|
||||||
)`}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
Let's add a bass to make this complete:
|
Let's add a bass to make this complete:
|
||||||
|
|
||||||
<MiniRepl
|
<MiniRepl
|
||||||
client:visible
|
client:visible
|
||||||
tune={`stack(
|
tune={`$: note("[~ [<[d3,a3,f4]!2 [d3,bb3,g4]!2> ~]]*2")
|
||||||
note("[~ [<[d3,a3,f4]!2 [d3,bb3,g4]!2> ~]]*2")
|
.sound("gm_electric_guitar_muted").delay(.5)
|
||||||
.sound("gm_electric_guitar_muted").delay(.5),
|
|
||||||
sound("bd rim").bank("RolandTR707").delay(.5),
|
$: sound("bd rim").bank("RolandTR707").delay(.5)
|
||||||
n("<4 [3@3 4] [<2 0> ~@16] ~>")
|
|
||||||
|
$: n("<4 [3@3 4] [<2 0> ~@16] ~>")
|
||||||
.scale("D4:minor").sound("gm_accordion:2")
|
.scale("D4:minor").sound("gm_accordion:2")
|
||||||
.room(2).gain(.4),
|
.room(2).gain(.4)
|
||||||
n("[0 [~ 0] 4 [3 2] [0 ~] [0 ~] <0 2> ~]/2")
|
|
||||||
|
$: n("[0 [~ 0] 4 [3 2] [0 ~] [0 ~] <0 2> ~]/2")
|
||||||
.scale("D2:minor")
|
.scale("D2:minor")
|
||||||
.sound("sawtooth,triangle").lpf(800)
|
.sound("sawtooth,triangle").lpf(800)`}
|
||||||
)`}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Box>
|
<Box>
|
||||||
|
|
|
||||||
|
|
@ -319,6 +319,7 @@ New functions:
|
||||||
| note | set pitch as number or letter | <MiniRepl client:visible tune={`note("b g e c").sound("piano")`} /> |
|
| note | set pitch as number or letter | <MiniRepl client:visible tune={`note("b g e c").sound("piano")`} /> |
|
||||||
| scale | interpret `n` as scale degree | <MiniRepl client:visible tune={`n("6 4 2 0").scale("C:minor").sound("piano")`} /> |
|
| scale | interpret `n` as scale degree | <MiniRepl client:visible tune={`n("6 4 2 0").scale("C:minor").sound("piano")`} /> |
|
||||||
| stack | play patterns in parallel (read on) | <MiniRepl client:visible tune={`stack(s("bd sd"),note("c eb g"))`} /> |
|
| stack | play patterns in parallel (read on) | <MiniRepl client:visible tune={`stack(s("bd sd"),note("c eb g"))`} /> |
|
||||||
|
| $: | play patterns in parallel | <MiniRepl client:visible tune={'$: s("bd sd")\n$: note("c eb g")'} /> |
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
|
@ -377,4 +378,29 @@ It's called `stack` 😙
|
||||||
)`}
|
)`}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
Since Strudel 1.1.0, there is another, simpler way to write multiple patterns in parallel. Just write `$:` before every part:
|
||||||
|
|
||||||
|
<MiniRepl
|
||||||
|
client:visible
|
||||||
|
tune={`$: note("<[c2 c3]*4 [bb1 bb2]*4 [f2 f3]*4 [eb2 eb3]*4>")
|
||||||
|
.sound("gm_synth_bass_1").lpf(800)
|
||||||
|
|
||||||
|
$: n(\`<
|
||||||
|
[~ 0] 2 [0 2] [~ 2]
|
||||||
|
[~ 0] 1 [0 1] [~ 1]
|
||||||
|
[~ 0] 3 [0 3] [~ 3]
|
||||||
|
[~ 0] 2 [0 2] [~ 2]
|
||||||
|
>*4\`).scale("C4:minor")
|
||||||
|
.sound("gm_synth_strings_1")
|
||||||
|
|
||||||
|
$: sound("bd*4, [~ <sd cp>]*2, [~ hh]*4")
|
||||||
|
.bank("RolandTR909")`}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Box>
|
||||||
|
|
||||||
|
Try changing `$` to `_$` to mute a part!
|
||||||
|
|
||||||
|
</Box>
|
||||||
|
|
||||||
This is starting to sound like actual music! We have sounds, we have notes, now the last piece of the puzzle is missing: [effects](/workshop/first-effects)
|
This is starting to sound like actual music! We have sounds, we have notes, now the last piece of the puzzle is missing: [effects](/workshop/first-effects)
|
||||||
|
|
|
||||||
|
|
@ -25,20 +25,16 @@ This is the same as:
|
||||||
|
|
||||||
<MiniRepl
|
<MiniRepl
|
||||||
client:visible
|
client:visible
|
||||||
tune={`stack(
|
tune={`$: n("0 1 [4 3] 2 0 2 [~ 3] 4").sound("jazz").pan(0)
|
||||||
n("0 1 [4 3] 2 0 2 [~ 3] 4").sound("jazz").pan(0),
|
$: n("0 1 [4 3] 2 0 2 [~ 3] 4").sound("jazz").pan(1).rev()`}
|
||||||
n("0 1 [4 3] 2 0 2 [~ 3] 4").sound("jazz").pan(1).rev()
|
|
||||||
)`}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
Let's visualize what happens here:
|
Let's visualize what happens here:
|
||||||
|
|
||||||
<MiniRepl
|
<MiniRepl
|
||||||
client:visible
|
client:visible
|
||||||
tune={`stack(
|
tune={`$: n("0 1 [4 3] 2 0 2 [~ 3] 4").sound("jazz").pan(0).color("cyan")
|
||||||
n("0 1 [4 3] 2 0 2 [~ 3] 4").sound("jazz").pan(0).color("cyan"),
|
$: n("0 1 [4 3] 2 0 2 [~ 3] 4").sound("jazz").pan(1).color("magenta").rev()`}
|
||||||
n("0 1 [4 3] 2 0 2 [~ 3] 4").sound("jazz").pan(1).color("magenta").rev()
|
|
||||||
)`}
|
|
||||||
punchcard
|
punchcard
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
@ -56,11 +52,9 @@ This is like doing
|
||||||
|
|
||||||
<MiniRepl
|
<MiniRepl
|
||||||
client:visible
|
client:visible
|
||||||
tune={`stack(
|
tune={`$: note("c2, eb3 g3 [bb3 c4]").s("piano").slow(0.5).color('cyan')
|
||||||
note("c2, eb3 g3 [bb3 c4]").s("piano").slow(0.5).color('cyan'),
|
$: note("c2, eb3 g3 [bb3 c4]").s("piano").slow(1).color('magenta')
|
||||||
note("c2, eb3 g3 [bb3 c4]").s("piano").slow(1).color('magenta'),
|
$: note("c2, eb3 g3 [bb3 c4]").s("piano").slow(1.5).color('yellow')`}
|
||||||
note("c2, eb3 g3 [bb3 c4]").s("piano").slow(1.5).color('yellow')
|
|
||||||
)`}
|
|
||||||
punchcard
|
punchcard
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
@ -110,17 +104,17 @@ We can add as often as we like:
|
||||||
|
|
||||||
<MiniRepl
|
<MiniRepl
|
||||||
client:visible
|
client:visible
|
||||||
tune={`stack(
|
tune={`$: n("0 [2 4] <3 5> [~ <4 1>]".add("<0 [0,2,4]>"))
|
||||||
n("0 [2 4] <3 5> [~ <4 1>]".add("<0 [0,2,4]>"))
|
|
||||||
.scale("C5:minor")
|
.scale("C5:minor")
|
||||||
.sound("gm_xylophone")
|
.sound("gm_xylophone")
|
||||||
.room(.4).delay(.125),
|
.room(.4).delay(.125)
|
||||||
note("c2 [eb3,g3]".add("<0 <1 -1>>"))
|
|
||||||
|
$: note("c2 [eb3,g3]".add("<0 <1 -1>>"))
|
||||||
.adsr("[.1 0]:.2:[1 0]")
|
.adsr("[.1 0]:.2:[1 0]")
|
||||||
.sound("gm_acoustic_bass")
|
.sound("gm_acoustic_bass")
|
||||||
.room(.5),
|
.room(.5)
|
||||||
n("0 1 [2 3] 2").sound("jazz").jux(rev)
|
|
||||||
)`}
|
$: n("0 1 [2 3] 2").sound("jazz").jux(rev)`}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
**ply**
|
**ply**
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ This page is just a listing of all functions covered in the workshop!
|
||||||
| note | set pitch as number or letter | <MiniRepl client:visible tune={`note("b g e c").sound("piano")`} /> |
|
| note | set pitch as number or letter | <MiniRepl client:visible tune={`note("b g e c").sound("piano")`} /> |
|
||||||
| n + scale | set note in scale | <MiniRepl client:visible tune={`n("6 4 2 0").scale("C:minor").sound("piano")`} /> |
|
| n + scale | set note in scale | <MiniRepl client:visible tune={`n("6 4 2 0").scale("C:minor").sound("piano")`} /> |
|
||||||
| stack | play patterns in parallel | <MiniRepl client:visible tune={`stack(s("bd sd"),note("c eb g"))`} /> |
|
| stack | play patterns in parallel | <MiniRepl client:visible tune={`stack(s("bd sd"),note("c eb g"))`} /> |
|
||||||
|
| $: | play patterns in parallel | <MiniRepl client:visible tune={'$: s("bd sd")\n$: note("c eb g")'} /> |
|
||||||
|
|
||||||
## Audio Effects
|
## Audio Effects
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue