TonalContext
Creating a TonalContext
Section titled “Creating a TonalContext”A TonalContext provides a context against which to evaluate the position and behaviour of notes “in” a key or mode. It exposes the following public fields:
tonic: NamedTuple # with fields letter: str, accidental: int, chroma: intmode: intSince tonic is a named tuple, its fields are accessed with ordinary attribute syntax: context.tonic.letter, context.tonic.chroma.
Class Constructor
Section titled “Class Constructor”TonalContext(chroma: int, mode: int)You can create a TonalContext directly via the class constructor, from the pitch chroma of its tonic degree, and a “mode number” using the following table:
| Lydian | 0 |
| Ionian | 1 |
| Mixolydian | 2 |
| Dorian | 3 |
| Aeolian | 4 |
| Phrygian | 5 |
| Locrian | 6 |
context = TonalContext(2, 1) # D major
p = SPN.to_pitch("F4")p.snap_to(context) # F#4from_strings
Section titled “from_strings”TonalContext.from_strings(tonic: str, mode: str) -> TonalContextThe more intuitive way to initialise a TonalContext. Takes the name of the tonic pitch class and the name of the mode as strings. Can be “major” or “minor”, or a traditional modal name like “dorian” or “ionian”. Case-insensitive. Raises a ValueError if either string is invalid.
context = TonalContext.from_strings("G", "minor")
p = SPN.to_pitch("B4")p.snap_to(context) # Bb4Methods
Section titled “Methods”Most of TonalContext’s methods are usually more conveniently accessed from the Pitch vectors they act on rather than the class itself, but are available nonetheless. TonalContext.degree_chroma is only available as a method directly on a TonalContext instance, however.
degree_number
Section titled “degree_number”TonalContext.degree_number(p: Pitch) -> intReturns the scale degree (0-indexed, such that the tonic is 0) of the passed in Pitch vector in the current TonalContext.
context = TonalContext.from_strings("C", "major")
p = SPN.to_pitch("C4")context.degree_number(p) # 0
p = SPN.to_pitch("D4")context.degree_number(p) # 1
p = SPN.to_pitch("D#4")context.degree_number(p) # still 1 (just an altered variant)degree_alteration
Section titled “degree_alteration”TonalContext.degree_alteration(p: Pitch) -> intReturns the scale degree alteration represented by a Pitch in the current TonalContext, e.g. C# is a raised note in the key of C major.
- 0 represents a diatonic degree.
- +1 and -1 represent raised and lowered degrees respectively.
- +2 and -2 represent degrees too sharp or too flat to belong in a given
TonalContext.
context = TonalContext.from_strings("G", "minor")
p = SPN.to_pitch("Bb4")context.degree_alteration(p) # 0, Bb is diatonic in G minor
p = SPN.to_pitch("B4")context.degree_alteration(p) # 1, B is raised in G minor
p = SPN.to_pitch("Bbb4")context.degree_alteration(p) # -2, Bbb is too flat for this contextdegree_chroma
Section titled “degree_chroma”TonalContext.degree_chroma(degree: int, alteration: int = 0) -> intProduces the chroma (signed distance from C measured in perfect 5ths) of the variant of the passed-in scale degree (0-indexed so the tonic is 0) that matches the specified alteration (diatonic if unspecified) with respect to the TonalContext.
context = TonalContext.from_strings("G", "minor")
context.degree_chroma(0) # 1, the chroma of Gcontext.degree_chroma(1) # 3, the chroma of Acontext.degree_chroma(2) # -2, the chroma of Bbcontext.degree_chroma(3) # 0, the chroma of Ccontext.degree_chroma(3, 1) # 7, the chroma of C#snap_diatonic
Section titled “snap_diatonic”TonalContext.snap_diatonic(p: Pitch) -> PitchSnaps the passed-in Pitch vector to the diatonic position for that letter-name in
the current TonalContext. Returns the result as a new Pitch:
context = TonalContext.from_strings("C", "major")p = SPN.to_pitch("F#4")
p = context.snap_diatonic(p) # p now points to F4