subsequence.chords
The API reference for Chord, parse_chord, and register_chord_quality.
Chord
class Chord(root_pc: int, quality: str)
Represents a chord as a root pitch class and quality.
Members: bass_note, intervals, name, quality, root_note, root_pc, tones
Chord.root_pc
Chord.root_pc: int
Chord.quality
Chord.quality: str
Chord.intervals
Chord.intervals() -> typing.List[int]
Return the chord intervals for this chord quality.
Chord.tones
Chord.tones(
root: int,
inversion: int = 0,
count: typing.Optional[int] = None,
) -> typing.List[int]
Return MIDI note numbers for chord tones starting from a root.
Finds the MIDI note corresponding to the chord's root pitch class that is
closest to the provided root argument.
Parameters
root: MIDI note number (e.g., 60 = middle C) to centre the chord around.inversion: Chord inversion (0 = root position, 1 = first, 2 = second, ...). Wraps around for values >= number of notes.count: Number of notes to return. When set, the chord intervals cycle into higher octaves untilcountnotes are produced. WhenNone(default), returns the natural chord tones. Near the top or the bottom of the keyboard a tone folds back by octaves, and one that lands on a pitch the chord already holds is left out, so fewer thancountcan come back.
Returns
typing.List[int]: List of MIDI note numbers for chord tones
Example
chord = Chord(root_pc=0, quality="major") # C major
chord.tones(root=60) # [60, 64, 67] - root position around C4
chord.tones(root=62) # [60, 64, 67] - still finds C4 as closest root
chord.tones(root=70) # [72, 76, 79] - finds C5 as closest root
Chord.root_note
Chord.root_note(root_midi: int) -> int
Return the MIDI note number for the chord root nearest to root_midi.
This is equivalent to self.tones(root_midi)[0] but makes intent
explicit when you only need the single root pitch.
Parameters
root_midi: Reference MIDI note number used to find the closest octave of this chord's root pitch class.
Returns
int: MIDI note number of the chord root.
Example
chord = Chord(root_pc=4, quality="major") # E major
chord.root_note(60) # → 64 (E4, nearest to C4)
chord.root_note(69) # → 64 (E4, nearest to A4)
Chord.bass_note
Chord.bass_note(root_midi: int, octave_offset: int = -1) -> int
Return the chord root shifted by a number of octaves.
Commonly used to produce a bass register note one or two octaves below the chord voicing.
Parameters
root_midi: Reference MIDI note number (passed toroot_note).octave_offset: Octaves to shift; negative moves down (default-1).
Returns
int: MIDI note number of the chord root in the target register.
Example
chord = Chord(root_pc=4, quality="major") # E major
chord.bass_note(64) # → 52 (E3, one octave down from E4)
chord.bass_note(64, -2) # → 40 (E2, two octaves down)
Chord.name
Chord.name() -> str
Return a human-friendly chord name.
A registered quality without a suffix prints as root(quality)
(e.g. "C(quartal)") rather than masquerading as a plain major.
parse_chord
parse_chord(name: str) -> Chord
Parse a chord name like "Cm7" or "Dbmaj7" into a Chord.
The name is a root note (A–G with an optional # or b) followed
by a quality suffix: "" major, m minor, dim diminished,
+/aug augmented, 7 dominant 7th, maj7 major 7th, m7 minor
7th, m7b5/ø half-diminished 7th, sus2, sus4. A few common
alternates (min, -, M7, …) are accepted too.
Raises ValueError for anything it can't read, so a typo surfaces at the
call site rather than as a silently wrong chord.
Example
parse_chord("Cm7") # → Chord(root_pc=0, quality="minor_7th")
parse_chord("Dbmaj7") # → Chord(root_pc=1, quality="major_7th")
parse_chord("F#") # → Chord(root_pc=6, quality="major")
register_chord_quality
register_chord_quality(
name: str,
intervals: typing.List[int],
suffix: typing.Optional[str] = None,
) -> None
Register a custom chord quality for use everywhere chords are used.
The counterpart to subsequence.intervals.register_scale - it opens
the quality table so quartal stacks, clusters, and extended chords become
first-class symbolic chords: they work in progressions, graphs, voice
leading, and describe() output.
Built-in qualities (e.g. "minor") cannot be overwritten. Custom names
may be re-registered freely - live reload re-runs registration on every
save, so this must not raise.
Parameters
name: Quality name (used asChord(root_pc, quality=name)).intervals: Semitone offsets from the root (e.g.[0, 5, 10]for a quartal stack,[0, 3, 7, 10, 14]for a minor 9th). Must start with 0, ascend strictly, and stay within 0–24 (extensions reach past the octave).suffix: Optional chord-name suffix. When given,parse_chord()accepts"A" + suffixandChord.name()prints it - soregister_chord_quality("minor_9th", [0, 3, 7, 10, 14], suffix="m9")makes"Am9"parse from then on. Must not collide with a built-in suffix.
Example
import subsequence
subsequence.register_chord_quality("quartal", [0, 5, 10], suffix="q4")
subsequence.parse_chord("Dq4") # → Chord(root_pc=2, quality="quartal")