@@ -1,35 +1,15 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import copy
|
||||
from dataclasses import dataclass
|
||||
|
||||
from generator import harmony
|
||||
from generator.model import LETTERS, NATURAL, alteration, key_from_fifths, key_label, parse_pitch_name, pitch_number, rational
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class KeyProfile:
|
||||
name: str
|
||||
root: int
|
||||
fifths: int
|
||||
|
||||
KEY_PROFILES = tuple(KeyProfile(name, root, fifths) for root, (name, fifths) in enumerate((('C', 0), ('Db', -5), ('D', 2), ('Eb', -3), ('E', 4), ('F', -1), ('Gb', -6), ('G', 1), ('Ab', -4), ('A', 3), ('Bb', -2), ('B', 5))))
|
||||
TARGET_KEYS = tuple(p.name for p in KEY_PROFILES)
|
||||
TARGET_KEYS = ('C', 'Db', 'D', 'Eb', 'E', 'F', 'Gb', 'G', 'Ab', 'A', 'Bb', 'B')
|
||||
|
||||
def mod12(value: int) -> int:
|
||||
return value % 12
|
||||
|
||||
def find_key(name: str) -> KeyProfile:
|
||||
tonic = parse_pitch_name(name)
|
||||
for fifths in range(-14, 15):
|
||||
key = key_from_fifths(fifths)
|
||||
if key['tonic'] == tonic:
|
||||
return KeyProfile(name, int(NATURAL[tonic['letter']] + alteration(tonic['alter'])) % 12, fifths)
|
||||
raise ValueError(f'unsupported key signature: {name}')
|
||||
|
||||
def signed_interval(source: KeyProfile, target: KeyProfile) -> int:
|
||||
value = (target.root - source.root) % 12
|
||||
return value - 12 if value > 6 else value
|
||||
|
||||
def interval_between(source: dict, target: dict) -> tuple[int, int]:
|
||||
semitones = (NATURAL[target['letter']] + alteration(target['alter']) - NATURAL[source['letter']] - alteration(source['alter'])) % 12
|
||||
if semitones > 6:
|
||||
|
||||
Reference in New Issue
Block a user