Module music_df.utils.pitch_classes

Functions

def get_figured_bass_class(pitches: Sequence[int]) ‑> list[int]
Expand source code
def get_figured_bass_class(pitches: Sequence[Pitch]) -> list[Pitch]:
    """
    >>> get_figured_bass_class([60, 64, 67])
    [0, 4, 7]
    >>> get_figured_bass_class([60, 64, 67, 72])
    [0, 4, 7]
    >>> get_figured_bass_class([62, 66, 69, 74])
    [0, 4, 7]
    """
    return sorted(set(int((p - pitches[0]) % 12) for p in pitches))
>>> get_figured_bass_class([60, 64, 67])
[0, 4, 7]
>>> get_figured_bass_class([60, 64, 67, 72])
[0, 4, 7]
>>> get_figured_bass_class([62, 66, 69, 74])
[0, 4, 7]
def get_pitch_classes_as_str(pcs: Sequence[int]) ‑> str
Expand source code
def get_pitch_classes_as_str(pcs: Sequence[PitchClass]) -> str:
    """
    >>> get_pitch_classes_as_str([0, 4, 7])
    '047'
    >>> get_pitch_classes_as_str([0, 4, 7, 11])
    '047b'
    >>> get_pitch_classes_as_str([11, 11, 5, 0, 10])
    'bb50a'
    """
    return "".join(hex(p)[2:] for p in pcs)
>>> get_pitch_classes_as_str([0, 4, 7])
'047'
>>> get_pitch_classes_as_str([0, 4, 7, 11])
'047b'
>>> get_pitch_classes_as_str([11, 11, 5, 0, 10])
'bb50a'
def get_prime_form(pc_str: str, inversional_equivalence: bool = False, tet: int = 12) ‑> str
Expand source code
@lru_cache(maxsize=512)
def get_prime_form(
    pc_str: str, inversional_equivalence: bool = False, tet: int = 12
) -> str:
    """
    We put pitches in "reverse lexicographic" order.

    Not a fast implementation, but results are small, so we use lru_cache so we can
    quickly apply to large pandas series etc.

    >>> get_prime_form("047")
    '047'
    >>> get_prime_form("038")
    '047'
    >>> get_prime_form("0ab")
    '012'
    >>> get_prime_form("04689")
    '02458'
    >>> get_prime_form("02478")
    '02478'
    >>> get_prime_form("0348a")
    '02478'

    We can also use this function on scale degrees by setting `tet` to 7:
    >>> get_prime_form("024", tet=7)
    '024'
    >>> get_prime_form("025", tet=7)
    '024'
    >>> get_prime_form("035", tet=7)
    '024'

    Note that we shouldn't have to worry about scale degrees being numbered from 1 to 7
    rather than 0 to 6:
    >>> get_prime_form("247", tet=7)
    '024'
    """
    if inversional_equivalence:
        raise NotImplementedError
    input_form = [int("0x" + x, 16) for x in pc_str]
    all_forms = [input_form[i:] + input_form[:i] for i in range(len(input_form))]
    all_forms = [[(x - form[0]) % tet for x in form][::-1] for form in all_forms]
    sorted_forms = sorted(all_forms)
    return get_pitch_classes_as_str(sorted_forms[0][::-1])

We put pitches in "reverse lexicographic" order.

Not a fast implementation, but results are small, so we use lru_cache so we can quickly apply to large pandas series etc.

>>> get_prime_form("047")
'047'
>>> get_prime_form("038")
'047'
>>> get_prime_form("0ab")
'012'
>>> get_prime_form("04689")
'02458'
>>> get_prime_form("02478")
'02478'
>>> get_prime_form("0348a")
'02478'

We can also use this function on scale degrees by setting tet to 7:

>>> get_prime_form("024", tet=7)
'024'
>>> get_prime_form("025", tet=7)
'024'
>>> get_prime_form("035", tet=7)
'024'

Note that we shouldn't have to worry about scale degrees being numbered from 1 to 7 rather than 0 to 6:

>>> get_prime_form("247", tet=7)
'024'