# Maths, gains and mixing

> Build gain stages, dry/wet paths, stereo matrices and musical value conversions.

Canonical: https://maru.audio/docs/dsp-math-and-mixing
Documentation index: https://maru.audio/llms.txt

Use these building blocks wherever signals meet: input/output trim, parallel
effects, voice summing, stereo placement and modulation scaling. A gain of 1 is
unity; multiplying by 0.5 halves amplitude. Decibels use a logarithmic scale:
`dbToGain(-6)` is approximately 0.501, while `dbToGain(0)` is 1.

## Choose a mix law

A sum adds both inputs and needs headroom. Linear dry/wet uses
`dry * (1 - mix) + wet * mix`; identical aligned signals retain their level.
An equal-power crossfade suits uncorrelated sources, but correlated signals can
rise in the middle. Match the law to the musical purpose.

```ts
import {
  initGainDbNode, setGainDbNodeGainDb, gainDbNodeTick,
} from "maruaudio/dsp/mixing/gain-db"

const trim = initGainDbNode(48_000) // prepare once
setGainDbNodeGainDb(trim, -6)      // control update, in dB
const outputSample = gainDbNodeTick(trim, 0.25)
```

`gain-db` accepts −60 to +24 dB and has an explicit mute setter. Linear `gain`
accepts 0 to 4. Smooth live changes where a hard gain step would click; these
simple gain ticks do not add a ramp automatically.

Stereo width uses mid/side arithmetic. Encode with M=(L+R)/2 and S=(L−R)/2;
decode with L=M+S and R=M−S. Treat an encoded pair as M/S until decoding it.
Panning a mono source and balancing a stereo source use different laws.
Check wide or delayed stereo material in mono.

## Math is also musical control

Use `math/pitch` for transposition and source/host sample-rate conversion,
`math/scale` for note quantization, and the shared velocity laws for sample
layers. These helpers keep the meaning of a parameter consistent with its DSP.
Use schema taper for a knob’s response curve; a dB or Hz argument expects a
physical value, rather than an unconverted normalized knob position.

## Toolkit reference

Import paths below are suffixes of `maruaudio/dsp/`. Use the exported types
and setters in your installed version for complete signatures and defaults.

### Maths

| Import suffix | Purpose | Selected API |
| --- | --- | --- |
| `math/precision` | Explicit double-precision intent via F64/asF64; the helper does not validate or round. | `asF64` |
| `math/decibels` | F64 decibel-to-linear gain and RBJ amplitude conversions with ECMAScript edge behavior. | `dbToGain`, `dbToRbjAmplitude` |
| `math/range` | Clamp values, handle non-finite inputs explicitly and retain the documented signed-zero policy. | `clamp`, `clampUnit` |
| `math/permutation-six` | Fixed six-element permutation rank and unrank shared by serial DSP and host presentation. | `tryUnrankPermutationSix`, `rankPermutationSix` |
| `math/integer` | Signed 32-bit multiply with Math.imul-compatible low-word results. | `multiplyInt32` |
| `math/hash` | Allocation-free 32-bit hash helpers for seeded musical decisions. | `hashStepU32`, `lowBias32ToUnit` |
| `math/quantizer` | Sampled-curve amplitude quantizer reproducing the 2048-point WaveShaper bitcrush staircase exactly at every 1..16 bit depth. | `initQuantizerNode`, `quantizerNodeTick` |
| `math/pitch` | Semitone/cent ratios and source-rate-corrected sample playback steps. | `exp2`, `semitonesToRatio` |
| `math/scale` | Static scale masks, key/enable-mask/reference-A mapping and a hysteretic nearest-note quantizer with pass-through. | `initScaleQuantizer`, `scaleIntervalMask` |
| `math/ring-stack` | Ring stacks of a heptatonic scale: line-of-thirds order, hinge, signed positions -3..+3, the diatonic stack at a position and height as pitch classes or close intervals, ring steps, mirror and shared-note counts. | `createRingStack`, `ringHeptatonicScaleId` |
| `math/grid-coordinates` | Allocation-free square/61-key hex key addressing shared by controller Processors (Isomorphic Keyboard, Exquis Controller). | `positionKeyRow`, `positionKeyColumn` |
| `math/float-clamp` | Firmware-compatible NaN-ignoring float clamp and signed-zero behavior. | `floatMax`, `floatMin` |
| `math/pcm16` | Float/PCM16 conversion with the firmware’s clamp, truncation and float32 scale. | `floatToPcm16`, `pcm16ToFloat` |

### Gains and mixing

| Import suffix | Purpose | Selected API |
| --- | --- | --- |
| `mixing/constant` | Bounded constant/DC source for modulation graphs and cross-lane parity probes. | `initConstantNode`, `constantNodeTick` |
| `mixing/control-gain` | Control-to-gain mapping law (rectify, normalize, optional invert, power curve, bounded min/max range) and the VCA that applies it. | `initControlGainNode`, `controlGainNodeTick` |
| `mixing/gain` | Bounded linear output-gain stage as a per-channel double multiply over one shared parameter state. | `initGainNode`, `gainNodeTick` |
| `mixing/gain-db` | Bounded decibel gain with a mute gate, using the dB-to-linear conversion. | `initGainDbNode`, `gainDbNodeTick` |
| `mixing/levels` | Amplitude-to-dB, equal-power gains and a prepared note-transition audio-edge blend. | `initNoteTransition`, `noteTransitionTick` |
| `mixing/mix` | Two-input mix operator: sum, linear dry/wet, equal-power crossfade and ring modulation with an equal-shape dry/wet. | `initMixNode`, `mixNodeTick` |
| `mixing/constant-power-pan` | Equal-power mono pan and stereo-input balance laws; scalar gains retain double precision. | `constantPowerPanLeft`, `constantPowerPanRight` |
| `mixing/velocity` | Velocity gain, MIDI velocity-byte conversion, configurable amplitude response and layer crossfade weights. | `velocitySquaredGain`, `velocityResponseGain` |
| `mixing/key-velocity-response` | Register-interpolated gain and velocity exponent for reusable instrument response calibration. | `keyInterpolatedValue`, `keyInterpolatedValueEight` |

### Stereo

| Import suffix | Purpose | Selected API |
| --- | --- | --- |
| `stereo/width` | Mid/side stereo-width matrix state, bounded coefficient derivation and per-channel sample operations. | `initStereoWidthNode`, `setStereoWidth` |
| `stereo/to-mono` | Stereo-to-mono arithmetic mean (L+R)/2 with float32 output. | `stereoToMonoNodeTick` |
| `stereo/pan` | Equal-power stereo pan law over the shared crossfade gain pair, with a bounded position and plain double per-channel multiplies | `initPanNode`, `setPanNodePosition` |

Return to [DSP fundamentals](https://maru.audio/docs/dsp-fundamentals.md) for I/O, lifecycle,
units and the category map.
