Comp
This commit is contained in:
@@ -152,7 +152,7 @@ def anchor_backbones(identifier, start, end, release, register, choices, bar, se
|
||||
states = list(generator.solo.sequences.diverse(following, lambda item: (item[0], generator.solo.policy.stable_rank(seed, tuple(a.pitch for a in item[1]))), lambda item: (item[2], item[1][0].pitch.number()), generator.solo.policy.DEFAULT.anchor_lines))
|
||||
return tuple(dict.fromkeys(anchors for _, anchors, _ in states))
|
||||
|
||||
def plans(analysis: generator.solo.analysis.Analysis, measures: list[dict], choices, end: fractions.Fraction, part: str, sequences: generator.solo.sequences.Library) -> tuple[generator.solo.types.PhrasePlan, ...]:
|
||||
def plans(analysis: generator.solo.analysis.Analysis, measures: list[dict], choices, end: fractions.Fraction, part: str, sequences: generator.solo.sequences.Library, *, lead=False) -> tuple[generator.solo.types.PhrasePlan, ...]:
|
||||
boundaries = [fractions.Fraction()]
|
||||
for measure in measures:
|
||||
boundaries.append(min(end, boundaries[-1] + generator.model.fraction(measure['duration'])))
|
||||
@@ -187,13 +187,15 @@ def plans(analysis: generator.solo.analysis.Analysis, measures: list[dict], choi
|
||||
release = fractions.Fraction(1, 2) if decision(passage_seed, 'breathing') % 3 == 0 else fractions.Fraction()
|
||||
release = min(release, (finish - start) / 8)
|
||||
envelope = activity_passages(start, finish, release, activity, decision(passage_seed, 'activity') % 3)
|
||||
anchors = anchor_backbones(passage_id, start, finish, release, register, choices, bar, passage_seed)
|
||||
anchors = () if lead else anchor_backbones(passage_id, start, finish, release, register, choices, bar, passage_seed)
|
||||
# Prefer four-bar phrasing; extend when a sustained harmony crosses that seam.
|
||||
middle = min(index + 4, stop)
|
||||
before = next((c for c in reversed(choices) if c.span.start < boundaries[middle]), None)
|
||||
after = next((c for c in choices if c.span.start <= boundaries[middle] < c.span.end), None)
|
||||
extended = stop - index > 4 and same_harmony(before, after)
|
||||
phrase_stops = [stop] if extended or middle == stop else [middle, stop]
|
||||
# A bounded complete lead draft can express an extended phrase directly.
|
||||
# Computational note groups below do not require additional phrase ends.
|
||||
phrase_stops = [stop] if lead or extended or middle == stop else [middle, stop]
|
||||
local = tuple(c for c in choices if c.span.start < boundaries[phrase_stops[0]] and c.span.end > start)
|
||||
slot = decision(passage_seed, 'motif') % 3
|
||||
if part == 'acoustic':
|
||||
@@ -210,7 +212,7 @@ def plans(analysis: generator.solo.analysis.Analysis, measures: list[dict], choi
|
||||
for phrase_stop in phrase_stops:
|
||||
phrase_end = boundaries[phrase_stop]
|
||||
terminal = phrase_end == finish
|
||||
treatment = 'opening_reference' if motif.origin == 'melody' else 'invented'
|
||||
treatment = 'lead' if lead else 'opening_reference' if motif.origin == 'melody' else 'invented'
|
||||
landmarks = tuple(generator.solo.types.Landmark(a.earliest, a.latest, min(v[i].pitch.number() for v in anchors), max(v[i].pitch.number() for v in anchors), 0, a.role) for i, a in enumerate(anchors[0])) if anchors and anchors[0] else ()
|
||||
result.append(generator.solo.types.PhrasePlan(f'{part}_phrase_{len(result) + 1}', phrase_start, phrase_end, motif, 'statement' if phrase_start == start else 'continue', treatment, None, register, activity, release if terminal else fractions.Fraction(), envelope, landmarks, 'breath' if terminal and release else 'sustain' if terminal else 'connected', 'closed' if terminal else 'open', passage_seed, passage_id, start, finish, anchors))
|
||||
phrase_start = phrase_end
|
||||
|
||||
Reference in New Issue
Block a user