Rhythm Patterns
ci / checks (push) Successful in 51m14s

This commit is contained in:
khodowany
2026-10-07 00:22:19 -05:00
parent 23b606e47f
commit a0e13434e4
8 changed files with 5451 additions and 291 deletions
+11 -2
View File
@@ -23,7 +23,7 @@ def _load(contents):
result = {}
for name, text in contents:
value = json.loads(text)
if value.get('version') != (5 if name == 'accompaniment' else 1) or not value.get('provenance') or not value.get('license'):
if value.get('version') != (6 if name == 'accompaniment' else 1) or not value.get('provenance') or not value.get('license'):
raise ValueError(f'{name}: unsupported or unprovenanced production vocabulary')
if name == 'accompaniment':
signatures = {}
@@ -43,6 +43,15 @@ def _load(contents):
lengths = tuple(map(fractions.Fraction, pattern['lengths']))
if not 1 <= len(lengths) <= 2 or any(n <= 0 for n in lengths):
raise ValueError('patterns require one or two positive measure lengths')
meter = pattern.get('meter')
grouping = tuple(pattern.get('grouping', ()))
if meter == 'partial':
if len(lengths) != 1 or grouping:
raise ValueError('partial patterns require one measure and no grouping')
elif meter not in ('3/4', '4/4', '5/4') or lengths != (fractions.Fraction(meter[0]),) * 2:
raise ValueError('full patterns require an explicit supported meter and two complete bars')
if (meter == '5/4' and grouping not in ((3, 2), (2, 3))) or (meter != '5/4' and grouping):
raise ValueError('5/4 patterns require a 3+2 or 2+3 grouping')
# Validate musical events before any measure projection or ties.
previous, releases = fractions.Fraction(), {}
onsets = []
@@ -69,7 +78,7 @@ def _load(contents):
previous = onset
onsets.append(onset)
if len(lengths) == 2:
signatures[part].add((lengths, tuple(onsets)))
signatures[part].add((meter, grouping, tuple(onsets)))
families = policy['voicing_families']
if not families.get('provenance'):
raise ValueError('guitar voicing families require provenance')