Music Notation
ci / checks (push) Successful in 43m19s

This commit is contained in:
khodowany
2026-09-15 01:30:42 -05:00
parent fe42d811fa
commit 1d1bd3e871
41 changed files with 1546 additions and 5236 deletions
+7 -6
View File
@@ -1,6 +1,6 @@
from __future__ import annotations
from generator.model import NATURAL, parse_pitch_name, pitch_name
from generator.model import NATURAL, alteration, parse_pitch_name, pitch_name
# Semantic degrees are independent of guitar voicing omissions.
KINDS = {
@@ -31,8 +31,8 @@ def degrees(harmony: dict) -> dict[int, int]:
raise ValueError(f'unsupported harmony kind: {kind}')
result = KINDS[kind].copy()
for change in harmony.get('degrees', []):
degree, alter, operation = change['value'], change['alter'], change['type']
if type(degree) is not int or degree < 1 or type(alter) is not int:
degree, alter, operation = change['value'], alteration(change['alter']), change['type']
if type(degree) is not int or degree < 1:
raise ValueError('invalid harmony degree')
if operation == 'subtract':
if degree not in result:
@@ -59,10 +59,10 @@ def pitch_classes(harmony: dict) -> tuple[int, ...]:
if harmony['kind'] == 'none':
return ()
root = harmony['root']
root_pc = NATURAL[root['letter']] + root['alter']
root_pc = NATURAL[root['letter']] + alteration(root['alter'])
values = [(root_pc + degree_semitones(d, a)) % 12 for d, a in degrees(harmony).items()]
if bass := harmony.get('bass'):
values.append((NATURAL[bass['letter']] + bass['alter']) % 12)
values.append((NATURAL[bass['letter']] + alteration(bass['alter'])) % 12)
return tuple(dict.fromkeys(values))
def symbol(harmony: dict) -> str:
@@ -71,7 +71,8 @@ def symbol(harmony: dict) -> str:
suffix = harmony.get('kind_text', SUFFIXES.get(harmony['kind'], harmony['kind']))
if 'kind_text' not in harmony:
for d in harmony.get('degrees', []):
sign = '#' * max(d['alter'], 0) + 'b' * max(-d['alter'], 0)
amount = alteration(d['alter'])
sign = '#' * max(int(amount), 0) + 'b' * max(int(-amount), 0) if amount.denominator == 1 else f'({amount})'
suffix += ('no' if d['type'] == 'subtract' else 'add' if d['type'] == 'add' and not sign else '') + sign + str(d['value'])
result = pitch_name(harmony['root']) + suffix
if bass := harmony.get('bass'):