Parameter
A named float you drive at runtime. Subscribers update immediately. Bind it to bus levels, FX values, anything.
Tension rises. You want the music bed up, the ambience down, the low-pass on the drone opening, and the reverb wet going with it. Written by hand that is four setters that have to stay in step, plus a fifth the day someone adds another layer.
A Parameter is a named float you
set at runtime, and a set of bindings that map it onto other values. You
set the parameter; everything bound to it updates through its own range
and curve. It is the seam between an idea a designer has and the ten
numbers that idea turns into.
Mental model
API surface
engine.parameter(name, initial?): Parameter
class Parameter {
readonly name: string;
readonly value: number;
set(v: number): void;
subscribe(fn: (v: number) => void): () => void;
bindTo(setter: (mapped: number) => void, opts?: {
from?: number; // default 0
to?: number; // default 1
curve?: 'linear' | 'easeIn' | 'easeOut' | 'easeInOut' | 'equal-power';
}): () => void;
} Live demo
One slider driving a bus level and a derived value, each through its own range and curve.
Recipes
Get / set
const intensity = engine.parameter('intensity', 0.3);
intensity.set(0.7); // updates all bound targets Bind to one or more targets
intensity.bindTo((v) => engine.bus('music').level = v, {
from: 0.4, to: 1.0, curve: 'easeInOut',
});
intensity.bindTo((v) => filter.setFrequency(v), {
from: 800, to: 12000, curve: 'easeIn',
}); Subscribe for UI updates
const off = intensity.subscribe((v) => console.log('intensity:', v));
// later: off(); Pitfalls
set in a tight loop.requestAnimationFrame means 60 Hz, which is fine. Anything
denser than that, throttle it.