Build with this node

Start with a prompt in Studio, or copy it into your own coding agent.

Ask Studio

@maruaudio/dsp/voices/portamento is an exact-duration glide in semitones: a retarget computes a linear per-sample step from the current pitch to the target note over a whole number of frames, and the last tick lands exactly on the target. The source header says it was extracted from Phase 7's voice. The default policy rounds pitch and step to f32; doublePrecision keeps f64, which @maru/voices-phase-7 selects (synth voices).

Parameters

CallCoded range and behavior
initPortamento(capacity, doublePrecision = false)One slot per voice; capacity is the caller's
portamentoFrames(mode, seconds, rate, hadHeldNote)Mode rounded into 0 off, 1 always, 2 only when a note was already held; seconds clamped to 0..2; returns round(seconds × rate) or 0
retargetPortamento(state, slot, note, frames)Frames rounded, floored at 0; 0 frames jumps to the note at once
tickPortamento(state, slot)Advances one frame and returns the current pitch in semitones

Lifecycle

initPortamento allocates four typed arrays at preparation → on a note event compute frames with portamentoFrames, then retargetPortamento → one tickPortamento per sample per slot → resetPortamento zeroes every slot and keeps the buffers and precision. Retarget and tick allocate nothing. A retarget mid-glide starts from the current value.

When to use it

A glide between notes that should take the same time at every sample rate, in mono or legato play or per polyphonic voice. The synth voices guide recommends it for new glides and keeping a product's legacy glide law where presets depend on it.

Limits

  • Pitch is linear in semitones; converting to frequency is the caller's job.
  • Glide time is capped at 2 seconds by portamentoFrames.
  • The slot index is not range-checked.
  • In the default policy a fractional value written into current before a retarget is rounded to f32, preserving the former Float32Array storage.

Algorithm properties and proofs

No Lean 4 proof is mapped to this node.

Explore proofs alongside performance

Dependencies

None: this node imports no other node.

Dependents

Used by