Routing and filters
Effects form a graph. Two structural nodes build it, and a handful of filters decide which events reach which branch.
Effects in series. The top level of a config is already an implicit chain, so you only write chain { } explicitly inside a fork to group several effects into one branch:
shuffle-lock seed=42 // these two linesvelocity-curve gamma=0.8 // are an implicit chainOrder matters: each effect feeds the next. An effect that emits nothing for an event swallows it for the rest of the chain.
Effects in parallel. Each branch gets a copy of the incoming event, and the branch outputs are merged in order. The merge drops exact duplicates, so the classic octave doubler
fork { pass transpose 12}doubles notes without doubling everything else: a control change, passed unchanged by both branches, comes out once, while a note comes out at two pitches because the copies differ.
Filters
Section titled “Filters”Filters pass some events and drop the rest; they have no state and no parameters beyond their ranges. All ranges are inclusive.
| Filter | Passes |
|---|---|
only-channels 1 2 ... |
events on the listed channels (1-16, at least one) |
key-range lo=21 hi=108 |
notes with keys in the range (keys 0-127, defaults 0 and 127); non-note events flow through |
velocity-range lo=1 hi=127 |
note-ons with velocities in the range (1-127, defaults 1 and 127); everything else flows through |
notes-only |
note and poly-pressure events |
controllers-only |
controller events |
pass |
everything (the identity) |
discard |
nothing |
pass and discard earn their keep inside forks: pass keeps the dry signal as one branch, and /- plus discard let you audition branches while editing live.
Note that key-range and velocity-range let non-matching non-note traffic through on purpose, so pedals and mod wheels keep working in every zone. To cut controllers from a branch, add notes-only.
A split keyboard, worked
Section titled “A split keyboard, worked”Lower half humanized into a bass, upper half doubled an octave up, each on its own channel for multitimbral routing in the DAW:
input "Arturia"output virtual="miditool Out"
only-channels 1 // the keyboard's main channel only
fork { // Bass half: notes wander a few keys around what was played. chain { key-range lo=21 hi=59 loose-keys seed=7 sigma=3.5 channelize 2 }
// Treble half: doubled an octave up, velocities tamed. chain { key-range lo=60 hi=108 fork { pass transpose 12 } velocity-curve gamma=1.4 ceiling=100 channelize 3 }}The implicit top-level chain runs only-channels before the fork, so both branches see only channel 1. Inside, each branch filters to its half of the keyboard, transforms, and stamps its output onto its own channel. Forks nest: the treble branch contains its own little doubling fork.