@maruaudio/dsp/mixing/levels holds the level mappings that gain, mix and pan DSP nodes share, so a pan position and a crossfade position mean the same gains everywhere, plus a short audio-edge blend for note changes.
| Function | Law | Precision |
|---|---|---|
gainToDb(g) | ln(g) × 20/ln(10), or −240 dB for g ≤ 1e-12 | f64 |
equalPowerGainA(p) | cos(p·π/2) over a 0 to 1 position | f32 |
equalPowerGainB(p) | sin(p·π/2) | f32 |
noteTransitionFrames(rate) | max(2, round(rate × 0.005)), a 5 ms fade | integer |
noteTransitionSample(out, in, remaining, total) | Linear blend with weight remaining / total on out; in once remaining ≤ 0 | f32 |
Parameters
There are no setters. The mappings take their arguments directly, and the note transition's length is fixed from the sample rate passed to initNoteTransition.
Lifecycle
The mappings are pure. The note transition is caller-owned state: initNoteTransition(rate) → startNoteTransition at a note event, which snapshots the last emitted frame → noteTransitionTick(state, left, right) once per frame, reading outLeft and outRight → resetNoteTransition, which zeroes the samples and the countdown and keeps the length. Nothing allocates or does I/O.
When to use it
gainToDb for metering or for showing a level in decibels. The equal-power pair for a crossfade or a pan whose position runs from 0 to 1. The note transition when a voice restarts on a new note and the jump from the last emitted sample should be bridged over 5 ms, independently of portamento.
Limits
equalPowerGainA(1)is 6.12e-17, not exactly 0.- The transition advances both channels on every tick, even for a mono voice sent to two ports. It blends from a snapshot; it does not crossfade two running voices.
- For a bipolar −1 to 1 pan returned as unrounded doubles, use
@maru/mixing-constant-power-pan; its angle matches this pair bit for bit.