pub enum AudioNode {
Show 27 variants
Vco {
wave: Waveform,
octave: i8,
detune: f64,
mod_depth: f64,
modulation: ModNode,
uid: Uid,
},
Supersaw {
octave: i8,
detune: f64,
mix: f64,
mod_depth: f64,
modulation: ModNode,
uid: Uid,
},
Noise {
color: NoiseColor,
uid: Uid,
},
Wavetable {
table: TableShape,
octave: i8,
morph: f64,
mod_depth: f64,
modulation: ModNode,
uid: Uid,
},
Pluck {
octave: i8,
damping: f64,
brightness: f64,
mod_depth: f64,
modulation: ModNode,
uid: Uid,
},
Formant {
vowel: f64,
shift: f64,
octave: i8,
mod_depth: f64,
modulation: ModNode,
uid: Uid,
},
Silence {
uid: Uid,
},
Mix {
balance: f64,
a: Box<AudioNode>,
b: Box<AudioNode>,
uid: Uid,
},
Filter {
kind: FilterKind,
cutoff: f64,
resonance: f64,
mod_depth: f64,
input: Box<AudioNode>,
modulation: ModNode,
uid: Uid,
},
Fold {
threshold: f64,
mod_depth: f64,
input: Box<AudioNode>,
modulation: ModNode,
uid: Uid,
},
Delay {
time: f64,
feedback: f64,
mix: f64,
mod_depth: f64,
input: Box<AudioNode>,
modulation: ModNode,
uid: Uid,
},
Chorus {
rate: f64,
depth: f64,
mix: f64,
mod_depth: f64,
input: Box<AudioNode>,
modulation: ModNode,
uid: Uid,
},
Reverb {
size: f64,
damp: f64,
mix: f64,
mod_depth: f64,
input: Box<AudioNode>,
modulation: ModNode,
uid: Uid,
},
Distortion {
drive: f64,
tone: f64,
mode: DriveMode,
mod_depth: f64,
input: Box<AudioNode>,
modulation: ModNode,
uid: Uid,
},
Bitcrush {
bits: f64,
downsample: f64,
mod_depth: f64,
input: Box<AudioNode>,
modulation: ModNode,
uid: Uid,
},
Phaser {
rate: f64,
depth: f64,
feedback: f64,
mod_depth: f64,
input: Box<AudioNode>,
modulation: ModNode,
uid: Uid,
},
Flanger {
rate: f64,
depth: f64,
feedback: f64,
mod_depth: f64,
input: Box<AudioNode>,
modulation: ModNode,
uid: Uid,
},
Tremolo {
rate: f64,
depth: f64,
shape: f64,
mod_depth: f64,
input: Box<AudioNode>,
modulation: ModNode,
uid: Uid,
},
Vibrato {
rate: f64,
depth: f64,
mix: f64,
mod_depth: f64,
input: Box<AudioNode>,
modulation: ModNode,
uid: Uid,
},
Eq {
low: f64,
mid: f64,
high: f64,
mod_depth: f64,
input: Box<AudioNode>,
modulation: ModNode,
uid: Uid,
},
Granular {
position: f64,
size: f64,
density: f64,
mod_depth: f64,
input: Box<AudioNode>,
modulation: ModNode,
uid: Uid,
},
RingMod {
mix: f64,
a: Box<AudioNode>,
b: Box<AudioNode>,
uid: Uid,
},
Shift {
semis: f64,
window: f64,
mix: f64,
mod_depth: f64,
input: Box<AudioNode>,
modulation: ModNode,
uid: Uid,
},
Comp {
threshold: f64,
ratio: f64,
makeup: f64,
mod_depth: f64,
input: Box<AudioNode>,
sidechain: Box<AudioNode>,
modulation: ModNode,
uid: Uid,
},
Duck {
amount: f64,
threshold: f64,
release: f64,
mod_depth: f64,
input: Box<AudioNode>,
key: Box<AudioNode>,
modulation: ModNode,
uid: Uid,
},
Gate {
threshold: f64,
range: f64,
release: f64,
mod_depth: f64,
input: Box<AudioNode>,
sidechain: Box<AudioNode>,
modulation: ModNode,
uid: Uid,
},
Vocoder {
bands: f64,
attack: f64,
release: f64,
mod_depth: f64,
carrier: Box<AudioNode>,
modulator: Box<AudioNode>,
modulation: ModNode,
uid: Uid,
},
}Expand description
An audio-sort term: sources at the leaves, processors and mixers above.
Variants§
Vco
Band-limited analog-style oscillator.
Its modulation slot lands on pitch, not on a timbre parameter — the
one destination no other module in the grammar can offer, and the
reason vibrato and pitch envelopes exist at all here. See
[crate::compile]’s wire_pitch.
mod_depth/modulation are #[serde(default)] for the reason spelled
out on AudioNode::Delay, and more urgently: a vco is in every
saved patch, so without the defaults no session on disk deserializes at
all.
Fields
Supersaw
Seven-voice detuned saw stack with sub oscillator.
Fields
mod_depth: f64Normalized pitch-modulation depth (0-1 → ±0.5 octave). Absent in
pre-2A saves — see AudioNode::Vco.
Noise
Noise source.
Wavetable
Morphing wavetable oscillator: eight bandlimited tables, crossfaded.
It has no detune — the faceplate budget is four knobs and morph is
the reason this module exists, so detune loses. The compiler still
routes pitch through the usual offset, pinned at “no detune”.
Fields
table: TableShapeBase table.
Pluck
Karplus-Strong plucked string, retriggered by the note gate.
Fields
Formant
Formant (vocal-tract) oscillator: a glottal pulse through five parallel resonators.
vowel is a continuous position interpolated across A/E/I/O/U
rather than a five-way switch, which is what makes it worth a
modulation slot: sweeping it moves the formant peaks, and that is a
spectral movement φ’s centroid and rolloff coordinates measure
directly.
Fields
Silence
A source that makes no sound.
The seventh source leaf, and the only one a player can mean literally:
an unplugged socket. Before this existed the rack drew a dashed EMPTY
plate over a substitute Vco, so the plate was honest and the patch
underneath was not — the model was taught on a tree containing a source
the player believed was silent, and every φ coordinate measured a
render that had it in.
It carries no parameters, which makes it the only source whose whole
genome is #leaf and #src. Its prior weight is deliberately tiny
(see PatchGrammarPrior::source_weights)
but not zero: at zero the grammar gives p = 0 to any tree
containing one, the Boltzmann target is −∞, and MH rejects every
proposal touching a hand-made hole — so unplugging a socket would
quietly make a patch un-evolvable. Small and nonzero instead means a
Silence-only tree renders silent, the vet gate quarantines it, and
evolution learns to avoid it. That is a path rather than a wall, and it
is the designed one.
Appended after Formant on purpose: #src is a categorical whose
index is what a saved trace stores, so a new kind may only ever be
added at the end. Inserting one here would silently re-point every
persisted genome at a different oscillator.
Mix
Equal-power crossfade of two audio terms.
Fields
Filter
A filter over an audio term, with an optional cutoff modulation.
Fields
kind: FilterKindWhich filter.
Fold
Wavefolder over an audio term, with optional threshold modulation.
Fields
Delay
Delay line over an audio term, with optional delay-time modulation.
mod_depth and modulation are #[serde(default)] because this
variant shipped without them: the v2 palette added a modulation
slot to a module users already have saved patches of. Serde requires
every field of a struct variant unless told otherwise, so without the
defaults a single v1-era delay anywhere in a bank fails the
SessionState deserialize — and that failure is not local to the
patch, it takes the whole save down: bank, observation log, lineage.
A grammar that grows knobs on existing modules must default them, and
the defaults must be the v1 behaviour (depth 0, no source), so a
restored patch sounds like the one that was saved. Same for
AudioNode::Chorus and AudioNode::Reverb. The variants the v2
palette introduced (wavetable, pluck, distortion, bitcrush, phaser,
ring mod) need no such treatment: no old save can contain one.
Fields
mod_depth: f64Normalized modulation depth (0-1). Absent in v1 saves; defaults to 0, which is “no modulation reaches the delay time”.
modulation: ModNodeDelay-time modulation source. Absent in v1 saves; defaults to
ModNode::None.
Chorus
Chorus over an audio term, with optional depth modulation.
Fields
mod_depth: f64Normalized modulation depth of the modulation slot (0-1).
Absent in v1 saves — see AudioNode::Delay.
Reverb
Algorithmic reverb (Freeverb) over an audio term, with optional size modulation.
Fields
mod_depth: f64Normalized modulation depth (0-1). Absent in v1 saves — see
AudioNode::Delay.
Distortion
Waveshaping distortion over an audio term.
Fields
Bitcrush
Bit-depth and sample-rate reduction over an audio term.
Fields
Phaser
Swept allpass phaser over an audio term.
Fields
Flanger
Flanging comb over an audio term: a 1–10 ms swept delay against the
dry signal, with signed feedback. Stereo — its spread decorrelates
the two sweeps, exactly as the phaser’s does.
Fields
Tremolo
Amplitude modulation over an audio term, sine-to-triangle.
Fields
Vibrato
Pitch wobble over an audio term (a modulated delay read).
The distinction from AudioNode::Chorus is mix: a half-wet
vibrato is a chorus, because the dry and the pitch-shifted copies
beat against each other. This module earns its place by running wet.
Fields
Eq
Three-band tone control over an audio term (low shelf, parametric mid, high shelf), each ±12 dB with unity at the knob’s centre.
Fields
Granular
Granular re-reading of an audio term: overlapping Hann-windowed grains taken from a rolling buffer of what the input just played.
Fields
RingMod
Ring modulation of two audio terms, crossfaded against the dry carrier. The grammar’s second binary node.
Fields
Shift
Grain-based pitch shifter over an audio term: two Hann-windowed grains read from a rolling buffer at a resampled rate.
Unary, unlike the four modules below it. Wave one cut it alongside the
compressor and the vocoder on the belief that it needed a second audio
input; it does not — quiver’s PitchShifter is in/shift/window/
mix, one signal in and one out.
Fields
Comp
Compressor whose detector runs on a second audio term: the
grammar’s third binary node, and the first whose /1 branch is heard
only as a control.
The four binary nodes below all follow AudioNode::Mix’s child
order: /0 is the signal you hear, /1 the signal that shapes it.
Fields
Duck
Ducker: a key signal pulls the main signal down, in proportion to how far the key’s envelope sits above the threshold.
The difference from AudioNode::Comp is what the gain reduction is
proportional to — a compressor reduces by the excess over the
threshold in dB, a ducker by the key’s level relative to it, up to a
fixed depth. That is the sidechain-pump gesture rather than dynamics
control, and it is the one people actually reach for.
Fields
Gate
Noise gate keyed by a second audio term.
Fields
Vocoder
Vocoder: a bank of bandpass filters whose per-band envelopes are taken from the modulator and imposed on the carrier.
Both branches are audible in the sense that both shape the output, but
only the carrier’s waveform reaches it — the modulator contributes
its spectral envelope and nothing else, which is why /1 is still the
control side under this family’s child-order convention.
Fields
Implementations§
Source§impl AudioNode
impl AudioNode
Sourcepub fn set_uid(&mut self, id: Uid)
pub fn set_uid(&mut self, id: Uid)
Overwrite this node’s identity. Only the settling and inheritance passes have any business calling this.
Sourcepub fn children(&self) -> Vec<&AudioNode>
pub fn children(&self) -> Vec<&AudioNode>
Audio children in key-index order — the same /0, /1 order
mutate::child_mut, describe and genome all use, so index i here
and the key segment i there address the same node.
Sourcepub fn children_mut(&mut self) -> Vec<&mut AudioNode>
pub fn children_mut(&mut self) -> Vec<&mut AudioNode>
Mutable Self::children.
Sourcepub fn modulation(&self) -> Option<&ModNode>
pub fn modulation(&self) -> Option<&ModNode>
The modulation term hanging off this node’s one mod slot, if the module
has one (Mix, RingMod, Noise and Shift do not).
Sourcepub fn modulation_mut(&mut self) -> Option<&mut ModNode>
pub fn modulation_mut(&mut self) -> Option<&mut ModNode>
Mutable Self::modulation.
Sourcepub fn site_count(&self) -> usize
pub fn site_count(&self) -> usize
Number of probabilistic-choice sites in this subtree (including the
structural #leaf/#src/#op sites and any modulation subterm).