@@ -4,11 +4,13 @@ import copy
|
||||
import fractions
|
||||
|
||||
import generator.accompaniment
|
||||
import generator.arrange.form
|
||||
import generator.arrange.pickup
|
||||
import generator.composition_types
|
||||
import generator.fretboard
|
||||
import generator.model
|
||||
import generator.parts
|
||||
import generator.score
|
||||
import generator.validation
|
||||
|
||||
def mask(document, allowed):
|
||||
@@ -58,11 +60,28 @@ def fill(notes, length, prefix, voice='voice_arranged'):
|
||||
rests(length)
|
||||
return result
|
||||
|
||||
def assemble(source, results):
|
||||
def improvisation(source, template, part):
|
||||
"""Fill the source's solo allocation, including pickups, with beat slashes."""
|
||||
document = copy.deepcopy(template)
|
||||
staff = document['staves'][0]
|
||||
for field in ('tuplets', 'octave_shifts', 'scale_spans'):
|
||||
staff[field] = []
|
||||
for measure in staff['measures']:
|
||||
measure['id'] = part + '_improv_' + measure['id']
|
||||
measure['voices'] = [{'id': 'voice_arranged', 'notes': generator.parts.generated_voice(measure, 'slash')}]
|
||||
generator.score.reidentify(staff['measures'], [])
|
||||
plan = generator.arrange.form.FormPlan.read(source.document(), part)
|
||||
mask(document, [(a, b) for a, b, role in plan.windows if role == part + '_solo'])
|
||||
return document
|
||||
|
||||
def assemble(source, results, *, solos_enabled=True):
|
||||
"""Union prevalidated role windows; no selection or pitch/fingering rewrite."""
|
||||
documents = {}
|
||||
for part in generator.parts.PART_TYPES:
|
||||
selected = [results[r]['document'] for r in generator.composition_types.ROLES if r.startswith(part + '_')]
|
||||
selected = [results[r]['document'] for r in generator.composition_types.ROLES
|
||||
if r.startswith(part + '_') and (solos_enabled or not r.endswith('_solo'))]
|
||||
if not solos_enabled and part != 'vocal':
|
||||
selected.append(improvisation(source, selected[0], part))
|
||||
document = copy.deepcopy(selected[0])
|
||||
staff = document['staves'][0]
|
||||
if part == 'vocal':
|
||||
@@ -80,7 +99,7 @@ def assemble(source, results):
|
||||
for d in selected:
|
||||
for voice in d['staves'][0]['measures'][i]['voices']:
|
||||
lane = voice['id'] if part == 'acoustic' and voice['id'] in ('upper', 'bass') else 'voice_arranged'
|
||||
sounding = [copy.deepcopy(n) for n in voice['notes'] if n['pitches'] or n.get('tuplet_ids')]
|
||||
sounding = [copy.deepcopy(n) for n in voice['notes'] if n['pitches'] or n.get('tuplet_ids') or n.get('notehead') == 'slash']
|
||||
if sounding:
|
||||
lanes.setdefault(lane, []).extend(sounding)
|
||||
lanes = lanes or {'voice_arranged': []}
|
||||
|
||||
Reference in New Issue
Block a user