Wrap a key/scale and its spelled tonic.
The key/scale; its root is normalized to a pitch class.
The spelled tonic anchoring letter-name spelling.
Optionalvariant: KeyVariant
The scale form. Read from the mask when none is named: a major mask is a major key whoever built it, and a key with no form at all is a state a reader would have to guess about.
A copy of the underlying plain KeyScale.
The spelled tonic.
The tonic pitch class (0..11).
Whether the scale has a minor third and no major third.
The key signature as a signed count of sharps (positive) or flats
(negative) — the fifths value a notation format such as MusicXML writes.
A scale that is not a diatonic mode takes the signature of its parallel major or minor, so A harmonic minor reports 0: its G# is written as an accidental rather than in the signature.
The built-in scale this key's mode mask is, or undefined when no built-in scale has that mask.
Only the Western vocabulary of NAMED_SCALES answers. A mask cannot
say which tradition names it — the major scale, maqam Ajam and thaat Bilaval
are the same seven pitch classes — so the scales of WORLD_SCALES are
reached by name rather than read back from one. Where two Western names
share a mask the table's own first name answers, so a natural minor reports
'naturalMinor' rather than 'aeolian' and a major scale 'major' rather
than 'ionian'.
A copy of the underlying plain key data.
The detected scale form, when this key came from key detection.
StaticmajorA major key.
Tonic as a note name (e.g. 'Eb') or a pitch class; a numeric
root is spelled the way spelledKeyOf spells it — the side the
scale reads best from, which for a major key is the shorter signature.
The major key.
StaticminorA natural-minor key.
Tonic as a note name or a pitch class; a numeric root is spelled the way spelledKeyOf spells it, so pitch class 8 is G# minor and not Ab minor.
The minor key.
StaticnamedA key on a named scale (e.g. 'dorian', 'harmonicMinor').
The scale name, a key of the scale module's named-scale table.
Tonic as a note name or a pitch class; a numeric root is spelled the way spelledKeyOf spells it, exactly as Key.major does — pitch class 1 altered is C#, not Db.
The key.
StaticparseParse a key name, in any of the supported note-name systems.
The name is a tonic and a mode word — 'C major', 'gis moll',
'嬰ト短調', 'la minore' — and the system is detected from the name
itself unless one is given. A German name may also be written with a
hyphen ('gis-Moll'), and its case carries the mode on its own, so 'Gis'
is G sharp major and 'gis' G sharp minor; see parseKeyName for
how a name whose case and mode word disagree is read.
An English name may also name a built-in scale instead of a mode —
'D harmonic minor', 'D dorian', 'C major pentatonic' — which is what
Function.toString writes for a key that is neither a plain major nor a
plain minor, so a key survives being written down and read back. Only the
tonic's spelling survives from the name, so 'ges dur' is G flat major,
not F sharp major.
The key name.
Optionalopts: NoteNameOptions
system reads the name in that notation system instead of
detecting it.
The key.
StatictryParse a key name, reporting failure instead of throwing it.
The same reading as Key.parse, for the callers where text that does
not name a key yet is the normal state of the input rather than a fault: a
key-signature field can say what is wrong with what has been typed so far
without a try around every keystroke.
The key name.
Optionalopts: NoteNameOptions
system reads the name in that notation system instead of
detecting it.
The key, or the error explaining why the text is not one.
StaticfromThe key a key signature denotes: the inverse of Key.fifths.
A signature names two keys — three sharps is both A major and F# minor — so the mode decides which one is built. The tonic is spelled the way that key is written, including the theoretical keys past ±7 (nine sharps is D# major).
The signed number of sharps (positive) or flats (negative).
Which of the signature's two keys to build; defaults to major.
The key.
StaticofWrap an existing KeyScale, synthesizing a spelled tonic when none is
given.
The synthesized tonic is chosen the same way as for a numeric root
elsewhere, by spelledKeyOf: the side the scale reads best from.
This is what keeps Key.of(detectKey(...).scale) from handing every
downstream chord a double-sharp spelling.
A value that already carries a spelling keeps it — a key region's key, the data a key serializes to — so wrapping one is not where an Ab minor becomes a G# minor. Only a bare key/scale has a tonic chosen for it, because only a bare key/scale is missing one.
The key.
StaticfromRebuild a key from its Key.toJSON output.
The serialized key, tonic, and scale form.
The key.
StaticfromWrap plain key data, matching the fromData factory on the other classes.
The plain key, as Key.data hands it out.
The key.
StaticdetectIdentify the keys a set of pitches fits, best interpretation first.
The counterpart of Chord.detect.
MIDI pitches or bare pitch classes.
Optionalopts: DetectKeyOptions
How to weigh the input; see DetectKeyOptions.
Ranked keys (may be empty).
StaticdetectIdentify keys while retaining each candidate's score, fit, and scale form.
MIDI pitches or bare pitch classes.
Optionalopts: DetectKeyOptions
How to weigh the input; see DetectKeyOptions.
Ranked key matches (may be empty).
StaticdetectThe single best key interpretation of a pitch set.
MIDI pitches or bare pitch classes.
Optionalopts: DetectKeyOptions
How to weigh the input; see DetectKeyOptions.
The top-ranked key, or null when nothing matches.
Whether another key has the same tonic pitch class and mode.
The spelled tonic is not compared: C# major and Db major are the same key written two ways.
The key to compare.
True when tonic and mode mask both match.
The scale's pitch classes.
They come in scale-degree order by default — the tonic first, then each
scale tone above it — so D dorian starts on 2 and wraps past 11 to 0. Ask
for order: 'ascending' where the answer is a pitch-class set rather than
a scale: sorted numerically, it compares directly against what
Chord.pitchClasses reports and against any pitch-class set of the
caller's own.
Optionalopts: { order?: "degree" | "ascending" }
Set order: 'ascending' to sort the pitch classes numerically
instead of by scale degree.
One pitch class per scale degree.
The kind of pitch organisation this key's scale belongs to: the common-practice material functional harmony is defined on, a modal rotation of it, or a collection that carries no chord function of its own.
A key holds a mode mask rather than a tradition, so the mask is read the
Western way, exactly as scaleSystemOf reads a bare KeyScale: a
key built on maqam Hijaz answers 'modal', because those seven pitch
classes are also the phrygian dominant. A mask no built-in scale names has
no system at all.
The scale system, or undefined for a mask that names no built-in scale.
Whether functional (Roman-numeral) analysis describes this key.
True for the common-practice and modal systems and false for everything classed as carrying no chord function, so code about to read a pentatonic or a raga as a chord progression can ask here first instead of imposing degrees on it. The mask is read the Western way, as Key.system reads it.
True when functional harmony describes the scale.
The relative key: for a plain major or minor key, the same key signature read in the other mode.
Because the new tonic is read off the circle of fifths rather than transposed by semitones, the relative of Db major is Bb minor and not its enharmonic A# minor.
A key that is not a plain major or minor is read through the mode its third names and stepped from where its tonic stands on the circle: the relative of D dorian is F major. The shared signature does not carry over to those — D dorian is written with no accidentals and F major with one.
The relative key, always a plain major or minor key.
The parallel key: the other mode on the same tonic, which keeps this key's tonic spelling — the parallel minor of C major is C minor, never B# minor.
The parallel key, always a plain major or minor key.
The dominant key: the key a fifth above, in the mode this key's third names.
The fifth is measured from the tonic, so a key that is not a plain major or minor answers with the same move: the dominant of D dorian is A minor.
The key a fifth above.
The subdominant key: the key a fifth below, in the mode this key's third names, and the exact inverse of Key.dominantKey on the tonic spelling.
The key a fifth below.
The same sounding key written the other way round the circle of fifths.
Only a spelling within ±7 fifths is offered, because that is as far as keys are actually written: Db major answers with C# major, while C major has no second spelling at all.
The other spelling of this key, or null when it has none.
The six closely related keys, each tagged with its relation.
These are the keys the German and Japanese teaching tradition counts as a key's near relations: the relative and parallel keys, the dominant and the subdominant, and the relatives of those two. For a plain major or minor key five of them are written within one accidental of this key's signature — the relative shares it exactly and the other four stand one away; the parallel key stands three away and belongs to the set for the tonic it shares instead.
A key that is not a plain major or minor is read through the mode its third names, so its relations are walked from where its tonic stands on the circle rather than from its own signature, and those accidental counts do not describe them.
The related keys in relation order.
How another key stands to this one.
Only the identity test looks at the tonic spelling; every other relation compares tonic pitch class and mode, so C# minor and Db minor both read as the relative of E major. Both keys are read through the mode their third names, so a detected A harmonic minor stands to C major exactly as A minor does, and the answer reads the same from either side.
The key the relation is measured to.
The relation, or null when other is none of this key's related
keys.
The chords a modulation from this key into another can pivot on.
A pivot belongs to both keys at once, so it is heard as a degree of this
key and reinterpreted as a degree of the key being entered. The candidates
are this key's diatonic triads, kept when every one of their pitch classes
is also a scale tone of other; each is reported with its numeral in both
keys. A key that stacks no diatonic triads offers nothing to pivot on and
yields an empty list rather than an error.
The shared triads, ascending by their degree in this key, each chord carrying this key as its context.
A scale degree, counted from 1 the way musicians name degrees: degree(1)
is the tonic and degree(5) the dominant.
The 1-based scale degree.
The spelled note on that degree.
The key rooted on one of this key's scale degrees.
Without an explicit mode the mode is read off the diatonic triad on that
degree: a major triad gives a major key, a minor or diminished one a minor
key. So the fourth degree of A minor gives D minor while the fourth degree
of C major gives F major. A scale with no diatonic triads — anything that
is not heptatonic — falls back to this key's own mode.
The tonic is derived rather than given, so the result is respelled to its enharmonic key whenever the letter arithmetic lands past the signatures keys are written with: the fourth degree of a C blues scale reads as F# minor, not as the Gb minor and its nine flats.
The 1-based scale degree, as Key.degree counts them.
Optionalmode: KeyMode
The mode of the resulting key; inferred when omitted.
The key on that degree.
The key on whose degree n this key's tonic sits: the inverse of
Key.keyOnDegree.
D minor is the fourth degree of A minor, so D minor answers A minor here.
The 1-based degree this key's tonic should occupy in the result.
Optionalmode: KeyMode
The mode of the resulting key; defaults to this key's own mode.
The key that has this key's tonic on its nth degree.
Transpose the key by a spelled interval, keeping the spelling the interval names.
Unlike Key.transpose, which picks a letter from the semitone count, the interval's diatonic number decides the tonic's letter: G# minor down an augmented fourth is D minor, while down a diminished fifth it is Dbb minor. The mode mask is unchanged, so the scale keeps its shape.
The interval to apply, as a name ('A4', '-A4'), plain
interval data, or an Interval; a descending interval moves down.
The transposed key.
The spelled interval from this key's tonic to another key's tonic.
Both tonics are octave-less, so the interval is measured within one ascending octave: C major to Eb major is a minor third, and Eb major back to C major is a major sixth.
The key to measure to.
The interval between the two tonics.
Transpose the key by a number of semitones.
The mode mask is unchanged, so the scale keeps its shape; only the tonic moves. The tonic's letter follows the semitone count, and the result is then respelled to its enharmonic key whenever the key would not be written that way: Db major up a semitone reads as D major rather than as Ebb major and its ten flats. A key written with a signature is judged by that signature — anything within ±7 is left exactly as it is, so C major up six semitones stays F# major — and a scale that only borrows one is judged by whether its spelling needs a double accidental. A key whose enharmonic is unwritable too keeps the letter-transposed spelling.
Use Key.transposeBy to transpose by a named interval instead, which spells the tonic exactly as that interval demands.
The signed semitone offset.
The transposed key.
The key a transposing instrument's part is written in, for this key at concert pitch.
The direction is written-side: the part is transposed away from what the instrument sounds, so a B flat instrument — which sounds a major second lower than it reads — has its part written a major second higher, and a concert C major becomes D major. The tonic is spelled by the interval, so a concert E flat major reads as F major on that instrument rather than as E sharp major, and the mode mask is untouched. What the interval spells is then respelled to its enharmonic key whenever it would not be written that way, since a part is what a player is actually handed: a concert F# major on a B flat clarinet reads as A flat major rather than as a G# major with an F double sharp in its signature.
The opposite reading, a written key back to the key it sounds in, is Key.transposeBy applied to instrumentTransposition — the instrument's own written-to-sounding interval.
A built-in instrument name, or an interval naming a transposition the table does not carry.
The key the player reads.
import { Key, instrumentTransposition } from '@libraz/libcantus';
Key.major('C').forInstrument('clarinetBb').toString(); // 'D major'
Key.major('C').forInstrument('hornF').toString(); // 'G major'
Key.major('F#').forInstrument('clarinetBb').toString(); // 'Ab major'
// And back: what a part written in C major on a clarinet in A sounds as.
Key.major('C').transposeBy(instrumentTransposition('clarinetA')).toString(); // 'A major'
The spelled scale, one note per degree (e.g. C D E F G A B for C major).
Spelled octave-less notes in scale-degree order.
The spelled scale as note-name strings.
Optionalopts: NoteNameOptions
system writes the names in that notation system instead of
English, matching Function.toString.
One name per scale degree.
Spell arbitrary pitch classes the way this key writes them.
The counterpart of Key.notes for pitches that are not scale degrees: a detected pitch-class set, an analysis result, or a voicing reduced to pitch classes gets the letters and accidentals the key implies, so in F major pitch class 10 reads as Bb while 11 reads as B natural rather than as Cb.
Named for what it takes, because Key.spell already answers the scale itself.
The pitch classes, spelled in the order they are given.
Optionaltonic: NoteLike
Spelled tonic anchoring the letter names, as a note name, a MIDI number, or a Note; defaults to this key's own tonic. It has to sound this key's root pitch class, so it can only respell that tonic — a Db major key spelled from C#.
Spelled octave-less notes, in input order.
Build a chord on a scale degree, carrying this key as context.
With an explicit quality the quality's interval template is attached to the degree's diatonic root; without one the scale-correct diatonic triad is stacked (e.g. a diminished triad on the leading tone of a major key).
1-based scale degree of the chord root, as Key.degree counts them: 1 is the tonic and 5 the dominant.
Optionalquality: ChordQuality
Optional chord quality.
The chord, with this key attached.
The diatonic triad on a scale degree, carrying this key as context.
1-based scale degree of the chord root, as Key.degree counts them: 1 is the tonic and 5 the dominant.
The triad, with this key attached.
If this key's scale is not heptatonic; stacking thirds needs seven degrees. Use Key.chord with an explicit quality instead.
The diatonic seventh chord on a scale degree, carrying this key as context.
1-based scale degree of the chord root, as Key.degree counts them: 1 is the tonic and 5 the dominant.
The seventh chord, with this key attached.
If this key's scale is not heptatonic; stacking thirds needs seven degrees. Use Key.chord with an explicit quality instead.
Build the chord denoted by a Roman numeral in this key (including applied
chords such as 'V7/V'), carrying this key as context.
The Roman numeral.
The chord, with this key attached.
The augmented sixth chord of a kind, built in this key.
The three kinds share the augmented sixth between the lowered sixth degree and the raised fourth and differ in what fills it: the Italian doubles the tonic, the French adds the second degree, and the German the third. The chord is spelled as the interval demands rather than as its enharmonic dominant seventh, which is what keeps its outward resolution readable.
Which augmented sixth to build.
The chord, with this key attached.
Build a progression from Roman numerals in this key.
Each numeral is read as Key.roman reads it, applied chords included, and the progression carries this key, so it can name its own numerals, functions and cadences without being handed a key again.
The numerals, in order.
The progression, carrying this key.
Whether a pitch belongs to the scale.
A MIDI pitch, bare pitch class, or note.
True if the pitch class is a scale tone.
The nearest MIDI pitch whose pitch class is in the scale.
The search expands symmetrically outward from pitch, and a tie — an equal
distance above and below — is settled downward. A pitch already in the scale
answers itself.
The MIDI pitch to snap.
The nearest in-scale MIDI pitch.
The scale degree a pitch sits on, counted from 1: the tonic is degree 1.
A pitch outside the scale has no degree and answers null, so a caller reading a degree cannot mistake the absent answer for the tonic.
A MIDI pitch or a bare pitch class.
The 1-based degree, or null when the pitch is not a scale tone.
The plain key data, for JSON serialization.
Private class fields do not serialize, so an explicit toJSON keeps
JSON.stringify(key) from collapsing to {}. The result pairs the
KeyScale with the spelled tonic and, for a detected harmonic or melodic
minor, the scale form — everything Key.fromJSON needs to rebuild a
key that reads and prints as this one.
The key/scale, its spelled tonic, and its scale form when it has one.
The key's tonic and the scale it is read in, so a template literal or a log line reads as the key.
The scale word is a function of the scale alone — its root pitch class and mode mask — rather than of how the key was built, so two keys holding the same scale print the same name: a harmonic minor names itself one whether it was detected or asked for by name, and a mode names its mode instead of the major or minor key its third would make it. What is printed is what Key.parse reads back.
A system names the key the way that notation system writes it, including
German's case convention. The scale word is an English-only qualifier —
the other systems have no word for it — so a harmonic minor names its
parallel plain minor there.
Optionalopts: NoteNameOptions
system writes the name in that notation system instead of
English.
The name, e.g. 'C major', 'A minor' or 'gis moll'.
An immutable key/scale: a
KeyScale(root pitch class plus mode mask) paired with a spelled tonic that anchors letter-name spelling. Acts as the factory for key-aware chords.Example