Add controls
Knobs, switches, and menus.Declare controls in describe. Msh draws them, styled like the built-in devices, with
automation and modulation for free. Full options in the parameters
reference.
A knob
// id, name, short name, min, max, default, modulatable
m.addParam(new ParamDef("cutoff", "Cutoff", "Cut", 20, 20000, 1000, true));A different shape
A control is a knob by default. Add a helper to change it:
m.addSetting(
new ParamDef("type", "Type", "Type", 0, 2, 0, false).asToggleGroup([
"LP",
"BP",
"HP",
]),
);.asToggle()for on/off (range0to1).asToggleGroup([...])for a row of buttons.asSelect([...])for a dropdown.asDragNumber()for a draggable number
Knob or setting
addParam for something you'd sweep or modulate. addSetting for a fixed choice (a
mode, a count). Same thing, except a setting gets no modulation wheel.
Read it
In process, by the order you declared them:
const cutoff = ctx.modulatedParam(0, i); // with modulation
const mode = ctx.param(1); // plain value, good for settingsDon't want to count indices? Resolve one by name: ctx.paramIndex("cutoff").
Feel
Chain .unit(UNIT_HZ) for a suffix, and .logarithmic() (frequency) or .skew(...)
(time) so the sweep feels right. Chain .precision(2) to fix the readout to a set
number of decimal places.
Shortcuts
For the common shapes there's a factory that fills in the unit and skew for you:
m.addParam(ParamDef.freq("cutoff", "Cutoff", "Cut", 20, 20000, 1000)); // Hz, log
m.addParam(ParamDef.time("attack", "Attack", "Atk", 0.001, 2, 0.01)); // seconds, skewed
m.addSetting(ParamDef.scaleSelect("scale", "Scale", "Scl")); // a scale dropdownParamDef.scaleSelect / rootSelect / chordSelect build dropdowns wired to the
scale, key, and chord catalogs, so the value reads straight back as a catalog index.
Full options in the parameters reference.