Tones¶
- class pytheory.tones.Interval[source]¶
Bases:
objectNamed constants for common musical intervals (in semitones).
- UNISON = 0¶
- MINOR_SECOND = 1¶
- MAJOR_SECOND = 2¶
- MINOR_THIRD = 3¶
- MAJOR_THIRD = 4¶
- PERFECT_FOURTH = 5¶
- TRITONE = 6¶
- PERFECT_FIFTH = 7¶
- MINOR_SIXTH = 8¶
- MAJOR_SIXTH = 9¶
- MINOR_SEVENTH = 10¶
- MAJOR_SEVENTH = 11¶
- OCTAVE = 12¶
- class pytheory.tones.Tone(name, *, alt_names: list[str] | None = None, octave: int | None = None, system: str | object = 'western', _validate: bool = True)[source]¶
Bases:
object- __init__(name, *, alt_names: list[str] | None = None, octave: int | None = None, system: str | object = 'western', _validate: bool = True) None[source]¶
Initialize a Tone with a name, optional octave, and musical system.
- Parameters:
name – The note name as a string (
"C","C#4") or an int for numbered systems (0,11). Ints are converted to strings and wrapped to the system’s range (e.g. 22 in a 22-tone system becomes 0 at octave+1).alt_names – Alternate spellings for this tone (e.g. enharmonics).
octave – The octave number. Overrides any octave parsed from name.
system – The tuning system, either as a string key (
"western") or aToneSysteminstance.
- property system: object¶
The
ToneSystemassociated with this tone.Lazily resolved from
system_nameon first access and cached.
- property scientific: str¶
Scientific pitch notation (e.g.
'C4','A#3').This is the default notation used throughout PyTheory — note name followed by octave number. Middle C is C4. Same as
full_name.
- property helmholtz: str¶
Helmholtz pitch notation.
The older European convention still used in some contexts:
C2 →
CC(sub-contra)C3 →
C(great octave)C4 →
c(small octave / middle C)C5 →
c'(one-line)C6 →
c''(two-line)C7 →
c'''
Accidentals are preserved as-is (e.g.
c#').Example:
>>> Tone.from_string("C4").helmholtz 'c' >>> Tone.from_string("C3").helmholtz 'C' >>> Tone.from_string("C5").helmholtz "c'" >>> Tone.from_string("A2").helmholtz 'AA'
- property letter: str¶
The letter name without any accidental.
Example:
>>> Tone.from_string("C#4").letter 'C' >>> Tone.from_string("Bb4").letter 'B' >>> Tone.from_string("G4").letter 'G'
- property enharmonic: str | None¶
The enharmonic equivalent of this tone, or None if there isn’t one.
Returns the alternate spelling: C# → Db, Db → C#, etc. Natural notes (C, D, E, F, G, A, B) have no enharmonic.
Example:
>>> Tone.from_string("C#4").enharmonic 'Db'
- property solfege: str¶
Map Western note names to fixed-Do solfege syllables.
Uses fixed Do system where C is always Do regardless of key.
C->Do, D->Re, E->Mi, F->Fa, G->Sol, A->La, B->Ti
Sharps: C#->Di, D#->Ri, F#->Fi, G#->Si, A#->Li
Flats: Db->Ra, Eb->Me, Gb->Se, Ab->Le, Bb->Te
Returns the note name unchanged if the system isn’t western or the name isn’t recognized.
Example:
>>> Tone.from_string("C4").solfege 'Do' >>> Tone.from_string("F#4").solfege 'Fi'
- classmethod from_string(s: str, system: str | object | None = None) Tone[source]¶
Create a Tone by parsing a string like
'C#4'or'Bb'.- Parameters:
s – A note string, optionally including an octave number.
system – The tuning system to associate with the tone.
- Returns:
A new
Toneinstance.
- classmethod from_tuple(t: tuple[str, ...]) Tone[source]¶
Create a Tone from a tuple of
(name, *alt_names).- Parameters:
t – A tuple where the first element is the primary name and any remaining elements are alternate names (enharmonics).
- Returns:
A new
Toneinstance.
- classmethod from_frequency(hz: float, system: str | object = 'western') Tone[source]¶
Create a Tone from a frequency in Hz.
Finds the nearest note in 12-TET tuning (A4=440Hz).
Example:
>>> Tone.from_frequency(440) <Tone A4> >>> Tone.from_frequency(261.63) <Tone C4>
- classmethod from_midi(note_number: int, system: str | object = 'western') Tone[source]¶
Create a Tone from a MIDI note number.
MIDI note 60 = C4 (middle C), 69 = A4 (440 Hz).
Example:
>>> Tone.from_midi(60) <Tone C4> >>> Tone.from_midi(69) <Tone A4>
- classmethod from_index(i: int, *, octave: int, system: object, prefer_flats: bool = False) Tone[source]¶
Create a Tone from its index within a tuning system.
- Parameters:
i – The index of the tone in the system’s tone list.
octave – The octave number.
system – The
ToneSysteminstance.prefer_flats – If True and the tone has a flat spelling, use it instead of the default sharp spelling.
- Returns:
A new
Toneinstance.
- add(interval: int, *, prefer_flats: bool = False) Tone[source]¶
Return a new Tone that is interval semitones above this one.
- Parameters:
interval – Number of semitones to add (positive = up).
prefer_flats – If True, use flat spellings (Bb, Eb) instead of sharp spellings (A#, D#) for accidentals.
- Returns:
A new
Toneinstance.
- subtract(interval: int) Tone[source]¶
Return a new Tone that is interval semitones below this one.
- Parameters:
interval – Number of semitones to subtract (positive = down).
- Returns:
A new
Toneinstance.
- interval_to(other: Tone) str[source]¶
Name the interval between this tone and another.
Returns a string like
"perfect 5th","major 3rd", or"octave". For intervals larger than an octave, returns the compound form (e.g."minor 2nd + 1 octave").Example:
>>> C4.interval_to(G4) 'perfect 5th' >>> C4.interval_to(C5) 'octave'
- property midi: int | None¶
MIDI note number (C4 = 60, A4 = 69).
The MIDI standard assigns integer note numbers from 0–127. Middle C (C4) is 60, and each semitone increments by 1.
- Returns:
the MIDI note number, or None if no octave is set.
- Return type:
- transpose(semitones: int) Tone[source]¶
Return a new Tone transposed by the given number of semitones.
Alias for
tone + semitones/tone - semitones. Positive values transpose up, negative values transpose down.
- cents_difference(other: Tone, *, temperament: str = 'equal') float[source]¶
Difference in cents between this tone and another.
One semitone = 100 cents. Musicians use cents to measure fine pitch differences — e.g. comparing equal temperament to Pythagorean tuning, or checking how far out of tune a note is.
- Parameters:
other – The tone to compare against.
temperament – Tuning temperament for both tones.
- Returns:
Signed float — positive means other is higher.
Example:
>>> a4 = Tone.from_string("A4", system="western") >>> a4.cents_difference(a4 + 1) # one semitone 100.0 >>> a4_pyth = a4.pitch(temperament="pythagorean") >>> a4_equal = a4.pitch(temperament="equal")
- circle_of_fifths() list[Tone][source]¶
The circle of fifths starting from this tone.
Each step ascends by a perfect fifth (7 semitones in 12-TET). After N steps (where N = number of tones in the system) you return to the starting tone. The circle of fifths is the backbone of Western harmony — it determines key signatures, chord relationships, and modulation paths.
- Returns:
A list of Tones (12 for Western, N for other systems).
- circle_of_fourths() list[Tone][source]¶
The circle of fourths starting from this tone.
Each step ascends by a perfect fourth — the reverse direction of the circle of fifths.
- Returns:
A list of Tones (12 for Western, N for other systems).
- property frequency: float¶
The frequency of this tone in Hz (equal temperament, A4=440).
The result is cached after the first computation.
- overtones(n: int = 8) list[float][source]¶
The first n overtones (harmonic series) of this tone.
The harmonic series is the foundation of timbre and consonance. When a string or air column vibrates, it produces not just the fundamental frequency but also integer multiples: 2f, 3f, 4f…
The intervals between consecutive harmonics form the basis of Western harmony:
Harmonic Ratio Interval from fundamental 1 1:1 Unison (the fundamental) 2 2:1 Octave 3 3:1 Octave + perfect 5th 4 4:1 Two octaves 5 5:1 Two octaves + major 3rd 6 6:1 Two octaves + perfect 5th 7 7:1 Two octaves + minor 7th (slightly flat) 8 8:1 Three octaves
The reason a perfect fifth sounds consonant is that the 3rd harmonic of the lower note aligns with the 2nd harmonic of the upper note (when the upper note is a fifth above). More shared harmonics = more consonance.
- Parameters:
n – Number of harmonics to return (default 8).
- Returns:
List of frequencies in Hz.