@maruaudio/dsp/mixing/control-gain maps a control signal to a gain and applies it, a VCA over any bounded control. The law rectifies and normalizes the control, optionally inverts it, shapes it with a power curve and maps it into a gain range:
n = clamp(|control|, 0, 1); if invert: n = 1 − n
gain = min + (max − min) × n^clamp(curve, 0.1, 8)
y = signal × gaincontrolGainValue and applyControlGain expose the law as pure functions; controlGainNodeTick(state, signal, control) applies it with stored settings.
Parameters
| Setter | Range | Default |
|---|---|---|
setControlGainMinimum | Stored raw; the law clamps it to 0 to 4 | 0 |
setControlGainMaximum | Stored raw; the law clamps it to 0 to 4 | 1 |
setControlGainCurve | Stored raw; the law clamps the exponent to 0.1 to 8 | 1 (linear) |
setControlGainInvert | 0 is off, any other value is on | Off |
The minimum may exceed the maximum; the gain then falls as the control rises.
Lifecycle
initControlGainNode → setters → controlGainNodeTick → resetControlGainNode. The state holds parameters only, so reset does nothing. The tick calls pow once per sample. Ticks allocate nothing and do no I/O.
When to use it
Turning an envelope, LFO or other control into loudness: a VCA after an envelope, an inverted control that ducks one signal as another rises, or a curved response so a linear control moves the level unevenly. It is a mapping law, not an envelope follower; pair it with a detector if the control comes from audio.
Limits
- Mono sample tick; signal and control are scalar arguments.
- Negative controls are rectified, so a bipolar LFO gives two gain peaks per cycle.
- No smoothing: the gain follows the control sample by sample.
- The clamps are the kernel node's conditional clamp, not the
math/rangepolicy.