Files
product-vamp/generator/scales/mapping.py
T
khodowany f5f0ab5eec
ci / checks (push) Successful in 48m15s
Scale Patterns
2026-09-30 03:17:06 -05:00

33 lines
1.6 KiB
Python

from __future__ import annotations
import generator.harmony
import generator.model
import generator.scales.library
import generator.scales.report
import generator.scales.selection
import generator.scales.timeline
def annotate(document: dict, solos: list[generator.scales.timeline.Solo], library: generator.scales.library.Library, source: str) -> str:
staff = document['staves'][0]
timeline = generator.scales.timeline.read(staff)
spans, reports = [], []
for solo in solos:
choices = generator.scales.selection.select(timeline, solo, library)
previous = None
for choice in choices:
if choice.span.chord is None:
previous = None
continue
label = choice.scale.label() if choice.scale else 'No exact scale match'
if previous is not None and previous['label'] == label and generator.model.fraction(previous['end']) == choice.span.start:
previous['end'] = generator.model.rational(choice.span.end)
else:
previous = {'id': f'scale-{len(spans) + 1}', 'start': generator.model.rational(choice.span.start), 'end': generator.model.rational(choice.span.end), 'label': label, 'matched': choice.scale is not None}
spans.append(previous)
if choice.scale is None:
print(f'{source}, {staff["name"]}, source measure {choice.span.source_measure}, beat {choice.span.beat}: {choice.reason} Chord: {generator.harmony.symbol(choice.span.chord)}', flush=True)
reports.append(generator.scales.report.passage(staff['arrangement_part_type'], solo, choices, library))
if spans:
staff['scale_spans'] = spans
return '\n'.join(reports)