@libraz/libcantus - v1.1.0
    Preparing search index...

    Class Progression

    An immutable ordered sequence of chords, optionally carrying a Key context shared by its analysis methods.

    import { Key } from '@libraz/libcantus';
    const key = Key.major('C');
    key.chord(2).progressionTo(key.chord(5), key.chord(1)).roman();
    // ['ii', 'V', 'I']
    Index
    • get chords(): readonly Chord[]

      The chord sequence.

      The array is the progression's own and is frozen rather than copied, so reading it in a loop stays linear.

      Returns readonly Chord[]

    • Start 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.

      Parameters

      • chords: readonly Chord[]

        The chords in order; the array is copied.

      • Optionalkey: KeyLike

        Optional key context for the analysis methods.

      Returns Progression

      The progression.

      import { Chord, Key, Progression } from '@libraz/libcantus';
      Progression.of([Chord.parse('C'), Chord.parse('G7')], Key.major('C')).roman();
      // ['I', 'V7']
    • Build 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.

      Parameters

      • spans: readonly ChordSpan[]

        The chord spans, in order.

      • Optionalkey: KeyLike

        Optional key context for the analysis methods.

      Returns Progression

      The progression.

      import { generateProgression, Key, Progression } from '@libraz/libcantus';
      const key = Key.major('C');
      const spans = generateProgression({ key, style: 'dance', bars: 4 });
      Progression.fromSpans(spans, key).roman();
    • The chord at an index.

      Parameters

      • index: number

        0-based position; a negative index counts from the end.

      Returns Chord | undefined

      The chord, or undefined when the index is out of range.

    • 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.

      Parameters

      Returns boolean

      True when the chord sequences match.

    • 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.

      Parameters

      • fn: (chord: Chord, index: number) => Chord

        Called with each chord and its 0-based index.

      Returns Progression

      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.

      Parameters

      • pred: (chord: Chord, index: number) => boolean

        Called with each chord and its 0-based index.

      Returns Progression

      The filtered progression, empty when nothing is accepted.

      import { Chord, Key, Progression } from '@libraz/libcantus';
      const progression = new Progression(
      [Chord.parse('C'), Chord.parse('Am'), Chord.parse('F'), Chord.parse('G')],
      Key.major('C'),
      );
      progression.filter((chord) => chord.quality === 'maj').toString(); // 'C F G'
    • 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.

      Parameters

      • Optionalstart: number

        First chord of the stretch; defaults to the beginning.

      • Optionalend: number

        One past the last chord; defaults to the end.

      Returns Progression

      The sliced progression.

      import { Chord, Key, Progression } from '@libraz/libcantus';
      const progression = new Progression(
      [Chord.parse('C'), Chord.parse('Am'), Chord.parse('F')],
      Key.major('C'),
      );
      progression.slice(1).toString(); // 'Am F'
      progression.slice(0, 2).toString(); // 'C Am'
    • 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.

      Parameters

      • other: Progression | readonly Chord[]

        The chords to append, as a progression or a plain array.

      Returns Progression

      The joined progression.

      import { Key } from '@libraz/libcantus';
      const key = Key.major('C');
      key.progression('I', 'vi').concat(key.progression('IV', 'V')).roman();
      // ['I', 'vi', 'IV', 'V']
    • 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.

      Parameters

      • chord: Chord

        The chord to look for.

      Returns number

      The 0-based position, or -1 when the progression holds no such chord.

      import { Chord, Progression } from '@libraz/libcantus';
      const progression = new Progression([Chord.parse('C'), Chord.parse('G7')]);
      progression.indexOf(Chord.of('G', 'dom7')); // 1
      progression.indexOf(Chord.parse('F')); // -1
    • Voice the progression with smooth voice leading.

      Parameters

      • Optionalopts: VoicingOptions

        Voicing options; defaults to four SATB voices.

      Returns number[][]

      One ascending voicing (MIDI pitches) per chord.

      If any chord admits no voicing within the given ranges.

    • The Roman numeral of each chord in a key.

      Parameters

      • 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.

      Returns string[]

      One numeral per chord.

      If no key is given and none is carried.

    • 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.

      Parameters

      • 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<
            DetectCadenceOptions,
            "voicing",
        > & { voicing?: number[][] }

        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?: boolean

          Report 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.

          false
          
        • Optionalvoicing?: number[][]

      Returns { chords: ChordAnalysis[]; cadence: CadenceResult | null }

      Per-chord analyses and the closing cadence.

      If no key is given and none is carried.

      import { Chord, Key, Progression } from '@libraz/libcantus';
      const progression = new Progression([Chord.parse('G7'), Chord.parse('C')], Key.major('C'));
      progression.analyze(undefined, { voicing: progression.voice() }).cadence?.strength;
      // 'perfect'
    • 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.

      Parameters

      • 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<
            DetectCadenceOptions,
            "approach"
            | "alternatives",
        >

        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.

      Returns CadenceResult[]

      One cadence per adjacent pair, in order.

      If no key is given and none is carried.

      import { Chord, Key, Progression } from '@libraz/libcantus';
      const progression = new Progression(
      [Chord.parse('C'), Chord.parse('F'), Chord.parse('G7'), Chord.parse('C')],
      Key.major('C'),
      );
      progression.cadences().map((cadence) => cadence.type); // [null, 'half', 'authentic']
    • 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.

      Parameters

      • index: number

        0-based position of the chord to replace; a negative index counts from the end, as Progression.at counts it.

      • type: SubstitutionType

        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.

      Returns Progression

      The progression with the substitute in place.

      If the index names no chord, if the progression carries no key context, or if that chord has no substitution of the named kind.

      import { Chord, Key, Progression } from '@libraz/libcantus';
      const progression = new Progression([Chord.parse('G7'), Chord.parse('C')], Key.major('C'));
      progression.substitute(0, 'tritone').toString(); // 'Db7 C'
    • 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.

      Parameters

      • beatsEach: number

        How long each chord sounds.

      Returns Timeline

      The timeline.

      If beatsEach is not a positive finite number of beats.

      import { Chord, Key, Progression } from '@libraz/libcantus';
      const progression = new Progression([Chord.parse('C'), Chord.parse('G7')], Key.major('C'));
      progression.timeline(4).at(5)?.symbol(); // 'G7'
    • 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.

      Parameters

      • semitones: number

        The signed semitone offset.

      Returns Progression

      The transposed progression.

      import { Chord, Progression } from '@libraz/libcantus';
      new Progression([Chord.parse('C'), Chord.parse('G')]).transpose(2).toString(); // 'D A'
    • 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.

      Parameters

      • interval: IntervalLike

        An interval name (e.g. 'A4', '-m3'), plain interval data, or an Interval; a descending interval moves down.

      Returns Progression

      The transposed progression.

      import { Chord, Progression } from '@libraz/libcantus';
      new Progression([Chord.parse('C'), Chord.parse('G7')]).transposeBy('A4').toString();
      // 'F# C#7'
    • 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.

      Parameters

      • target: KeyLike

        The key the transposed progression should be in, as a key name, a plain key/scale, or a Key.

      Returns Progression

      The transposed progression, carrying target as its key.

      If the progression carries no key context to measure from.

      import { Chord, Key, Progression } from '@libraz/libcantus';
      const progression = new Progression([Chord.parse('C'), Chord.parse('G7')], Key.major('C'));
      progression.transposeTo(Key.major('Eb')).toString(); // 'Eb Bb7'
    • The chord symbols separated by spaces, so a template literal or a log line reads as the progression.

      Returns string

      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).

      Returns ProgressionData

      The chord data sequence and the carried key, if any.