Wrap a set of sounding pitches.
MIDI pitches, lowest voice first; the array is copied, never retained or mutated, and its order is kept. A doubled pitch is kept too, since doubling is how a four-voice texture states a triad.
StaticsatbA copy of the default four-voice SATB ranges, ascending: the compass Voicing.satb voices into and Voicing.checkTo judges a four-voice exercise against.
A copy of the sounding MIDI pitches, lowest voice first.
The compass the voicing occupies: its lowest and highest sounding pitch.
Read as a VoiceRange so it can be handed straight back as a range for another voice. The pitches are searched rather than read off the ends, so a voicing whose voices cross still reports the compass it sounds.
A copy of the underlying plain pitch array.
StaticofWrap a set of sounding pitches.
MIDI pitches, lowest voice first.
The voicing.
StaticforRealize a chord as an explicit tertian voicing in a chosen style — close, drop-2, drop-3, shell or rootless — independent of the SATB range search Voicing.satb runs.
A chord symbol, plain chord data, or a Chord.
Optionalopts: StyledVoicingOptions
Styled voicing options; defaults to a close voicing at octave 4.
The voicing, ascending.
StaticsatbRealize a chord as one pitch per voice inside the voice ranges, defaulting to the four SATB_RANGES.
The bass takes the chord's slash bass when it has one, otherwise the root; the result is compact, centred in its ranges, and free of voice crossing.
A chord that carries a key passes it to the voicer, so the leading tone is
not doubled; an explicit opts.key overrides it. That is the order
Chord.voice resolves them in, and the two answer alike.
A chord symbol, plain chord data, or a Chord.
Optionalopts: VoicingOptions
Voicing options; defaults to four voices in SATB_RANGES.
The voicing, ascending.
StaticfromWrap a plain pitch array, as Voicing.data hands it out.
The MIDI pitches.
The voicing.
StaticfromRebuild a voicing from its Voicing.toJSON output.
The serialized pitches.
The voicing.
Spell the voicing as notes with letters and octaves, so the rules that read letters can be applied to it.
Each pitch is named against the key, and against the chord sounding under it when one is given, so a chord tone takes the letter its interval above the root implies: the third of a D major chord in C major spells F#, not Gb.
One spelled note per pitch, in voice order.
Voice a chord to follow smoothly from this voicing.
Candidates are enumerated within the ranges opts names, or — when neither
voices nor ranges is given — within a one-octave window around each of
these pitches, so the answer keeps this voicing's voice count. Each is
scored by structural quality, motion from here, and a large penalty per
counterpoint violation. A chord that carries a key passes it to the voicer
unless opts.key names another one.
The rules read from the chord being left — a chordal seventh's resolution,
a leading tone's resolution, and the cross relation between the two chords
— are scored only when opts.previousChord names that chord: a voicing
does not say what it was written on.
A chord symbol, plain chord data, or a Chord.
Optionalopts: VoicingOptions
Voicing options; when omitted, the ranges follow this voicing.
The chosen voicing.
The voice-leading cost from this voicing to another: the summed absolute semitone motion across voices, and nothing besides. What the motion breaks is Voicing.checkTo's question.
The voicing moved to.
The cost, or Infinity when the two hold a different number of
voices and are therefore not comparable.
Check the motion from this voicing to another against the four-part rules, and report every rule the pair breaks.
Both voicings are spelled in key against the chord each realizes, then
graded as a two-chord exercise: voice crossing, spacing and range inside
each chord, and parallel and hidden perfects, overlap, cross relations,
augmented melodic intervals and unresolved tendency tones between them.
The voicing moved to.
The chord this voicing realizes and the chord other does.
The key the exercise is written in; it names the leading tone.
Optionalopts: PartWritingOptions
Ranges and the upper-voice spacing limit; a four-voice pair is judged against SATB_RANGES when no ranges are given.
Every violation found, in musical order; an empty array for a clean pair.
Mark this voicing, read as a written counterpoint line, against a cantus firmus in one of the five species.
The pitches are the counterpoint, one per slot rather than one per voice:
this is the one place where the array is a line in time instead of a chord
in register. Both lines are spelled in mode, since half of what the
species rules forbid — the augmented second, the diminished fourth — is
invisible in a pitch.
The given voice, one note per measure, as note names, plain notes, MIDI pitches, or Note instances.
Which species the exercise is written in.
The mode the exercise is in.
Optionalopts: SpeciesOptions
Note lengths, and which side the counterpoint is written on;
the fifth species cannot be read without durations.
Every violation found, in the order the exercise commits them.
Measure how independent this voicing, read as a line, is from another.
As in Voicing.species the pitches are slots in time, one per entry,
aligned with other slot for slot. Nothing here is a verdict: parallel
thirds report as parallel motion with a small separation, a pedal point as
oblique motion.
The line measured against this one, of the same length.
Optionalopts: VoicingIndependenceOptions
Attack flags, the treatment of the fourth, and the key both lines are spelled in.
The motion breakdown, rhythmic complementarity, separation, crossings, and the longest perfect-consonance run.
Judge a candidate pitch placed against these voices.
Every pitch of this voicing stands as another part sounding under the
candidate, so the vertical rules read them all; the motion rules need
query.previous, which gives each of those voices the pitch it came from.
The candidate MIDI pitch.
The candidate's harmonic and voice-leading context.
Optionalopts: EvaluateSafetyOptions
Set suggestions: false to skip the search for safe
replacements when the verdict is not safe.
The verdict, reason bitmask, and optional resolution guidance.
Enumerate the pitches placeable against these voices in a range, chord tones first, each group descending.
The harmonic and voice-leading context, as Voicing.safetyOf reads it.
Lowest MIDI pitch to consider (inclusive).
Highest MIDI pitch to consider (inclusive).
The placeable pitches — those not judged dissonant.
The n-th inversion of the voicing: the lowest voice taken up an octave, n times over.
A negative n takes the highest voice down an octave as many times, and
invert(0) is the voicing itself, voice order and all. Unlike
Chord.invert, which rotates a chord's interval template, this moves
real voices: inverting a four-voice texture four times leaves the same chord
an octave higher. A voicing that actually inverts comes back ascending,
since the voice that moved is no longer where it was.
How many voices to move, upward when positive.
The inverted voicing, ascending; this voicing itself when n is 0.
Whether another voicing sounds the same pitches in the same order.
A doubling counts: two voices on the same pitch are two voices, and a three-voice texture is not the four-voice one that doubles its root.
The voicing to compare.
True when the pitches match one for one.
The plain pitch array, for JSON serialization.
Private class fields do not serialize, so an explicit toJSON keeps
JSON.stringify(voicing) from collapsing to {}.
A copy of the sounding MIDI pitches, in voice order.
The pitches separated by spaces, so a template literal or a log line reads as the voicing.
The pitches in voice order, e.g. '60 64 67'.
An immutable voicing: the pitches one chord sounds at one moment, lowest voice first (index 0 = the bass), the voice order voiceChord and SATB_RANGES already use.
The order given is kept rather than sorted: a voicing whose voices are out of order is one whose voices cross, which is a fault Voicing.checkTo reports rather than one the class quietly repairs.
The voicing, part-writing, counterpoint and safety functions all take the same array of voices; this holds it once and passes it to each of them. Two of the methods read the pitches as a line rather than a chord — Voicing.species and Voicing.independence, which judge a written part slot by slot — and say so.
The individual counterpoint predicates (
createsParallelPerfect,createsVoiceCrossing, and the rest) stay standalone functions: they judge one pair of voices at one moment, which is a question about two pitches rather than about a voicing. Voicing.checkTo is the bundled check.Example