+13
-10
@@ -5,8 +5,8 @@ import itertools
|
||||
|
||||
import generator.accompaniment
|
||||
import generator.model
|
||||
import generator.solo.analysis
|
||||
import generator.solo.policy
|
||||
import generator.source
|
||||
import generator.vocabulary
|
||||
|
||||
def meter_context(measure):
|
||||
@@ -90,7 +90,7 @@ class Rhythm:
|
||||
return tuple((e.lane, str(e.start), str(e.end - e.start), str(e.harmonic_time)) for e in self.events)
|
||||
|
||||
def melody_contexts(document):
|
||||
melody = generator.solo.analysis.attacks(document)
|
||||
melody = generator.source.attacks(document)
|
||||
result, cursor = [], fractions.Fraction()
|
||||
for m in document['staves'][0]['measures']:
|
||||
length = generator.model.fraction(m['duration'])
|
||||
@@ -247,9 +247,10 @@ def evaluate(events, part, melody, harmony, lengths):
|
||||
divisor = max(1, len(lengths))
|
||||
return tuple((k, v / divisor) for k, v in (('activity', activity), ('melody_support', support), ('harmonic_support', coverage), ('articulation', articulation)))
|
||||
|
||||
def candidates(measure, prior, part, melody, seed, *, lengths=None, limit=None, grouping=()):
|
||||
def candidates(measure, prior, part, melody, seed, *, lengths=None, limit=None, grouping=(), composition=None):
|
||||
composition = composition or generator.vocabulary.current()
|
||||
lengths = lengths or (generator.model.fraction(measure['duration']),)
|
||||
policy = generator.vocabulary.accompaniment(part)
|
||||
policy = composition.accompaniment(part)
|
||||
result = []
|
||||
for pattern in patterns_for(policy, measure, lengths, grouping):
|
||||
for anticipate in (False, True):
|
||||
@@ -371,13 +372,14 @@ def realize_acoustic_form(rhythms, context):
|
||||
def form_cost(rhythms, groups):
|
||||
return sum(r.cost * len(g) for r, g in zip(rhythms, groups))
|
||||
|
||||
def choose_cycles(groups, part, melody, seed, *, breaks=()):
|
||||
def choose_cycles(groups, part, melody, seed, *, breaks=(), composition=None):
|
||||
"""Select a small recurring vocabulary against every occurrence in the form.
|
||||
|
||||
No local shortlist precedes whole-form evaluation. A pattern/mode is retained
|
||||
as one decision even where a chord boundary changes its legal release.
|
||||
"""
|
||||
policy = generator.vocabulary.accompaniment(part)
|
||||
composition = composition or generator.vocabulary.current()
|
||||
policy = composition.accompaniment(part)
|
||||
settings = policy['groove']
|
||||
selected, locations, reports = [], [], []
|
||||
runs = []
|
||||
@@ -463,7 +465,7 @@ def choose_cycles(groups, part, melody, seed, *, breaks=()):
|
||||
selected.append((p, anticipate, cache[i, p['id'], anticipate]))
|
||||
locations.append({'cycle_start': run[0][0][2], 'cycle_slot': i % len(cycle), 'base_pattern': p['id'], 'fill': None})
|
||||
context = acoustic_context(groups, melody, breaks) if part == 'acoustic' else None
|
||||
add_fills(groups, selected, locations, part, melody, seed, context=context)
|
||||
add_fills(groups, selected, locations, part, melody, seed, context=context, composition=composition)
|
||||
if context:
|
||||
realized = realize_acoustic_form([r for _, _, r in selected], context)
|
||||
selected = [(p, a, r) for (p, a, _), r in zip(selected, realized)]
|
||||
@@ -472,9 +474,10 @@ def choose_cycles(groups, part, melody, seed, *, breaks=()):
|
||||
report['attack_assignment'] = 'sequential_combined_except_eighth_pairs'
|
||||
return selected, locations, reports
|
||||
|
||||
def add_fills(groups, selected, locations, part, melody, seed, *, context=None):
|
||||
def add_fills(groups, selected, locations, part, melody, seed, *, context=None, composition=None):
|
||||
"""Fixed source-position answers; no iteration seed or generated lead input."""
|
||||
policy = generator.vocabulary.accompaniment(part)
|
||||
composition = composition or generator.vocabulary.current()
|
||||
policy = composition.accompaniment(part)
|
||||
spacing = policy['groove']['fill_spacing_measures']
|
||||
if not groups:
|
||||
return
|
||||
@@ -519,7 +522,7 @@ def add_fills(groups, selected, locations, part, melody, seed, *, context=None):
|
||||
if any(e.start < middle < e.end for e in current.events):
|
||||
continue
|
||||
for variation in policy['patterns']:
|
||||
if variation['family'] != base['family'] or variation['lengths'] != base['lengths'] or variation.get('meter') != base.get('meter') or variation.get('grouping') != base.get('grouping'):
|
||||
if variation['family'] != base['family'] or tuple(variation['lengths']) != tuple(base['lengths']) or variation.get('meter') != base.get('meter') or tuple(variation.get('grouping', ())) != tuple(base.get('grouping', ())):
|
||||
continue
|
||||
hybrid = {**base, 'id': base['id'] + '.fill.' + variation['id'], 'events':
|
||||
[r for r in base['events'] if fractions.Fraction(r['onset']) < middle] +
|
||||
|
||||
Reference in New Issue
Block a user