@maruaudio/dsp/mixing/velocity holds the velocity laws sample players share, extracted from voices/sampler-zone with the arithmetic unchanged.
| Function | Law | Precision |
|---|---|---|
velocitySquaredGain(v) | v² | f32 |
velocityResponseGain(v, floor, curve) | floor + (1 − floor) × curve(v), curve VELOCITY_CURVE_SQUARED (v²) or VELOCITY_CURVE_LINEAR (v) | f32 |
velocityToByte(v) | floor(clamp(v × 127, 0, 127) + 0.5), the MIDI byte a layer is selected with | integer |
velocityCrossfadeWeight(byte, low, high, fadeIn, fadeOut) | 1 without a fade; inside a fade span sin(w·π/2) of the linear position | f64 |
The crossfade spans are measured inward from the layer's own edges: fadeIn steps above low and fadeOut steps below high, with the linear position (steps + 0.5) / span. A layer never contributes outside the range it declares.
Parameters
There are no setters or state; every value is a function argument. floor is the gain at velocity 0: 0 follows the curve fully and 1 holds every strike at unity.
Lifecycle
Pure functions, evaluated at note-on and folded into the voice's constant gain. Nothing allocates or does I/O.
When to use it
Mapping note velocity to loudness in a sample player, choosing the velocity layer for a strike, and crossfading two adjacent layers at constant power across their seam.
Limits
- The response shapes loudness only; layer selection is
velocityToByte's. velocityResponseGain(v, 0, VELOCITY_CURVE_SQUARED)equalsvelocitySquaredGain(v)to the bit.- The crossfade weight stays a double so the caller rounds once after folding it into its gain.
velocitySquaredGainandvelocityResponseGaindo not clampv.