MIREX-style chord labels parser in Python 3 (based on ANTLR)
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
chord_labels
tests
.gitignore
ChordLabel.g4
LICENSE
MANIFEST.in
README.md
setup.cfg
setup.py

README.md

chord-labels

MIREX-style chord labels parser in Python 3 (based on ANTLR)

It allows to parse symbolic chord labels defined in [1] into pitch class sets.

For example:

  • C into [0, 4, 7].
  • C:(b3,5,b7) into [0, 3, 7, 10].
  • D:min into [2, 5, 9].
  • Eb:min7(9)/5 into [3, 5, 6, 10, 1].

How to build and use?

Install for using:

$ pip install chord-labels

Basic usage examples

TL;DR:

from chord_labels import parse_chord
assert parse_chord("C:maj7").tones == [0, 4, 7, 11]

You can parse one chord at time. The result of parse_chord() is an instance of the ChordLabel class. It provides a few properties:

  • tones - set of absolute pitch classes (C is 0)
  • tones_binary - binary list of absolute pitch classes
  • root - absolute pitch class of the root tone
  • bass - absolute pitch class of the bass tone (behind slash)
from chord_labels import parse_chord, ChordLabel

chord = parse_chord("C:maj7")

# pitch classes, root, bass, label
assert chord == ChordLabel([0, 4, 7, 11], 0, 0, 'C:maj7')

assert chord.tones == [0, 4, 7, 11]
assert chord.tones_binary == [1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1]

assert parse_chord("F#").root == 6

assert parse_chord("C#/5").bass == 8

Development

Install for development:

$ git clone https://github.com/bzamecnik/chord-labels.git
$ pip install -e chord-labels

The lexer/parser code is generated from ANTLR grammar to Python. You need antlr4 installed.

# Ubuntu:
$ sudo apt install antlr4
# OS X:
$ brew install antlr
# regenerate the files
$ python setup.py antlr

Syntax

  • The root tone is written as the natural tone name (A, B, C, D, E, D, G) with optional suffix modifiers (flat - b, sharp - #).
    • Eg. C, Eb, G#, Cbb#b
  • After the separator (:) there are other components of the chord written as numeric diatonic intervals relative to the root (with optional one or more prefix modifiers). Eg. (2, b3, 3, 4, b5, 5, #5, 6, bb7, b7, 7). The intervals can span into the second octave (eg. b9, 9, #9, 11, 13). The components are in parentheses and separated by a comma. The root tone already defined the tonic (the 1 component).
    • Eg. C:(3,5), D:(b3,b5,b7), G:(3,5,b7,9,11,13)
  • For some common chords there are "shorthands" - pre-defined sets of components identified by name. A shorthand is optional and can be combined with explicit components. Generally either a shorthand or a list of components must be present after the separator.
    • Eg. C:min = C:(b3,5), C:maj7 = C:(4,5,7)
    • Pre-defined shorthands:
      • maj = (3,5)
      • min = (b3,5)
      • dim = (b3,b5)
      • aug = (3,#5)
      • maj7 = (3,5,7)
      • min7 = (b3,5,b7)
      • 7 = (3,5,b7)
      • dim7 = (b3,b5,bb7)
      • hdim7 = (b3,b5,b7)
      • minmaj7 = (b3,5,7)
      • maj6 = (3,5,6)
      • min6 = (b3,5,6)
      • 9 = (3,5,b7,9)
      • maj9 = (3,5,7,9)
      • min9 = (b3,5,b7,9)
      • sus4 = (4,5)
  • In order to exclude some tone from the shorthand, we can prefix it with an asterisk (*).
    • Eg. C:7(*5) = C:(3,b7)
  • The syntax allows to specify some concrete inversion of the chord, ie. some ordering of the pitch class set. In particular, there can be some explicit bass tone. Similarly to common notation it marked is optionally at the end as an relative interval with modified after a slash.
    • Eg. C:maj/3 - bass tone is the third
  • As a syntax sugar, a lonely root tone symbol (with no components or a shorthand) is considered to denote the major chord.
    • Eg. C = C:maj = C:(3,5)

API

The API is currently not stable and might change without any notification.

Author & License

Enjoy and feel free to use and talk about any enhancements/bugs.

Originally this was implemented in Java chord-labels-java.

References