from __future__ import annotations import copy import fractions import generator.accompaniment import generator.arrange.accompaniment import generator.arrange.form import generator.electric import generator.fretboard import generator.model import generator.score import generator.solo.analysis import generator.solo.composer import generator.solo.notation import generator.solo.report import generator.solo.types def regions(document): result, first, start = {}, 0, fractions.Fraction() source = generator.score.source_staff(document)['measures'] for section in generator.arrange.form.full_arrangement_sections(source, 'acoustic'): length = sum((generator.model.fraction(m['duration']) for m in source[section.source_measure_index:section.source_measure_index + section.measure_count]), fractions.Fraction()) result[section.section_index] = (first, section.measure_count, start, length) first += section.measure_count start += length return result def annotate(document, solo, offset): spans = [] for choice in solo.choices: if choice.scale is None: continue label = choice.scale.label() if spans and spans[-1]['label'] == label and generator.model.fraction(spans[-1]['end']) == offset + choice.span.start: spans[-1]['end'] = generator.model.rational(offset + choice.span.end) else: spans.append({'id': f'{solo.part}_scale_{len(spans) + 1}', 'start': generator.model.rational(offset + choice.span.start), 'end': generator.model.rational(offset + choice.span.end), 'label': label, 'matched': True}) document['staves'][0]['scale_spans'] = spans