Sampler & Sample
Sampling in Resonon has three layers. A Kit is metadata: it describes a folder of WAV files and their note mapping. A Sampler (drums) or SamplerMelodic (pitched) is an instrument that loads a kit and plays on a track. A Sample is a single hit inside a pattern — bd, sd — that you can transform per-event with methods like .vel() and .pitch().
The constructors live in the standard library: use "std/instruments" { Sampler, SamplerMelodic, Kit };. Most methods return their receiver, so calls chain freely.
| Kit method | Returns | Meaning |
|---|---|---|
samples() | Array | Sample names in the kit |
sample_info() | Array | [name, note, file] rows, sorted by note |
name() | String | Kit display name |
mode() | String | "oneshot" or "melodic" |
author() | String | Author from kit.toml, or "" |
info() | Nul | Print a formatted kit table |
| Sampler (drum) method | Returns | Meaning |
|---|---|---|
samples() | Array | Loaded sample names |
sample_info() | Array | [name, note, file] rows, sorted by note |
note_for(name) | Number | MIDI note a sample is mapped to |
name() | String | Sampler name (= kit name) |
get(name) | Sample | Extract a standalone Sample copy |
slot(name_or_note) | DrumSampleRef | Handle to a live sample slot |
set_note(name, note) | Sampler | Remap a sample to a new MIDI note |
choke_group(id, names) | Sampler | Samples that cut each other off |
load_kit(kit) | Sampler | Swap in a different kit |
param(path) | ParamRef | Modulatable parameter handle |
param_get(path) | Number | Read a parameter value |
param_set(path, value) | Sampler | Set a parameter (native range) |
param_set_norm(path, value) | Sampler | Set a parameter (normalized 0–1) |
params(filter?) | Nul | Print available parameters |
| DrumSampleRef method | Returns | Meaning |
|---|---|---|
param(name) | ParamRef | Modulatable slot parameter handle |
param_get(name) | Number | Read a slot parameter |
param_set(name, value) | DrumSampleRef | Set a slot parameter |
params(filter?) | Nul | Print slot parameters |
envelope(a, d, s, r) | DrumSampleRef | Set ADSR (milliseconds, sustain 0–1) |
name() | String | Slot’s sample name |
note() | Number | Slot’s MIDI note |
| SamplerMelodic method | Returns | Meaning |
|---|---|---|
load_sample(name, root?) | SamplerMelodic | Load a sample by name |
root(note) | SamplerMelodic | Override the root note |
envelope(a, d, s, r) | SamplerMelodic | Set ADSR (milliseconds, sustain 0–1) |
set_loop(start, end) | SamplerMelodic | Loop points in seconds |
set_loop_normalized(start, end) | SamplerMelodic | Loop points 0–1; reversed = ping-pong |
samples() / sample_info() / root_for(name) | Array / Array / Number | Inspection |
get(name) | Sample | Extract a standalone Sample copy |
load_kit(kit) | SamplerMelodic | Swap in a different kit |
param(path) / param_get / param_set / param_set_norm / params(filter?) | — | Parameter access (as drum sampler) |
| Sample method (in patterns) | Returns | Meaning |
|---|---|---|
vel(v) | Sample | Velocity, 0.0 and up |
pitch(semitones) | Sample | Pitch shift in semitones |
pan(position) | Sample | Stereo position, -1.0 to 1.0 |
slice(start, end) | Sample | Play a region, 0.0–1.0 normalized |
reverse() | Sample | Play backwards |
Kit(name?)
Section titled “Kit(name?)”Load kit metadata by name. Without an argument, loads the built-in "CR-78". Kits are looked up in your project’s kits/ folder, in kit paths from your configuration, and in installed packages (qualified as "package/kit"). A folder without a kit.toml works too — every WAV inside is auto-detected.
use "std/instruments" { Kit };
let kit = Kit("CR-78");PRINT kit.name(); // "CR-78"PRINT kit.mode(); // "oneshot"PRINT kit.samples(); // sample nameslet custom = Kit("mykit"); // kits/mykit/ in your projectlet packaged = Kit("drumlib/808"); // kit from an installed packagesamples() / sample_info() / name() / mode() / author() / info()
Section titled “samples() / sample_info() / name() / mode() / author() / info()”Inspection getters. samples() returns the sample names; sample_info() returns [name, note, file] rows sorted by MIDI note; mode() is "oneshot" (drums) or "melodic" (pitched); info() prints a formatted table.
for entry in kit.sample_info() { PRINT f"{entry[0]} note={entry[1]}";}PRINT kit.author();kit.info();Sampler (Drums)
Section titled “Sampler (Drums)”Sampler(kit?)
Section titled “Sampler(kit?)”Create a drum sampler instrument from a Kit. One-shot playback with a 64-voice pool shared across all samples; when the pool is full, the quietest releasing voice is stolen first. Without an argument, creates an empty sampler — load a kit later with load_kit(). Passing a string is an error: wrap it as Sampler(Kit("name")).
use "std/instruments" { Sampler, Kit };use "std/signals" { Sine };
let kit = Sampler(Kit("CR-78"));let drums = AudioTrack("drums");drums.load_instrument(kit);drums << [bd sd bd sd];samples() / sample_info() / note_for(name) / name()
Section titled “samples() / sample_info() / note_for(name) / name()”Inspection mirrors the Kit getters, but reflects the sampler’s live state (after set_note() or load_kit()). note_for() returns the MIDI note a sample name is mapped to — patterns accept either form: [bd 42 sd 42].
PRINT kit.samples();PRINT kit.note_for("bd"); // 36PRINT kit.name(); // "CR-78"get(name)
Section titled “get(name)”Extract a sample as a standalone Sample value — an independent copy of the audio data, unlike slot(), which controls the live plugin slot. The result supports all sample methods.
let kick = kit.get("bd");let reversed = kick.reverse().pitch(-5);set_note(name, note)
Section titled “set_note(name, note)”Remap a sample to a different MIDI note. Accepts a note name ("C2") or number. Returns the sampler, so remappings chain.
kit.set_note("bd", 60).set_note("sd", "D4");kit.set_note("bd", 36).set_note("sd", 38); // restorechoke_group(id, names)
Section titled “choke_group(id, names)”Put samples into a choke group (id 1–255): triggering any member releases the others’ voices — the classic closed-hat-cuts-open-hat behavior. Calls accumulate; groups are reset when a new kit is loaded.
kit.choke_group(1, #["hh", "cy"]);drums << [cy _ _ _ hh _ _ _]; // hh chokes the ringing cymbalload_kit(kit)
Section titled “load_kit(kit)”Replace all samples with another kit, keeping the same plugin instance (and its place on the track).
kit.load_kit(Kit("TR-808"));drums << [bd sd bd sd];param(path) / param_get(path) / param_set(path, value) / param_set_norm(path, value) / params(filter?)
Section titled “param(path) / param_get(path) / param_set(path, value) / param_set_norm(path, value) / params(filter?)”Path-based parameter access using slot_N/name paths, e.g. "slot_0/gain". param() returns a modulatable handle for <<; param_set_norm() takes a normalized 0–1 value. params() prints the full table, optionally filtered by substring. For everyday use, prefer the name-based slot() API below.
kit.params("gain");kit.param_set("slot_0/gain", 0.8);PRINT kit.param_get("slot_0/gain");DrumSampleRef
Section titled “DrumSampleRef”slot(name_or_note)
Section titled “slot(name_or_note)”Return a DrumSampleRef — a handle to one live sample slot, addressed by sample name or MIDI note. This is the main API for per-sample sound shaping.
let bd_ref = kit.slot("bd");PRINT bd_ref.name(); // "bd"PRINT bd_ref.note(); // 36kit.slot(38); // by MIDI noteparam(name) / param_get(name) / param_set(name, value) / params(filter?)
Section titled “param(name) / param_get(name) / param_set(name, value) / params(filter?)”Per-slot parameter access by plain name. param() returns a modulatable handle — bind a value or a signal with <<. Available parameters:
| Parameter | Range | Meaning |
|---|---|---|
gain | 0.0 and up | Slot amplitude |
pan | -1.0 to 1.0 | Stereo position |
attack / decay / release | ms | ADSR times |
sustain | 0.0–1.0 | ADSR sustain level |
slice_start / slice_end | 0.0–1.0 | Playback region |
reverse | 0 or 1 | Reverse playback |
kit.slot("bd").param("gain") << 0.8;kit.slot("bd").param("pan") << Sine(0.5).range(-0.5, 0.5);kit.slot("sd").param("slice_end") << 0.5;envelope(attack, decay, sustain, release)
Section titled “envelope(attack, decay, sustain, release)”Set the slot’s ADSR in one call. Times are in milliseconds (0–5000); sustain is a level from 0.0 to 1.0.
kit.slot("bd").envelope(5, 0, 1.0, 50); // punchykit.slot("sd").envelope(5, 100, 0.8, 200); // naturalSamplerMelodic
Section titled “SamplerMelodic”SamplerMelodic(kit?)
Section titled “SamplerMelodic(kit?)”Create a pitched sampler from a melodic-mode kit: incoming notes transpose each sample relative to its root note. 32-voice pool; retriggering the same note releases the previous voice, different notes overlap freely. Without an argument, creates an empty sampler.
use "std/instruments" { SamplerMelodic, Kit };use "std/signals" { Sine };
let keys = SamplerMelodic(Kit("keys"));let track = AudioTrack("keys");track.load_instrument(keys);track << [C3 E3 G3 C4];load_sample(name, root?)
Section titled “load_sample(name, root?)”Load a sample by name from the current kit. The root note comes from the explicit second argument (name or number), or falls back to the kit.toml root field.
keys.load_sample("sound1");keys.load_sample("sound2", "C3");root(note)
Section titled “root(note)”Override the root note of the most recently loaded sample. Accepts a note name or MIDI number.
keys.root("C4");envelope(attack, decay, sustain, release)
Section titled “envelope(attack, decay, sustain, release)”Set the amplitude ADSR. Times are in milliseconds (0–5000); sustain is 0.0–1.0.
keys.envelope(10, 100, 0.8, 200);set_loop(start, end) / set_loop_normalized(start, end)
Section titled “set_loop(start, end) / set_loop_normalized(start, end)”Set sustain-loop points — in seconds, or normalized 0.0–1.0 relative to the sample length. With start > end the loop plays ping-pong, reversing direction at each boundary. Loop points from kit.toml (loop_start/loop_end) are applied automatically. The loop is also modulatable via the LoopStart/LoopEnd parameters.
keys.set_loop_normalized(0.2, 0.8);keys.set_loop_normalized(0.6, 0.3); // ping-pongkeys.param("LoopStart") << Sine(0.5).range(0.1, 0.4);samples() / sample_info() / root_for(name) / get(name) / name() / load_kit(kit)
Section titled “samples() / sample_info() / root_for(name) / get(name) / name() / load_kit(kit)”Inspection and management, analogous to the drum sampler. sample_info() rows are [name, root, file]; root_for() returns a sample’s root note (or NUL if unset); get() extracts a standalone Sample; load_kit() swaps the kit.
PRINT keys.samples();PRINT keys.root_for("sound1"); // 60 (C4)let s = keys.get("sound1");keys.load_kit(Kit("keys"));The five param* methods work exactly as on the drum sampler, including param_set_norm().
Sample Methods in Patterns
Section titled “Sample Methods in Patterns”Sample events in patterns take methods directly: [bd.vel(0.5) sd]. Each method returns a new Sample, so they chain — the original is never mutated.
use "std/instruments" { Sampler, Kit };
let drums = AudioTrack("drums");drums.load_instrument(Sampler(Kit("CR-78")));drums << [bd sd bd sd];vel(v)
Section titled “vel(v)”Set the hit’s velocity: 1.0 is full strength, below is softer, above boosts. Clamped at 0.
drums << [bd sd.vel(0.3) sd.vel(0.3) sd.vel(1.0)]; // ghost notespitch(semitones)
Section titled “pitch(semitones)”Pitch-shift the hit by semitones, positive or negative. Repeated calls in a chain accumulate.
drums << [bd bd.pitch(12) bd.pitch(-12)];drums << [cb cb.pitch(2) cb.pitch(4) cb.pitch(7)]; // pitched cowbell melodypan(position)
Section titled “pan(position)”Place the hit in the stereo field: -1.0 hard left, 0.0 center, 1.0 hard right.
drums << [bd.pan(-1) sd.pan(1)];slice(start, end)
Section titled “slice(start, end)”Play only a region of the sample, with start and end normalized to 0.0–1.0 (start < end required).
drums << [bd.slice(0.0, 0.5) sd bd.slice(0.5, 1.0) sd];reverse()
Section titled “reverse()”Play the hit backwards. Calling it again on the same chain toggles back to forward playback.
drums << [bd.reverse() sd];drums << [bd.slice(0.3, 0.8).reverse().vel(1.2).pan(-0.5)]; // chainingBundled Kits
Section titled “Bundled Kits”Three kits ship with Resonon and are always available — docs and examples rely on them.
CR-78 (oneshot)
Section titled “CR-78 (oneshot)”The default kit, with round-robin variations per sample.
| Name | Note | Sound | Name | Note | Sound |
|---|---|---|---|---|---|
bd | C2 (36) | Bass drum | cb | G#2 (44) | Cowbell |
rs | C#2 (37) | Rimshot | ma | A2 (45) | Maracas |
sd | D2 (38) | Snare | tb | C3 (48) | Tambourine |
cp | D#2 (39) | Clap | gu | C#3 (49) | Guiro |
hh | F#2 (42) | Hi-hat | hb | D3 (50) | High bongo |
cy | A#2 (46) | Cymbal | lb | D#3 (51) | Low bongo |
me | B2 (47) | Metal beat | lc | E3 (52) | Low conga |
cl | G#3 (56) | Clave |
TR-808 (oneshot)
Section titled “TR-808 (oneshot)”| Name | Note | Sound | Name | Note | Sound |
|---|---|---|---|---|---|
bd | C2 (36) | Bass drum | lc | A#2 (46) | Low conga |
rs | C#2 (37) | Rimshot | mc | B2 (47) | Mid conga |
sd | D2 (38) | Snare | hc | C3 (48) | High conga |
cp | D#2 (39) | Clap | cb | C#3 (49) | Cowbell |
ch | E2 (40) | Closed hat | cl | D3 (50) | Clave |
oh | F2 (41) | Open hat | ma | D#3 (51) | Maracas |
cy | F#2 (42) | Cymbal | lt | G2 (43) | Low tom |
mt | G#2 (44) | Mid tom | ht | A2 (45) | High tom |
keys (melodic)
Section titled “keys (melodic)”Two pitched samples for SamplerMelodic: sound1 (root C4) and sound2 (root C3).
kit.toml Format
Section titled “kit.toml Format”A kit is a folder with WAV files and an optional kit.toml. Without the file, every WAV is auto-detected and mapped. With it, you control names, notes, and playback details:
[kit]name = "My Kit" # display name (defaults to the folder name)author = "Your Name" # optionalmode = "oneshot" # "oneshot" (drums) or "melodic" (pitched)
[defaults]bd = "C2" # fallback note for samples without an explicit one
[samples]bd = { files = ["kick_1.wav", "kick_2.wav"], note = "C2", choke_group = 1, velocity = 1.0 }sd = { file = "snare.wav", note = 38 }
# melodic mode uses root instead of note, plus optional loop pointspad = { file = "pad.wav", root = "C4", loop_start = 0.3, loop_end = 0.9 }files with multiple entries enables round-robin playback. When a sample has no explicit note, resolution falls back through [defaults], then the General MIDI drum mapping by name, then sequential assignment from C2. See the samplers chapter for a guided walkthrough of building custom kits.
See Also
Section titled “See Also”- Samplers chapter — guided introduction to kits and samplers
- Track Methods —
load_instrument()and the mixer - Pattern Methods — transforming whole patterns
- Signals — modulation sources for slot parameters
- Configuration — kit search paths