The chord sequence.
The array is the progression's own and is frozen rather than copied, so reading it in a loop stays linear.
The carried key context, if any.
A copy of the underlying plain progression data: the chords as plain objects and the carried key, if any, as its own plain data.
The number of chords.
StaticofStart from a chord sequence, matching the of factory on the other
classes.
The same reading as the constructor, so a progression reads like
Chord.of and Score.of do at the point it is built.
The progression.
StaticfromBuild a progression from the ChordSpan records the generators return, keeping their order.
The spans' startBeat, degree, and secondaryDominant are analysis
annotations that a chord sequence does not carry; only the harmony crosses
over. Keep the spans themselves if the timing matters.
The progression.
StaticfromRebuild a progression from its Progression.toJSON output.
The serialized chords and key.
The progression.
StaticfromWrap plain progression data, matching the fromData factory on the other
classes.
The plain progression, as Progression.data hands it out.
The progression.
The chord at an index.
0-based position; a negative index counts from the end.
The chord, or undefined when the index is out of range.
Iterate the chords in order, so a progression works with for...of.
Whether another progression holds the same chords in the same order.
The key context is not compared: it is an analysis lens, not part of the harmony. Chord equality follows Chord.equals.
The progression to compare.
True when the chord sequences match.
A copy of this progression with a chord appended.
The chord to append.
The new progression.
A new progression with every chord replaced by what fn returns for it.
The result is a progression rather than an array, and it carries this progression's key context, so a transformation stays inside the class instead of dropping out of it and having to be rebuilt. This progression is untouched.
The key reaches the returned chords the way the constructor attaches it, so
a chord fn built without one is still spelled and analyzed in this key.
The mapped progression.
import { Chord, Key, Progression } from '@libraz/libcantus';
const progression = new Progression([Chord.parse('C'), Chord.parse('G')], Key.major('C'));
const moved = progression.map((chord) => chord.transpose(2));
moved.toString(); // 'D A'
moved.key?.toString(); // 'C major'
progression.toString(); // 'C G' — the original is unchanged
A new progression holding only the chords pred accepts, in order.
The key context travels with them and this progression is untouched.
Called with each chord and its 0-based index.
The filtered progression, empty when nothing is accepted.
A stretch of this progression, as a progression carrying the same key.
The bounds read as Array.prototype.slice reads them: end is exclusive,
a negative index counts from the end, and an omitted bound runs to the edge.
Optionalstart: number
First chord of the stretch; defaults to the beginning.
Optionalend: number
One past the last chord; defaults to the end.
The sliced progression.
This progression followed by another run of chords.
The result carries this progression's key context; a key the other progression carried is dropped, because two keys cannot both analyze one chord sequence. Re-key the result with Progression.withKey where the second run is the one to read it in.
The chords to append, as a progression or a plain array.
The joined progression.
The position of the first chord equal to chord.
Equality is Chord.equals, not reference identity, so a chord built separately is found as long as it names the same harmony.
The chord to look for.
The 0-based position, or -1 when the progression holds no such chord.
Voice the progression with smooth voice leading.
Optionalopts: VoicingOptions
Voicing options; defaults to four SATB voices.
One ascending voicing (MIDI pitches) per chord.
The Roman numeral of each chord in a key.
Optionalkey: KeyLike
Key to analyze in, as a key name, a plain key/scale, or a Key; falls back to the carried context.
Optionalopts: ChordToRomanOptions
Applied-numeral rendering options.
One numeral per chord.
The harmonic function of each chord in a key.
One function per chord.
Analyze every chord and classify the closing cadence.
The cadence is detected on the final chord pair and is null when the progression has fewer than two chords.
The options reach both analyses: applied and alternatives go to every
chord, and voicing — the pitches sounding under the progression, one
voicing per chord as Progression.voice produces them — to the
cadence, which cannot tell a perfect authentic cadence from an imperfect
one without knowing the soprano. It is the same shape
Progression.cadences takes, and the closing pair is cut from it
here; a two-element array is read as that pair itself.
Optionalkey: KeyLike
Key to analyze in, as a key name, a plain key/scale, or a Key; falls back to the carried context.
Optionalopts: ChordToRomanOptions & { alternatives?: boolean } & Omit<Applied-numeral rendering options, alternatives for the
readings both analyses turned down, and voicing for the cadence's
voice-leading detail; see AnalyzeChordOptions and
DetectCadenceOptions.
Optionalalternatives?: booleanReport the readings this analysis turned down: the function the chord's degree alone would have carried, the tonicizing reading a dominant sonority could have had, and the numerals the other rendering options would emit.
Off by default. The rationale is built from facts the analysis already established, but a rival costs work nothing else needs — a second and third numeral rendering among them — and most callers read the conclusion only.
Optionalvoicing?: number[][]Per-chord analyses and the closing cadence.
Choose one compatible scale for every chord, favoring smooth changes.
One scale choice per chord in this progression.
Classify the motion at every chord change, not only the closing one.
One entry per adjacent pair, so entry i is the motion from chord i to
chord i + 1 and the list is one shorter than the progression. A pair that
cadences not at all keeps its place with a null type, which is what lets a
caller read a cadence back against the chord it arrives on — a progression
has no beats to name it by.
The chord before each pair is supplied from the progression itself, so a cadential six-four is recognized as one wherever it stands.
Optionalkey: KeyLike
Key to analyze in, as a key name, a plain key/scale, or a Key; falls back to the carried context.
Optionalopts: { voicing?: number[][] } & Pick<voicing is the pitches sounding under the whole progression,
one voicing per chord as Progression.voice produces them, from
which each pair takes its own two — without it no authentic cadence can be
graded perfect or imperfect. alternatives collects the readings each
pair came close to, and approach is the chord sounding before the
progression began, which only the first pair has no predecessor of its
own for. See DetectCadenceOptions, whose fields these are.
One cadence per adjacent pair, in order.
A copy of this progression with one chord replaced by a substitute.
The substitutions are the ones substituteChord proposes for that chord in this progression's key, and the first of the named kind is taken. Each is spelled the way the key writes it, so the tritone substitute of G7 in C major arrives as Db7 rather than C#7.
0-based position of the chord to replace; a negative index counts from the end, as Progression.at counts it.
Which substitution relationship to realize.
Optionalopts: SubstituteOptions
melodyPcs keeps only substitutes that contain those pitch
classes, so a melody stays consonant against the new harmony; see
SubstituteOptions.
The progression with the substitute in place.
Place the chords on a regular grid, giving each the same number of beats.
The inverse of Timeline.progression, which drops the time axis again. A carried key becomes the one key region under the span.
How long each chord sounds.
The timeline.
Transpose every chord by a number of semitones.
A carried key moves with the chords, so the progression keeps its degrees and functions in the new key.
The signed semitone offset.
The transposed progression.
Transpose every chord by a spelled interval.
Unlike Progression.transpose, which picks letters from a semitone count, the interval's diatonic number decides them, so a progression taken up an augmented fourth is spelled with sharps and one taken up a diminished fifth with flats. A carried key moves with the chords.
An interval name (e.g. 'A4', '-m3'), plain interval
data, or an Interval; a descending interval moves down.
The transposed progression.
Transpose the progression so that its key becomes target.
The interval between the two tonics moves the chords and decides their
spelling, so moving C major to Gb major writes flats while moving it to F#
major writes sharps. The result carries target itself, mode included: the
chords move by interval but the key is replaced rather than transposed, so
a target in another mode — a relative, parallel, or modal key — is the key
the progression is then analyzed in.
The transposed progression, carrying target as its key.
The chord symbols separated by spaces, so a template literal or a log line reads as the progression.
The symbols in order, e.g. 'C Am F G'.
The plain progression data, for JSON serialization.
Private class fields do not serialize, so this preserves both the chord
data and any carried key in JSON.stringify(progression).
The chord data sequence and the carried key, if any.
An immutable ordered sequence of chords, optionally carrying a Key context shared by its analysis methods.
Example