Samplers
A sampler plays back recorded audio — a kick drum, a piano note, a vocal
chop. Resonon ships with a built-in sample engine and two flavours of sampler.
A Sampler is a drum machine: each name in your pattern triggers a different
one-shot sample. A SamplerMelodic is a pitched instrument: it takes a recorded
note and transposes it across the keyboard so you can play melodies.
Both live in the std/instruments module, alongside Kit, which loads a folder
of samples:
use "std/instruments" { Sampler, SamplerMelodic, Kit };Here’s the drum sampler from the previous chapter, start to finish:
use "std/instruments" { Sampler, Kit };
let drums = AudioTrack("drums");drums.instrument(Sampler(Kit("CR-78")));
drums << [bd sd bd sd];
PLAY;Kit("CR-78") names the built-in CR-78 kit and Sampler(...) describes an
instrument built from it; instrument is what puts it on the track and makes the
handle live. The pattern triggers samples by name. Reach into a sampler after
that line, never before — see
A constructor is a description.
Sample Names
Section titled “Sample Names”The names in [bd sd bd sd] aren’t keywords — they’re the sample slots of the
loaded kit. The CR-78 names follow its original drum machine: bd is the bass
drum, sd the snare, hh the hi-hat, cy the cymbal, cp the clap, rs the
rimshot, cb the cowbell. There are more — bongos, claves, maracas, a tambourine
— enough to write a full groove from one kit:
use "std/instruments" { Sampler, Kit };
let drums = AudioTrack("drums");drums.instrument(Sampler(Kit("CR-78")));
drums << [bd cp sd cp];
PLAY;Not sure what a kit contains? show() prints its full sample table to the
console:
use "std/instruments" { Sampler, Kit };
show(Kit("CR-78"));Three kits come bundled: CR-78 and TR-808 for drums, and keys for
melodic sampling. You can also load your own — a folder of .wav files under
kits/, optionally with a kit.toml describing the sample-to-note mapping.
MIDI Numbers
Section titled “MIDI Numbers”Every slot is mapped to a MIDI note, so you can trigger samples by number instead
of name — handy when you think in note numbers or drive a GM-style kit. In the
CR-78, 36 is the bass drum, 38 the snare, 42 the hi-hat. Names and numbers
mix freely in one pattern:
use "std/instruments" { Sampler, Kit };
let drums = AudioTrack("drums");drums.instrument(Sampler(Kit("CR-78")));
drums << [36 42 38 42]; // kick, hat, snare, hatdrums << [bd 42 sd 42]; // mixed names and numbers
PLAY;Layering & Subdivision
Section titled “Layering & Subdivision”A comma stacks patterns into parallel layers that play at once — kicks, a snare backbeat, and a running hi-hat, all in one bar:
use "std/instruments" { Sampler, Kit };
let drums = AudioTrack("drums");drums.instrument(Sampler(Kit("CR-78")));
drums << [bd _ bd _, _ sd _ sd, hh*8];
PLAY;The _ is a rest. Nesting [...] inside a step subdivides it, so you can pack a
drum roll into a single beat: [[bd bd] sd bd sd]. These are all mini-notation
features — the Patterns chapters go through them
properly.
Sample Methods
Section titled “Sample Methods”Individual hits can be shaped right in the pattern. Attach a method to a sample name and only that hit changes:
.vel(n)sets velocity — how hard the hit lands,0to1.1.0is full; lower values are softer, good for ghost notes..pitch(semitones)transposes the sample up or down..pan(position)places the hit in the stereo field,-1left to1right..gain(n)scales the hit’s level,1.0unchanged. This is where you go past full — velocity stops at1.
use "std/instruments" { Sampler, Kit };
let drums = AudioTrack("drums");drums.instrument(Sampler(Kit("CR-78")));
drums << [bd.vel(1.0) sd.vel(0.4) bd.vel(1.0) sd.vel(0.4)]; // dynamicsdrums << [bd bd.pitch(5) bd bd.pitch(-5)]; // pitch movesdrums << [hh.pan(-0.3) hh.pan(0.3) hh.pan(-0.3) hh.pan(0.3)]; // stereo hats
PLAY;Each one shapes only the voice that hit starts, so the pad keeps its own settings for every other hit.
Chain them to combine — a loud, slightly detuned kick panned left:
use "std/instruments" { Sampler, Kit };
let drums = AudioTrack("drums");drums.instrument(Sampler(Kit("CR-78")));
drums << [bd.gain(1.4).pitch(-2).pan(-0.5) sd.vel(0.5).pitch(2)];
PLAY;Melodic Sampling
Section titled “Melodic Sampling”For pitched material — bass, keys, pads — reach for SamplerMelodic. It maps a
recorded sample across the keyboard, so note names in a pattern come out as a
melody. The bundled keys kit is a good place to start:
use "std/instruments" { SamplerMelodic, Kit };
let lead = AudioTrack("lead");lead.instrument(SamplerMelodic(Kit("keys")));
lead << [C4 E4 G4 C5];
PLAY;SamplerMelodic(Kit(...)) is a ready-to-play preset: it loads the kit’s
default_sample before the sampler can be placed on a track. A kit containing
only one sample may omit that field because the choice is unambiguous. Use
SamplerMelodic() when you deliberately want an empty device, then choose
content later with .load_kit() or .load_sample().
Loading a different sample is explicit and replaces the preset selection:
use "std/instruments" { SamplerMelodic, Kit };
let keys = SamplerMelodic(Kit("keys"));keys.load_sample("sound2");Missing media, a missing root note, or an ambiguous multi-sample kit is an error at load time rather than a sampler that accepts notes but stays silent.
The same per-hit methods work on melodic notes. On a melodic sampler,
.pitch(n) is a relative offset from the note you played: C4.pitch(12) sounds
at C5, while E4.pitch(-12) sounds at E3. It composes with the sampler’s
root-note tracking rather than replacing it. Gain and pan likewise shape only
that note’s voice:
use "std/instruments" { SamplerMelodic, Kit };
let lead = AudioTrack("lead");lead.instrument(SamplerMelodic(Kit("keys")));
lead << [C4 C4.pitch(12) C4.gain(0.5) C4.pan(-0.5)];
PLAY;Note names, octaves, chords, and rests all behave as they do for drums — a comma
still stacks voices, so [C4 E4 G4, D4 F4 A4] plays two chords in sequence.
Envelope Shaping
Section titled “Envelope Shaping”A melodic sampler has an amplitude envelope — attack, decay, sustain, and
release — that decides how each note swells and fades. Set it with .envelope,
with all three time values in milliseconds:
use "std/instruments" { SamplerMelodic, Kit };
let lead = AudioTrack("lead");let keys = SamplerMelodic(Kit("keys"));lead.instrument(keys);
keys.envelope(10, 100, 1.0, 200); // attack, decay, sustain, releaselead << [C3 E3 G3 C4];
PLAY;keys is the handle to the sampler on that track, and lead.instrument(keys)
comes first for a reason: that line is what builds it, and .envelope(...) shapes
what it built.
A quick attack and short release give a plucky, percussive note; a slow attack and long release turn the same sample into a swelling pad.
Per-Sample Control
Section titled “Per-Sample Control”Pattern methods like .vel() shape one hit at a time. To change a sample for
every hit — its overall gain, pan, envelope, slice points or reverse — reach
into the sampler’s slot and set a parameter. Those belong to the pad, not to a
single hit, and a per-hit .pan() or .gain() sits on top of whatever the slot
says:
use "std/instruments" { Sampler, Kit };
let drums = AudioTrack("drums");let kit = Sampler(Kit("CR-78"));drums.instrument(kit);
kit.slot("bd").param("gain") << 0.8; // every kick, a touch quieterdrums << [bd sd bd sd];
PLAY;Same order again: .instrument() first, then reach into a slot. kit.slot("bd")
names something inside a live sampler, so the sampler has to be on the track
before you can name it.
Because that’s the same << you use for track volume, a slot parameter can take
a moving signal too — auto-panning a hi-hat, pulsing a kick — which the
Signals & Automation chapter covers. The
sampler can also remap samples to new notes and assign choke groups (so an
open hi-hat cuts off a closed one); when you need them, those live on the same
Sampler value.
Next Steps
Section titled “Next Steps”You can load kits, write grooves, sample melodies, and shape individual hits. Next, run a track through effects.
- Effects — delays, filters, and reverb on a track
- A constructor is a description
— why the constructor line and the
.instrument()line do different jobs - Signals & Automation — move parameters
over time with
<< - Patterns — the mini-notation behind every pattern you’ve written here