Build with this node

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

Ask Studio

@maruaudio/dsp/voices/chord-voicing voices a stacked chord of one to seven tones (a triad up to a ring stack of height 7) into MIDI notes, in one of four styles: root position, voice-led (the inversion and octave that move least from the previous chord, with a mild pull back to the register), drop 2 (the voice-led stack with its second voice from the top dropped an octave) and spread (every step rises by at least eight semitones). addBassNote adds the root below the lowest voice. The source header says SPREAD restates @maruaudio/chord-banks' allocating spreadVoicing exactly and DROP 2 applies its drop operation, without allocation (pitch and harmony).

Parameters

InputCoded behavior
styleVOICING_ROOT 0, VOICE_LED 1, DROP2 2, SPREAD 3; any other value voices root position (CLOSE in voiceChordInRegister)
count1 to 7 tones (CHORD_VOICING_MAX_TONES); outside that range nothing is voiced and 0 is returned
rootNote, intervals[intervalOffset..]Root MIDI note and ascending semitone offsets
previous, previousCountLast voiced chord tones, ascending, for VOICE-LED and DROP 2; 0 for none
register (in-register only)Rounded and clamped to MIDI; the lowest note lies in [register − 6, register + 5]
anchor (in-register only)VOICING_ANCHOR_ROOT 0 (root lowest) or NEAREST 1 (the tone nearest the register, ties downward); other values act as NEAREST
windowLow, windowHigh (in-register only)Rounded and clamped to MIDI; [0, 127] means no window; notes outside fold in by octaves

Lifecycle

Stateless. The caller owns the scratch, stack and out buffers (at least count notes; CHORD_VOICING_BUFFER = 8 covers seven tones and a bass) and the previous-chord buffer, which it updates after each chord. voiceChord places the stack by the root note's octave; voiceChordInRegister ignores that octave and places it by register and anchor.

When to use it

A chord generator, strummer or ring-stack instrument that turns chord symbols into playable notes and wants smooth motion between chords, or a fixed register for a part.

Limits

  • No allocation, closures or strings; loops have compile-time bounds.
  • Integer MIDI notes only; voice-led candidates outside 0..127 are skipped.
  • addBassNote adds nothing when the root would fall below MIDI 0 or out is full.
  • A DROP 2 of five or more tones can lack a root-lowest candidate; ANCHOR ROOT then falls back to NEAREST's choice.

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

No other node imports this one.

Used by