Skip to content

AbcNotation

abc_notation

ABC notation ↔ scientific notation conversions.

The AbcNotation namespace converts between ABC notation (the music notation language used in folk-music tooling) and the scientific note names used elsewhere in tonal.

ABC notation rules in brief:

  • Uppercase letters (C, D, ...) are octave 4.
  • Lowercase letters (c, d, ...) are octave 5.
  • Apostrophes (') raise an octave each.
  • Commas (,) lower an octave each.
  • Underscores (_) are flats; carets (^) are sharps.
Example

from tonal_py import AbcNotation AbcNotation.abc_to_scientific_notation("c") # lowercase = oct 5 'C5' AbcNotation.abc_to_scientific_notation("_b") # _ = flat 'Bb5' AbcNotation.scientific_to_abc_notation("Bb4") '_B'

Source parity: @tonaljs/abc-notation

tokenize

tokenize(s: str) -> tuple[str, str, str]

Split an ABC note into (accidentals, letter, octave_marks).

Parameters:

Name Type Description Default
s str

An ABC note string.

required

Returns:

Type Description
tuple[str, str, str]

(accidentals, letter, octave_marks). All empty on invalid input.

Example

from tonal_py import AbcNotation AbcNotation.tokenize("b") ('', 'b', '') AbcNotation.tokenize("C,") ('', 'C', ',') AbcNotation.tokenize("garbage") ('', '', '')

Source code in src/tonal_py/abc_notation.py
def tokenize(s: str) -> tuple[str, str, str]:
    """Split an ABC note into `(accidentals, letter, octave_marks)`.

    Args:
        s: An ABC note string.

    Returns:
        `(accidentals, letter, octave_marks)`. All empty on invalid input.

    Example:
        >>> from tonal_py import AbcNotation
        >>> AbcNotation.tokenize("_b")
        ('_', 'b', '')
        >>> AbcNotation.tokenize("C,")
        ('', 'C', ',')
        >>> AbcNotation.tokenize("garbage")
        ('', '', '')
    """
    m = _REGEX.match(s)
    if not m:
        return ("", "", "")
    return (m.group(1), m.group(2), m.group(3))

abc_to_scientific_notation

abc_to_scientific_notation(s: str) -> str

Convert an ABC note to scientific notation.

Parameters:

Name Type Description Default
s str

ABC notation note (e.g. "c", "_b", "C,").

required

Returns:

Type Description
str

Scientific notation note name (e.g. "C5", "Bb5", "C3").

str

Empty string for invalid input.

Example

from tonal_py import AbcNotation AbcNotation.abc_to_scientific_notation("c") 'C5' AbcNotation.abc_to_scientific_notation("C") 'C4' AbcNotation.abc_to_scientific_notation("_b") 'Bb5' AbcNotation.abc_to_scientific_notation("C,") 'C3' AbcNotation.abc_to_scientific_notation("c'") 'C6'

Source code in src/tonal_py/abc_notation.py
def abc_to_scientific_notation(s: str) -> str:
    """Convert an ABC note to scientific notation.

    Args:
        s: ABC notation note (e.g. `"c"`, `"_b"`, `"C,"`).

    Returns:
        Scientific notation note name (e.g. `"C5"`, `"Bb5"`, `"C3"`).
        Empty string for invalid input.

    Example:
        >>> from tonal_py import AbcNotation
        >>> AbcNotation.abc_to_scientific_notation("c")
        'C5'
        >>> AbcNotation.abc_to_scientific_notation("C")
        'C4'
        >>> AbcNotation.abc_to_scientific_notation("_b")
        'Bb5'
        >>> AbcNotation.abc_to_scientific_notation("C,")
        'C3'
        >>> AbcNotation.abc_to_scientific_notation("c'")
        'C6'
    """
    acc, letter, oct_marks = tokenize(s)
    if letter == "":
        return ""
    o = 4
    for c in oct_marks:
        o += -1 if c == "," else 1
    if acc and acc[0] == "_":
        a = acc.replace("_", "b")
    elif acc and acc[0] == "^":
        a = acc.replace("^", "#")
    else:
        a = ""
    if ord(letter) > 96:  # lowercase letter -> octave +1, uppercase result
        return letter.upper() + a + str(o + 1)
    return letter + a + str(o)

scientific_to_abc_notation

scientific_to_abc_notation(s: str) -> str

Convert a scientific notation note to ABC notation.

Parameters:

Name Type Description Default
s str

Scientific notation note (must include octave).

required

Returns:

Type Description
str

ABC notation. Empty string for invalid input or pitch classes

str

without octaves.

Example

from tonal_py import AbcNotation AbcNotation.scientific_to_abc_notation("C5") 'c' AbcNotation.scientific_to_abc_notation("Bb4") '_B' AbcNotation.scientific_to_abc_notation("C") # no octave ''

Source code in src/tonal_py/abc_notation.py
def scientific_to_abc_notation(s: str) -> str:
    """Convert a scientific notation note to ABC notation.

    Args:
        s: Scientific notation note (must include octave).

    Returns:
        ABC notation. Empty string for invalid input or pitch classes
        without octaves.

    Example:
        >>> from tonal_py import AbcNotation
        >>> AbcNotation.scientific_to_abc_notation("C5")
        'c'
        >>> AbcNotation.scientific_to_abc_notation("Bb4")
        '_B'
        >>> AbcNotation.scientific_to_abc_notation("C")        # no octave
        ''
    """
    n = _pitch_note.note(s)
    if n.empty or n.oct is None:
        return ""
    letter, acc, oct_ = n.letter, n.acc, n.oct
    if acc and acc[0] == "b":
        a = acc.replace("b", "_")
    else:
        a = acc.replace("#", "^")
    letter_out = letter.lower() if oct_ > 4 else letter
    if oct_ == 5:
        o = ""
    elif oct_ > 4:
        o = "'" * (oct_ - 5)
    else:
        o = "," * (4 - oct_)
    return a + letter_out + o

transpose

transpose(note: str, interval: str) -> str

Transpose an ABC-notation note by an interval.

Parameters:

Name Type Description Default
note str

ABC notation note.

required
interval str

Interval string (e.g. "M3", "P5").

required

Returns:

Type Description
str

Transposed note in ABC notation.

Example

from tonal_py import AbcNotation AbcNotation.transpose("C", "M3") 'E' AbcNotation.transpose("c", "P5") 'g'

Source code in src/tonal_py/abc_notation.py
def transpose(note: str, interval: str) -> str:
    """Transpose an ABC-notation note by an interval.

    Args:
        note: ABC notation note.
        interval: Interval string (e.g. `"M3"`, `"P5"`).

    Returns:
        Transposed note in ABC notation.

    Example:
        >>> from tonal_py import AbcNotation
        >>> AbcNotation.transpose("C", "M3")
        'E'
        >>> AbcNotation.transpose("c", "P5")
        'g'
    """
    return scientific_to_abc_notation(
        _pitch_distance.transpose(abc_to_scientific_notation(note), interval)
    )

distance

distance(from_note: str, to_note: str) -> str

Find the interval between two ABC-notation notes.

Parameters:

Name Type Description Default
from_note str

ABC notation note.

required
to_note str

ABC notation note.

required

Returns:

Type Description
str

Interval name (e.g. "M3").

Example

from tonal_py import AbcNotation AbcNotation.distance("C", "e") '10M'

Source code in src/tonal_py/abc_notation.py
def distance(from_note: str, to_note: str) -> str:
    """Find the interval between two ABC-notation notes.

    Args:
        from_note: ABC notation note.
        to_note: ABC notation note.

    Returns:
        Interval name (e.g. `"M3"`).

    Example:
        >>> from tonal_py import AbcNotation
        >>> AbcNotation.distance("C", "e")
        '10M'
    """
    return _pitch_distance.distance(
        abc_to_scientific_notation(from_note), abc_to_scientific_notation(to_note)
    )