strudel-samples.txt
A presentation on loading and manipulating samples with strudel.
Table of Contents
Samples Redux
strudel has lots of awesome ways to modulate, loop, chop,
and process samples; kind of like having a Digitakt in your browser.
Playing samples
Playing a sample is the same as playing a sound; in fact, most sounds we have already played with are samples:
$: sound("xylophone_hard_ff")
Speed
speed controls the rate of playback, altering the pitch:
groove: "bd!2 [~ bd]!2".swing(2).speed("1 0.75").s()
Negative speeds reverse sample playback:
groove: "sd!2 [~ sd]!2".speed("1 -1").swing(2).s()
Cut
cut creates cut groups; only 1 sample can play at a time in any cut group.
melody: "piano*4".s().cut(1)
drums: "bd*4".s().late(1/16).cut("1 0")
Sample Banks
All the percussion we have used thus far are samples.
We can choose different sample banks to pull samples from:
groove: stack("bd!2 [~ bd]!2".swing(2), "hh*8", "~ ~ cp ~").s()
.bank("RolandTR808")Try changing the sample bank:
bank | description |
|---|---|
"RolandTR808" | Iconic drum machine of 80s hip-hop sounds |
"RolandTR909" | Popular in techno and house |
"BossDR220" | Simplified Roland TR707 |
"OberheimDMX" | Influential 1980s drum machine |
"LinnDrum" | 1980s drum machine targeting realistic sound |
The bank function works by putting the name of the sample bank with an _
at the front of sample names.
bank: s("bd*2").bank("RolandTR808")
explicit: s("RolandTR808_bd*2").late(1/4)Find sample banks in the drum machine
tab of the sounds
window.
Not all sample banks support the same percussion sounds!
Velocity
Changing the velocity of a sample changes its loudness.
d1: "bd*4".s().bank("RolandTR909")
.velocity(range(0.6, 1, sine))
Begin & End
Strudel can start and end samples in different spots:
$: n("0*2").s("numbers").late(1/16).begin("0 0.2").cut(0)
$: "<bd sd>*8".s().end("0.1 0.5 0.75 1").slow(2)
Filter
Strudel also supports filters:
$: "sd*8".s().bank("RolandTR909")
.hpf(range(0, 2000, sine).slow(8))
.hpq("<0 0 10>") // Resonance
.hpattack("<0 0.1 1 4 -4>".slow(2)) // Envelope attack| Filter Type | Description |
|---|---|
hpf | high-pass filter |
lpf | low-pass filter |
bpf | band-pass filter |
djf | dj-filter (try different values from 0 to 1.0) |
Loading Samples
Strudel can load samples with a custom name from a URL:
samples({ conga: [ 'https://glfmn.io/samples/menegass-conga-7.wav' ]});
$: "conga*2".s()
Variations
Samples can have variations; 2 ways to select the variations:
- Pass a pattern of sample indices into the
nfunction - Append the index to the sample name with
:
samples({
conga: [
'https://glfmn.io/samples/menegass-conga-7.wav',
// CC-BY 4.0: https://freesound.org/people/MrRentAPercussionist/sounds/455509/
'https://glfmn.io/samples/mrrentapercussionist-congas-muted-slap.wav'
]
});
$: cat("conga:<0 1>*2".s(), "conga*2".s().n("0 1"))
Sample Packs
One can make sample packs in strudel using a special strudel.json file.
{
"_base": "https://glfmn.io/samples/",
"conga": [ "menegass-conga-7.wav", "mrrentapercussionist-congas-muted-slap.wav" ],
"tumbao": [ "stomachache-bongopattern145bpm" ],
"train": [ "nnus_train_whistle1.wav" ]
}_base- A URL that gets added to the beginning of every other URL in the file.
Github
Strudel has a special shorthand from loading samples from github repositories.
samples('github:path/to/repo');Longer samples
By default, samples play at normal speed until the end. For long samples, this
causes chaos.
Overlap
Try playing this sample:
samples({
tumbao: ['https://glfmn.io/samples/stomachache-bongopattern145bpm.wav']
});
$: "tumbao".s()
cut groups can mitigate the chaos. Try adding .cut(1).
Slow
We can give more space for the sample to play out with slow:
samples({
tumbao: ['https://glfmn.io/samples/stomachache-bongopattern145bpm.wav']
});
$: "tumbao".s().cut(1).slow(2)
Speed
We can speed up the sample to hear more of it:
samples({
tumbao: ['https://glfmn.io/samples/stomachache-bongopattern145bpm.wav']
});
$: "tumbao".s().cut(1).slow(2).speed(1.25)
setcps
We can even try changing strudels tempo:
samples({
tumbao: ['https://glfmn.io/samples/stomachache-bongopattern145bpm.wav']
});
setcps(1/2);
$: "tumbao".s().cut(1).slow(2).speed(1.25)
setcps sets cycles-per-second. A lower cps results in a faster tempo.
We can use a formula to convert bpm to cps:
const bpm = 120;
setcps(bpm/60/4);
LoopAt
loopAt speeds up the sample so that it loops perfectly in n cycles.
samples({
tumbao: ['https://glfmn.io/samples/stomachache-bongopattern145bpm.wav']
});
setcps(125/60/4)
$: "tumbao".s().loopAt(5)
Combining knowledge of sample length and strudel's tempo is key!
fit makes the pattern perfectly fit its event duration:
$: n("<0 [0 1]>").s("numbers").end("<1!2 0.5>/2").fit()
Chopping samples
Strudel has lots of fun and gnarly ways of chopping up samples and making them feel new again.
Breakbeats!
But first, let's get some break beats :)
samples('github:yaxu/clean-breaks');
setcps(120/60/4)
$: s("amen").loopAt(4)
Chop
chop seamlessly splits the sample into multiple parts.
samples('github:yaxu/clean-breaks');
setcps(144/60/4)
$: s("amen").chop(8).color("<blue red>").loopAt(4)
._punchcard({ labels: 1 })
chop + more
Once the sample is chopped, we can start to transform it with patterns:
samples('github:yaxu/clean-breaks');
setcps(120/60/4);
$: s("groove").chop(32).loopAt(2)
.velocity(sine.range(0.5, 1).fast(2))
.mul(speed("0.75 1.5 0.9 1"))
._punchcard({ labels: 1 })
striate
Instead of chopping, we can striate:
$: s("numbers:0 numbers:1 numbers:2 numbers:3").cut(1)
.color("red white purple brown")
.every(2, striate(4))
._punchcard({ labels: 1 })
Repeats the pattern n times, but only playing the 1st nth of the sample the
first time, the 2nd nth the next time, and so on.
Jam time
samples('github:yaxu/clean-breaks');
// Downtempo
setcps(80/60/4);
$: s("amen").loopAt(4).chop(32).gain(0.8)