+13
-1
@@ -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')
|
||||
|
||||
Reference in New Issue
Block a user