TonalVector
TonalVector()A tuple of form (d_iatonic, c_hromatic, (o_ctave)), representing either a pitch or interval (or both). TonalVector implements tonal arithmetic with dunder methods, allowing use of standard operators (+, -, =, <, >).
TonalVector is the WSMN implementation of both Tone and Interval:
>>> isinstance(TonalVector((0, 0)), Tone)
True
>>> isinstance(TonalVector((0, 0)), Interval)
TrueAttributes
| Name | Description |
|---|---|
__slots__ |
|
| tonal_system | |
| pitch | This TonalVector as a pitch (letter name, accidental, octave, …). |
| interval | This TonalVector as an interval (quality, number, …). |
| d | |
| c | |
| o | The octave designation, for a qualified vector (middle C is octave 0). |
| has_octave | True if this TonalVector carries an octave designation. |
| fifths_position | The position of this TonalVector on the circle (line) of fifths, |
Methods
| Name | Description |
|---|---|
__format__ |
Display form of the Tone, used by str.format and f-strings. |
__new__ |
TonalVector is an immutable value: a tuple, compared by value. |
| from_string | Creates and returns a TonalVector, |
| from_ly | Creates and returns an octave-qualified TonalVector, |
__repr__ |
>>> TonalVector((0,0)) |
__str__ |
Returns a string that includes the repr string, |
__add__ |
|
__sub__ |
|
| distance | Returns the smallest difference between self and x, as an interval |
| nearest_instance | Returns a Tonal Vector that has the same pitch class or interval type as x, |
__abs__ |
Returns the distance, in half-steps, from self to the origin. |
__int__ |
Returns the signed distance, in half-steps, from self to the origin. |
__gt__ |
Returns True if self is higher (in pitch) |
__lt__ |
Returns True if self is lower (in pitch) |
| transpose | Returns a TonalVector transposed by x, in the given direction. |
| inversion | Returns the inversion of self over x. |
__eq__ |
Returns True if self and x are the same (d, c, [o]) values. |
__hash__ |
Hashes as its tuple, so a TonalVector is a set member and a dict key by value. |
__call__ |
Adds another TonalVector, or applies other to this one: |
| qualify_octave | Returns a TonalVector with an octave designation set to octave. |
| conditional_qualify_octave | Returns a TonalVector with an octave designation set to octave, |
| unqualify_octave | Returns a TonalVector without an octave designation. |
__format__
__format__(spec: str)Display form of the Tone, used by str.format and f-strings.
For pitched tones, the format spec names an attribute of the Tone’s PitchRepresentation, defaulting to unicode; unpitched tones fall back to str(). str() and repr() are unaffected, so they remain available as debug forms (use {tone!r} or {tone!s} in a template to get them).
>>> from openmusickit.systems.wsmn.tonal.tonal_vector import TonalVector
>>> from openmusickit.values.tone.silent_tone import SilentTone
>>> Eb = TonalVector((2, 3))
>>> f"{Eb} major"
'E♭ major'
>>> f"{Eb:ascii} major"
'Eb major'
>>> f"{Eb!r}"
'TonalVector((2, 3))'
>>> f"{SilentTone()}"
'SilentTone()'The spec must name a string attribute of the PitchRepresentation:
>>> f"{Eb:nonsense}"
Traceback (most recent call last):
...
ValueError: ...__new__
__new__(*args)TonalVector is an immutable value: a tuple, compared by value.
The canonical way to create a TonalVector is to pass in a tuple:
>>> TonalVector((0, 0, 0))
TonalVector((0, 0, 0))For convenience, you can also pass in positional arguments:
>>> TonalVector(0, 0, 0)
TonalVector((0, 0, 0))
>>> TonalVector(0, 0) == TonalVector((0, 0))
TrueThere is no per-instance state, so nothing can be set on one:
>>> TonalVector((0, 0)).d = 1
Traceback (most recent call last):
...
AttributeError: ...
>>> TonalVector((0, 0)).anything = 1
Traceback (most recent call last):
...
AttributeError: ...from_string
from_string(
s: str,
mid_c: int = 4,
solfege_style: SolfegeStyle = SolfegeStyle.EURO_FIXED,
)Creates and returns a TonalVector, given a parsable string representation of a pitch or interval.
Accepts letter names (A-G, case-insensitive) with ASCII, Unicode, or spelled-out accidentals; numeric octave designations (mid_c sets which octave number is treated as middle C); solfege syllables; and interval names (quality abbreviation or word, plus a number or ordinal). Lilypond-style spellings (“is”/“es” accidentals, “’”/“,” octave marks) are not accepted here – use from_ly instead.
Solfege syllables are ambiguous between two conventions, selected with solfege_style: EURO_FIXED (the default) treats each syllable as a fixed diatonic letter name with an optional separate accidental (e.g. “Si” = B, “Sol#” = G-sharp); OMK_MOVEABLE treats syllables as moveable-do, with dedicated chromatic syllables of their own (e.g. “Si” = so-sharp, “Di” = do-sharp).
Examples
>>> TonalVector.from_string('C')
TonalVector((0, 0))>>> TonalVector.from_string('G#')
TonalVector((4, 8))>>> TonalVector.from_string('Bb3')
TonalVector((6, 10, -1))>>> TonalVector.from_string('perfect fifth')
TonalVector((4, 7))>>> TonalVector.from_string('M9')
TonalVector((1, 2, 1))from_ly
from_ly(s: str, prev_note: tuple[int, ...] | None = None)Creates and returns an octave-qualified TonalVector, given a Lilypond-style pitch string.
Accepts Lilypond note names using “is”/“es” accidental suffixes (including the Dutch contractions “as”/“es” for “aes”/“ees”), and either absolute (“’”/“,”) or relative (resolved against prev_note) octave marks. Since Lilypond has no notion of an octave-less (abstract) pitch, the result is always octave-qualified – with no octave mark and no prev_note, the pitch is assumed to be in Lilypond’s default octave (OMK octave 0).
Relative octaves follow Lilypond’s rule: the note goes in whichever octave puts its letter name within a fourth of prev_note, ignoring accidentals, and any octave marks shift it from there.
Examples
>>> TonalVector.from_ly('cis')
TonalVector((0, 1, 0))>>> TonalVector.from_ly("g'")
TonalVector((4, 7, 1))>>> TonalVector.from_ly("g", prev_note=TonalVector((0, 0, 0)))
TonalVector((4, 7, -1))>>> TonalVector.from_ly("as")
TonalVector((5, 8, 0))__repr__
__repr__()>>> TonalVector((0,0))
TonalVector((0, 0))>>> TonalVector((2,4,1))
TonalVector((2, 4, 1))__str__
__str__()Returns a string that includes the repr string, along with human readable pitch and interval annotations in a Python-style inline comment.
This is a debug form. Note that f-strings and str.format do not use it: they go through Tone.__format__, which gives the display form (pitch.unicode by default).
Examples
>>> print(TonalVector((0,1)))
TonalVector((0, 1)) # C♯
>>> f"{TonalVector((0,1))}"
'C♯'>>> print(TonalVector((2,3,1)))
TonalVector((2, 3, 1)) # E♭5__add__
__add__(x: tuple[int, ...])Examples
>>> TonalVector((0,1)) + TonalVector((1,1))
TonalVector((1, 2))>>> TonalVector((6,11,1)) + TonalVector((1,1))
TonalVector((0, 0, 2))__sub__
__sub__(x: tuple[int, ...])Examples
>>> TonalVector((0,1)) - TonalVector((1,1))
TonalVector((6, 0))>>> TonalVector((6,11,1)) - TonalVector((1,1))
TonalVector((5, 10, 1))>>> abs(TonalVector((6,11,1)) - TonalVector((1,1,0))) == abs(TonalVector((1,1,0)) - TonalVector((6,11,1)))
Truedistance
distance(x: tuple[int, ...])Returns the smallest difference between self and x, as an interval (the absolute distance: never larger than a tritone for abstract vectors).
Examples
>>> TonalVector((0,0,0)).distance(TonalVector((4,7,0)))
TonalVector((4, 7, 0))>>> TonalVector((4,7,0)).distance(TonalVector((0,0,0)))
TonalVector((4, 7, 0))>>> TonalVector((0,0)).distance(TonalVector((4,7)))
TonalVector((3, 5))nearest_instance
nearest_instance(x: tuple[int, ...])Returns a Tonal Vector that has the same pitch class or interval type as x, closest to self.
Examples
>>> TonalVector((0,0)).nearest_instance(TonalVector((1,1,-3)))
TonalVector((1, 1))>>> TonalVector((0,0)).nearest_instance(TonalVector((6,11,3)))
TonalVector((6, 11))>>> TonalVector((0,0,0)).nearest_instance(TonalVector((1,1,-3)))
TonalVector((1, 1, 0))>>> TonalVector((0,0,0)).nearest_instance(TonalVector((6,11,3)))
TonalVector((6, 11, -1))__abs__
__abs__()Returns the distance, in half-steps, from self to the origin.
Examples
>>> abs(TonalVector((0,0,-1)))
12>>> abs(TonalVector((0,0,1)))
12__int__
__int__()Returns the signed distance, in half-steps, from self to the origin.
Examples
>>> int(TonalVector((0,0,-1)))
-12>>> int(TonalVector((0,0,1)))
12__gt__
__gt__(x: tuple[int, ...])Returns True if self is higher (in pitch) or larger (in interval size) than x, otherwise False.
Examples
>>> TonalVector((1,1,0)) > TonalVector((0,0,0))
True>>> TonalVector((2,4,1)) > (3,5,1)
False>>> TonalVector((3,6,1)) > 6
True__lt__
__lt__(x: tuple[int, ...])Returns True if self is lower (in pitch) or smaller (in interval size) than x, otherwise False.
Examples
>>> TonalVector((1,1,0)) < TonalVector((0,0,0))
False>>> TonalVector((2,4,1)) < (3,5,1)
True>>> TonalVector((3,6,1)) < 6
Falsetranspose
transpose(x: tuple[int, ...], direction: TonalDirection = TonalDirection.UP)Returns a TonalVector transposed by x, in the given direction.
Examples
>>> TonalVector((0,0)).transpose(TonalVector((1,1)))
TonalVector((1, 1))inversion
inversion(x: tuple[int, ...] = (0, 0))Returns the inversion of self over x.
When x is unspecified, returns the inversion of self over the origin, which is equivalent to the standard definition of inverting an interval.
Examples
>>> TonalVector((2,4)).inversion() # Maj3 --> min6
TonalVector((5, 8))>>> TonalVector((5,8)).inversion() # min6 --> Maj3
TonalVector((2, 4))>>> TonalVector((3,6)).inversion() # Aug4 --> dim5 (tritone)
TonalVector((4, 6))>>> TonalVector((0,1,0)).inversion((0,0,0)) # augment unison --> diminished octave
TonalVector((0, 11, 0))__eq__
__eq__(x)Returns True if self and x are the same (d, c, [o]) values. Can compare with TonalVectors and plain (d, c, [o]) tuples.
Enharmonic equivalents are not equal (C♯ is not D♭); compare half-step values with int() for that.
Examples
>>> TonalVector((0,1,0)) == (0,1,0)
True>>> TonalVector((0,1)) == TonalVector((1,1))
False>>> TonalVector((0,1)) == 1
False>>> int(TonalVector((0,1))) == int(TonalVector((1,1)))
True__hash__
__hash__()Hashes as its tuple, so a TonalVector is a set member and a dict key by value.
>>> hash(TonalVector((0, 0))) == hash((0, 0))
True
>>> len({TonalVector((0, 0)), TonalVector(0, 0)})
1__call__
__call__(other)Adds another TonalVector, or applies other to this one: C(maj) realizes a chord type at C, so a chord reads root first.
>>> from openmusickit.systems.wsmn.tonal.symbols import C, M3, maj
>>> C(M3)
TonalVector((2, 4))
>>> str(C(maj))
'C'qualify_octave
qualify_octave(octave: int = 0)Returns a TonalVector with an octave designation set to octave.
Example
>>> TonalVector((1, 2)).qualify_octave()
TonalVector((1, 2, 0))>>> TonalVector((3, 4)).qualify_octave(2)
TonalVector((3, 4, 2))>>> TonalVector((1, 2, 1)).qualify_octave()
TonalVector((1, 2, 0))>>> TonalVector((3, 4, -1)).qualify_octave(2)
TonalVector((3, 4, 2))conditional_qualify_octave
conditional_qualify_octave(octave: int = 0)Returns a TonalVector with an octave designation set to octave, but does not change an existing octave designation if present.
>>> TonalVector((1, 2)).conditional_qualify_octave(1)
TonalVector((1, 2, 1))
>>> TonalVector((1, 2, 0)).conditional_qualify_octave(1)
TonalVector((1, 2, 0))unqualify_octave
unqualify_octave()Returns a TonalVector without an octave designation.
Example
>>> TonalVector.unqualify_octave(TonalVector((1, 2, 3)))
TonalVector((1, 2))