Universal Music Theory Library - v0.12.0
    Preparing search index...

    Class Harmony

    Tonal harmony, as static methods: progression analysis (analyzeProgression), chord detection (detectChords, detectChordsScored), cadences, voice leading and doubling checks, secondary and borrowed chords, modulation and pivot chords, chord-scale suggestions, negative harmony, the Coltrane axis, slash chords and enharmonic respelling. Key arguments are written 'C major', 'A minor', 'D dorian'.

    Index

    Constructors

    Methods

    • Analyzes the cadence between two chords in a given key.

      Recognized cadences: Authentic (V→I), Plagal (IV→I), Minor Plagal (iv→i), Deceptive (V→vi), Half (→V, with the leading tone), Phrygian/Hyper-phrygian (♭II→I or iv→V), Picardy (minor i → major I), Backdoor (♭VII7→I), Tritone Sub (subV7→I).

      Parameters

      Returns string

    • Analyzes a progression in a given key, returning Roman-numeral-level info for each chord (function, diatonicism, borrowed/secondary flags, cadence-with-next) and a list of detected modulations (see below). After a modulation, numerals and cadences are read in the new key, and each entry's key says which key it was read in.

      Modulation: a chord foreign to the current key starts a passage held by a new key; the new key is the one with an authentic cadence (V → I) in the passage, then with its tonic chord in it, then with the best Krumhansl-Schmuckler correlation. A passage of fewer than three chords is a tonicization, not a modulation (E7 → Am inside C major). Nor is a passage whose foreign chords are all secondary dominants of the current key and after which the music returns to it: the turnaround G7 Cm7 F7 Bb7 in Bb major (VI7 ii7 V7 I7) stays in Bb, though G7 → Cm7 is a cadence in C minor. A passage that does not return (C … D7 G Em Am D7 G to the end) is a modulation.

      style: 'blues': dominant sevenths on I, IV and V belong to the key (C7, F7 and G7 in C major are I7, IV7 and V7, functions T, S and D), not secondary dominants (C7 as V7/IV) nor borrowed chords, and they do not start a modulation. I7 preceded by its ii is still V7/IV (Gm7 C7 → F7). Without the option, I7 → IV is V7/IV, as in rhythm changes.

      Harmonic rhythm: with durations (in beats, one per chord), chord changes per bar of beatsPerBar (default 4); without them, chord changes per chord, which only says how often consecutive chords differ. harmonicRhythmUnit says which.

      Numerals read back with parseRomanProgression (I7 is a dominant, Imaj7 a major seventh). A chromatic root takes its letter from the key by default (spellChordInKey: Gb in C is read F#, #IV); with spelling: 'written' every root keeps the letter of its name when the name matches its pitch (Gb in C is bV), for chords that arrive already named rather than detected.

      Parameters

      • chords: Chord[]
      • keySymbol: string
      • options: {
            beatsPerBar?: number;
            durations?: readonly number[];
            spelling?: "key" | "written";
            style?: "blues" | "tonal";
        } = {}

      Returns {
          analysis: ChordAnalysis[];
          harmonicRhythm: number;
          harmonicRhythmUnit: "per-bar" | "per-chord";
          modulations: ModulationEvent[];
      }

      • analysis: ChordAnalysis[]

        One entry per chord, in order.

      • harmonicRhythm: number

        Chord changes per bar (with durations) or per chord (without them).

      • harmonicRhythmUnit: "per-bar" | "per-chord"

        Which of the two harmonicRhythm measures.

      • modulations: ModulationEvent[]

        Key changes, in order; empty when the progression stays in the key.

    • Determines the context of a second-inversion (6/4) chord within a progression. Returns 'none' if the chord at index is not in second inversion.

      • cadential: tonic 6/4 followed by V → I.
      • pedal: bass stays the same across the 6/4 and its neighbors.
      • passing: bass moves by step through the 6/4.
      • arpeggiated: same chord repeats with different inversions.

      Parameters

      • progression: Chord[]
      • keySymbol: string
      • index: number

      Returns SixFourAnalysis

    • Analyzes a slash chord and classifies it as inversion, hybrid, polychord, or upper-structure. Returns { type: 'inversion' } for chords without a bass note.

      Given played notes, the lowest is the bass and the notes above it, without its pitch class, are read as a chord over it: C3 D4 F#4 A4 is D over C ('upper-structure', 9 #11 13), not D7/C. All the notes are read as one chord, as detectChords names it, when they are a triad, sixth or seventh on the bass (C3 E4 G4 B4 is Cmaj7, not Em over C) or when the notes above make no chord of three or more pitch classes (E3 C4 G4 is C/E, an inversion). No recognizable chord → { type: 'hybrid' }.

      Parameters

      Returns SlashAnalysis

    • Returns warnings about chord voicing: doubled leading tone, missing essential chord tones, and improper doublings relative to conventional practice.

      Parameters

      • voicing: Note[]
      • chordSymbol: Chord
      • OptionalkeySymbol: string

      Returns DoublingIssue[]

    • Checks voice leading between two chords. Emits warnings for parallel motion, voice crossing, overlap, and (when context is provided) unresolved tendency tones, hidden/direct 5ths/8ves, false relations, and doubled leading tones.

      Voices are expected to be ordered bass → soprano in both chords.

      Parameters

      • chordA: Note[]
      • chordB: Note[]
      • ruleset: "strict" | "contemporary" | "species" = 'strict'

        'strict': Bach chorale-style - all standard prohibitions enforced.

        • 'contemporary': jazz/pop - relaxes parallel 5ths/8ves and leaps.
        • 'species': minimal - no parallels, no crossing, no overlap. Full species counterpoint rules live in the counterpoint module (future phase).
      • Optionalcontext: { chordA?: Chord; chordB?: Chord; keySymbol?: string }

        Optional harmonic context enabling tendency-tone and false-relation checks.

      Returns VoiceLeadingIssue[]

    • Classifies the type of modulation between two key areas based on the transitional chords.

      • 'enharmonic': both keys have identical pitch class content.
      • 'chromatic': the tonic notes are one semitone apart.
      • 'pivot': a chord in chordsA is diatonic to keyB.
      • 'common-tone': the last chord of A and first chord of B share at least one PC.
      • 'direct': abrupt modulation, no smooth transition detected.

      Parameters

      • chordsA: Chord[]
      • chordsB: Chord[]
      • keyA: string
      • keyB: string

      Returns "chromatic" | "direct" | "pivot" | "enharmonic" | "common-tone"

    • Analyzes an array of notes and returns possible chord names. Useful for Ear Training apps or MIDI input analysis.

      Parameters

      Returns string[]

    • Reads a set of notes as chords and ranks the readings, with the reasons. Besides exact matches (those of detectChords), a reading may leave out the fifth, and an eleventh or thirteenth chord its ninth or eleventh, when at least three different notes sound. The lowest note (by pitch) is the bass. Readings are ranked by, in order: fewer omitted members, root in the bass, fewer tensions, fewer formula notes; score follows the same order (1 − 0.3 per omitted member − 0.15 off the root − 0.03 per tension, at least 0). 12-TET only: other tunings return [].

      Parameters

      Returns ChordCandidate[]

      Harmony.detectChordsScored(['E3', 'C4', 'Bb4'].map(n => parseNote(n)))[0]
      // → { name: 'C7/E', omitted: ['5'], rootInBass: false, score: 0.55, … }
    • Detects common harmonic sequences in a chord progression.

      Parameters

      Returns { confidence: number; type: string }

      • confidence: number

        0 to 1: 1 for an exact match, 0 for 'unknown'.

      • type: string

        'circle-of-fifths-descending', 'circle-of-fifths-ascending', their 'diatonic-…' forms, 'parallel-descending', 'parallel-ascending', 'pachelbel', 'romanesca' or 'unknown'.

    • Finds chords that are diatonic to both keys and can therefore serve as pivot chords for modulation between them. Returns PivotChord[] with harmonic function in each key.

      Parameters

      • keyA: string
      • keyB: string
      • type: "triad" | "seventh" = 'triad'

      Returns PivotChord[]

    • Returns all scales from the dictionary that contain every pitch class of the chord. completeness = chord notes / scale notes (how much of the scale the chord fills). Results are sorted by completeness descending.

      Parameters

      Returns { completeness: number; scale: Scale }[]

      • completeness: number

        Share of the scale's notes that the chord holds, 0 to 1.

      • scale: Scale

        A scale that holds every note of the chord.

    • Returns borrowed chords from parallel modes (Modal Interchange).

      Returns BorrowedChord[]. Each entry includes the source mode, brightness, harmonic function in the home key, whether the chord is characteristic of its source mode, and whether it is a usual borrowing (common: iv, bVI, bVII… in major; the Picardy I and dorian IV in minor). Sources: the seven modes (ionian gives the Picardy third in minor and the major chords of a church-mode key), harmonic and melodic minor, harmonic major; a mode with the home key's notes is skipped. Chords that analyzeProgression reads as diatonic are left out: in a minor key, the dominant and leading-tone chords of the harmonic minor (E7 and G#dim7 in A minor).

      Parameters

      • keySymbol: string

        e.g. 'C major', 'A minor'

      • Optionaloptions: { sources?: string[]; tuning?: TuningSystem; type?: "triad" | "seventh" }
        • Optionalsources?: string[]

          Limit results to these mode names only.

        • Optionaltuning?: TuningSystem

          Defaults to TET12; returns [] for non-12-TET.

        • Optionaltype?: "triad" | "seventh"

          'seventh' (default) or 'triad', as in Scale.getDiatonicChords.

      Returns BorrowedChord[]

    • Returns the Coltrane axis for a given key root: the three roots separated by equal major thirds (dividing the octave into thirds). Used in Coltrane Changes.

      Example: 'C' → { root: 'C', majorThirds: ['C', 'E', 'Ab'] }.

      Parameters

      • key: string

      Returns ColtraneAxis

    • Returns the two Coltrane substitutions for a chord: the other two roots on the same major-third axis, using the same chord quality as the original.

      Parameters

      • chord: Chord
      • _keySymbol: string

      Returns Chord[]

    • Returns the Negative Harmony equivalent of a chord in a given key.

      Parameters

      • chord: Chord
      • keyCenter: string

      Returns Chord

    • Applies negative harmony to each chord in the progression, preserving order.

      Parameters

      • chords: Chord[]
      • keyCenter: string

      Returns Chord[]

    • Suggests scales for improvisation over a given chord. Triads and sixth chords take the scales of their seventh chord: C as Cmaj7, Cm as Cm7 (Cm6, with the natural sixth, takes dorian or melodic minor). A chord no rule names is read by its third (major or minor scale); without a third (sus2) none is suggested.

      Parameters

      • chord: Chord
      • OptionalnextChord: Chord
      • ruleset: "modal" | "berklee" | "classical" = 'berklee'

      Returns { hint?: string; scale: string }[]

      • Optionalhint?: string

        When the scale applies: 'standard V', 'if IV chord'…

      • scale: string

        Scale name with its root: 'G mixolydian'.

    • Returns a harmonically inverted progression around axisNote. Each chord's root is reflected: newRoot = 2*axis - root (in steps). Chord quality is preserved.

      Parameters

      Returns Chord[]

    • Respells a chord's root and slash bass based on key context or melodic direction, keeping the written suffix (extensions, alterations).

      • keySymbol: spellChordInKey (root letter from the key, chord tones by interval).
      • direction: 'ascending': sharp names; 'descending': flat names (C#9 → Db9).

      Parameters

      Returns Chord

    • Respells a note based on key context or melodic direction.

      • keySymbol: the key's spelling (spellPitchInKey): scale letters, chromatic notes as the harmonic chromatic scale writes them (F# in C, Gb in Db major).
      • direction: 'ascending': prefer sharps; 'descending': prefer flats. Returns the original note if no context applies.

      Parameters

      Returns Note

    • Returns the retrograde (reversed order) of a chord progression.

      Parameters

      Returns Chord[]

    • Measures average voice-leading smoothness across a progression (0 = rough, 1 = smooth). Every pitch class of each chord moves to the nearest pitch class of the next one, and every pitch class of the next to the nearest of the previous: the mean move, in interval classes, against half an octave (the largest move). Common tones count as 0.

      Parameters

      Returns number