Expand description
Hand-designed preset patches: a starting vocabulary for the bank, and a fast way to seed the taste model (“keep the ones you like”).
Every preset must compile and pass the vetting gate — pinned by a test in the features crate’s dependents (see auracle-wasm tests).
§Every parameter here is normalized; none of them are in units
A PatchTree field is 0.0..=1.0 and the musical meaning lives in the
compiler and in quiver. Writing these by feel rather than by the maps is
how the first nine went wrong in a way nobody could see: every modulated
preset in the library ran between 0.033 Hz and 0.165 Hz — six to thirty
seconds per cycle — against an audition phrase whose longest held note is
1.8 s. The library demonstrated no audible modulation at all, and since the
warm start draws its whole cold-start evidence from these patches, two of
the fifteen features the taste model reasons over (centroid_std,
flux_mean) were pinned to the floor for every observation it started
from. Dub Echo’s time: 0.45 was likewise 30 ms — a flanger.
So: use the maps. They are the arithmetic, not a style guide.
| field | map | worked examples |
|---|---|---|
Filter.cutoff | 20·1000^x Hz | .3→159 · .5→632 · .7→2.5k · .85→7.1k |
AmpEnv.*, Env.* | 1 ms·10000^x time constant | .0→1 ms · .25→10 ms · .5→100 ms · .75→1 s |
Lfo.rate, Rand.rate | 0.01·3000^x Hz | .42→0.29 · .49→0.51 · .58→1.0 · .75→4.05 |
Delay.time | 1 ms·2000^x | .54→60 ms · .63→120 ms · .79→420 ms |
Chorus.rate | 0.1·50^x Hz | .15→0.18 · .25→0.27 · .35→0.39 · .5→0.71 |
Reverb.size | Freeverb room 0.28+0.7x | .9→0.91 |
Filter.resonance | ×0.85 | 1.0 is 0.85, never self-oscillation |
Delay.feedback | ×0.7 | .62→0.43 — the grammar cannot run away |
Phaser.rate | 0.05·100^x Hz | .25→0.16 · .35→0.25 · .5→0.5 · .7→1.25 |
Phaser.feedback | (2x−1)·0.7 | .5 is no feedback; below it the sign flips |
Bitcrush.bits | 1 + 15x bits | .2→4 · .35→6.3 · .6→10 · 1.0→16 (clean) |
Bitcrush.downsample | 1 + 63x × slower | .1→7.3× · .3→20× · .5→33× |
Follow.release | 1 + 999x ms | .2→200 ms · .4→400 ms · .7→700 ms |
AmpEnv.sustain and every mix/balance/depth are levels, not times.
The envelope map is a time constant, not a duration. compile.rs runs
the ADSR in exponential mode, so the mapped value is a one-pole τ: reaching
90% takes ≈2.3 τ and settling takes ≈6.9 τ. Cathedral’s attack of 0.75
maps to 1.0 s and measures 1.397 s to its knee. Read every envelope
number here as “about 1.4× longer than the table says”, and remember the
phrase’s longest note is 1.8 s — an attack much past 0.75 will still be
climbing when the note ends.
Supersaw is ~14 dB quieter than Vco. Quiver scales Vco and
Noise outputs by 5.0 and leaves Supersaw at unity. That is invisible
for anything downstream that only cares about relative level, and fatal for
Fold, which folds x / 5.0 and therefore never reaches its threshold on
a supersaw. Build folded patches on Vco.
§What the grammar cannot do
Worth knowing before designing: there is no FM, no oscillator sync and no
PWM. Vco.detune on a lone oscillator only transposes the whole patch a
few cents sharp; it is only musical inside a Mix (or a RingMod) of two
sources.
Pitch modulation does exist as of wave 2A — Vco and Supersaw carry
a slot that lands on their pitch offset (±0.5 octave at full depth), which
is where vibrato and pitch envelopes come from.
What a ModNode reaches is one parameter per module, and the choice is
the compiler’s, not the patch’s: Vco/Supersaw pitch, Filter.cutoff,
Fold.threshold, Delay.time, Chorus.depth, Reverb.size,
Distortion.drive, Bitcrush.bits, Phaser.depth, Flanger.depth,
Tremolo.depth, Vibrato.depth, Eq.mid, Granular.position,
Wavetable.morph, Pluck.damping, Formant.vowel, Shift.semis,
Comp/Gate threshold, Duck.amount and Vocoder.bands. Only Mix and
RingMod have no slot — both of their inputs are audio and their one knob
is the blend.
ModNode::Follow is the odd one: it listens to the owning module’s own
input, so it only says something on a module whose input has dynamics to
follow. On a source’s slot it is silence, deliberately.
§Levels are not comparable, and the dynamics modules care
Comp, Duck and Gate are keyed by a second branch whose absolute
level decides everything. Measured as mean |x| on a held note: a sine
vco is 3.18 V, a supersaw ≈0.6 V, a plucked string 0.14 V. The
threshold knobs are geometric over 0.05–5 V (compile::map::detector_volts)
so all three are reachable, but a key branch swapped from a pluck to a vco
moves the useful threshold by 25 dB — about a third of the knob.
§The gate is not the constraint
Vetting rejects only non-finite output, RMS < 1e-4, peak > 3.5, and
|mean|/rms > 0.6. It catches pathology, not taste. Design musically and
let the gate do its narrow job.
§This is also the model’s vocabulary lesson
The bank’s auto-namer (auracle-session::naming) fits its adjectives to
the pool’s own spread and suppresses any axis whose range falls below a
just-noticeable difference. A library clustered in one corner therefore
produces a bank that honestly reports itself as Soft Lead, Soft Lead 2,
Soft Lead 3. Coverage here is what gives the whole app its adjectives.
Structs§
- Preset
- One built-in patch, with the copy that makes it findable.
Constants§
- CATEGORIES
- The categories, in display order.
Functions§
- preset_
bank - The built-in preset library, in category order.
- presets
- The built-in presets, as
(name, tree)pairs.
Type Aliases§
- Category
- What a preset is for, so the browser can group them and the warm start can sample across the space instead of down one corner of it.