@@ -66,6 +66,7 @@ def validate_document(document: dict) -> None:
|
||||
if not staff.get('tablature'):
|
||||
continue
|
||||
for measure in staff['measures']:
|
||||
sounding = []
|
||||
for voice in measure['voices']:
|
||||
for note in voice['notes']:
|
||||
tones = []
|
||||
@@ -73,8 +74,15 @@ def validate_document(document: dict) -> None:
|
||||
tab = pitch['tablature']
|
||||
position = TabPosition(tab['string'], tab['fret'], dict(STANDARD_TUNING)[tab['string']] + tab['fret'])
|
||||
tones.append((position, generator.model.fraction(pitch['duration'])))
|
||||
start = generator.model.fraction(note['onset'])
|
||||
sounding.append((start, start + generator.model.fraction(pitch['duration']), position))
|
||||
if not playable_attack(tones):
|
||||
raise ValueError(f'{measure["id"]}, event {note["id"]}: single notes require frets {MIN_FRET}-{MAX_SINGLE_FRET}; each sounding chord requires an anchor in {MIN_FRET}-{MAX_ANCHOR_FRET} and at most {MAX_FRET_SPAN} consecutive fret positions, including held/tied tails')
|
||||
if len(measure['voices']) > 1:
|
||||
for time in sorted({t for a, b, _ in sounding for t in (a, b)}):
|
||||
held = [(p, b - time) for a, b, p in sounding if a <= time < b]
|
||||
if not playable_attack(held):
|
||||
raise ValueError(f'{measure["id"]}, beat {time + 1}: overlapping guitar voices conflict in string, fret span or sounding anchor')
|
||||
|
||||
def validate_tuning(state: dict, location: str) -> None:
|
||||
details = state['staff_details']
|
||||
|
||||
Reference in New Issue
Block a user