Accompaniment
ci / checks (push) Successful in 49m53s

This commit is contained in:
khodowany
2026-10-06 01:59:55 -05:00
parent 04bb44b9d0
commit df83cae38c
14 changed files with 916 additions and 156 deletions
+13 -1
View File
@@ -23,8 +23,20 @@ def _load(contents):
result = {}
for name, text in contents:
value = json.loads(text)
if value.get('version') != 1 or not value.get('provenance') or not value.get('license'):
if value.get('version') != (2 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':
if fractions.Fraction(value['grid']) != fractions.Fraction(1, 2):
raise ValueError('accompaniment requires an eighth-note placement grid')
for lane in ('electric', 'bass', 'upper'):
layer = value['layers'][lane]
if not 0 <= layer['attacks'][0] <= layer['attacks'][1] <= 3 or not layer['families']:
raise ValueError('invalid accompaniment attack range or duration families')
for family in layer['families']:
if not value['families'][family] or any(fractions.Fraction(d) <= 0 for d in value['families'][family]):
raise ValueError('accompaniment durations must be positive')
if not 1 <= value['lane_candidates'] <= 64 or not 1 <= value['measure_candidates'] <= 64:
raise ValueError('accompaniment candidate budgets must be 1–64')
entries = value.get('cells', value.get('patterns', value.get('colors', value.get('transformations', []))))
if len({v['id'] for v in entries}) != len(entries):
raise ValueError(f'{name}: duplicate vocabulary ID')