@maruaudio/dsp/math/pitch converts musical intervals to frequency ratios in f64. exp2(x) is written as Math.exp(x × ln 2) rather than Math.pow(2, x) because Maru compiler lowers exp directly; the sampler's golden output was pinned against exactly this expression. Semitone and cent ratios are exp2(s / 12) and exp2(c / 1200), and samplePlaybackStep gives the source frames a pitched sample advances per engine frame.
import { samplePlaybackStep } from "@maruaudio/dsp/math/pitch"
const step = Math.fround(samplePlaybackStep(7, -13.7, 44100, 48000))Functions
| Name | Inputs | Output | Domain as coded |
|---|---|---|---|
exp2 | x | Math.exp(x × 0.6931471805599453) | Any number; no clamp |
semitonesToRatio | semitones | exp2(semitones / 12) | Equal temperament |
centsToRatio | cents | exp2(cents / 1200) | |
samplePlaybackStep | semitones, fineTuneCents, sourceRate, engineRate | transposition × fine tune × sourceRate / engineRate | Multiplied in that order; a non-positive rate skips the rate term instead of dividing |
Lifecycle
None. Pure double functions with no state.
When to use it
Transpose a sample player, tune an oscillator by semitones and cents, or play a recording made at another sample rate. It was extracted from voices/sampler-zone with its arithmetic unchanged.
Limits
- f64 only. The caller applies
Math.froundwhere it stores a ratio into f32 state, as the sampler does for its playback step. - The constant and the operand order are part of the contract; reordering the product changes rounding.
- Distinct from the stmlib float32 table law in
math/stmlib-pitch.ts, which the Mutable Instruments translations use (shared behavior).