Sepearate Generation
This commit is contained in:
@@ -13,7 +13,7 @@ import generator.solo.types
|
||||
import generator.solo.harmonic
|
||||
import generator.solo.drafts
|
||||
import generator.solo.similarity
|
||||
import generator.solo.references
|
||||
import generator.solo.features
|
||||
import generator.solo.placement
|
||||
|
||||
def describe(solo: generator.solo.types.Solo, scales, measure_offset=0, time_offset=0) -> str:
|
||||
@@ -32,7 +32,7 @@ def describe(solo: generator.solo.types.Solo, scales, measure_offset=0, time_off
|
||||
lines.extend(('', f'{plan.id}: {plan.start}-{plan.end}; {plan.relationship}; motif {plan.motif.id}', f' Origin: {plan.motif.origin}; source events: ' + ', '.join(s for n in plan.motif.notes for s in n.sources)))
|
||||
lines.append(f' Contract: {plan.treatment}; closure: {plan.closure}; ending: {plan.ending}; score: {phrase.score:.4f}; identity: {plan.seed}')
|
||||
if plan.treatment in ('source_variation', 'thematic_recomposition'):
|
||||
lines.append(' Activity preference: 4–6 attacks per four beats; source phrasing takes precedence. Occupancy is diagnostic, not a target.')
|
||||
lines.append(' Activity follows the selected gesture and tempo-aware vocabulary; occupancy is diagnostic, not a target.')
|
||||
if phrase.draft:
|
||||
draft = phrase.draft
|
||||
lines.append(f' Complete draft {draft.id}: {draft.relationship}; home {draft.home.id if draft.home else "none"}; {len(draft.notes)} attacks; rests {draft.rests()}')
|
||||
@@ -76,8 +76,10 @@ def describe(solo: generator.solo.types.Solo, scales, measure_offset=0, time_off
|
||||
degrees = [str(d) for d, a in generator.harmony.degrees(choice.span.chord).items() if (root + generator.harmony.degree_semitones(d, a)) % 12 == note.pitch.number() % 12]
|
||||
function = 'chord degree ' + '/'.join(degrees) if degrees else 'in-collection connection'
|
||||
if note.pitch.number()%12 not in generator.solo.types.permitted(solo.choices,note.start,note.end):
|
||||
function='validated enclosure exception'
|
||||
function='validated expression exception'
|
||||
lines.append(f' {note.start}-{note.end}: {note.pitch.label()}; {note.role}; {generator.harmony.symbol(choice.span.chord)}, {function}; {choice.scale.label()}; string {note.position.string_number}, fret {note.position.fret}')
|
||||
for expression in detail['expressions']:
|
||||
lines.append('Expression: ' + expression['kind'] + ' / ' + expression['rule'] + ' -> ' + str(expression['target']['pitch']))
|
||||
lines.append('\nSounding harmonic spans (ties merged before classification):')
|
||||
for event in detail['harmonic_roles']:
|
||||
if float(fractions.Fraction(event['sounding_duration'])) >= 1 or event['protected'] or event['enclosure']:
|
||||
@@ -88,7 +90,8 @@ def structure(solo):
|
||||
harmony = generator.solo.harmonic.Harmony(solo.choices)
|
||||
contracts = tuple(dict.fromkeys(t for p in solo.phrases if p.state for t in p.state.treatments))
|
||||
enclosures = tuple(e for p in solo.phrases if p.draft for e in p.draft.enclosures)
|
||||
checked = harmony.evaluate(solo.notes(), contracts, until=solo.end, complete=True,enclosures=enclosures)
|
||||
expressions = tuple(e for p in solo.phrases if p.draft for e in p.draft.expressions)
|
||||
checked = harmony.evaluate(solo.notes(), contracts, until=solo.end, complete=True,enclosures=enclosures,expressions=expressions)
|
||||
|
||||
def rational(value):
|
||||
if isinstance(value, dict):
|
||||
@@ -122,10 +125,10 @@ def structure(solo):
|
||||
entry['head_comparison_plain']=generator.solo.similarity.compare(phrase.refined.notes,local_source)
|
||||
entry['head_comparison_elaborated']=generator.solo.similarity.compare(tuple(n for d in phrase.decisions for n in d.notes),local_source)
|
||||
if phrase.state and phrase.state.home:
|
||||
entry['theme_relationship']=generator.solo.references.relationship(phrase.refined.notes,phrase.state.home)
|
||||
entry['theme_relationship']=generator.solo.features.relationship(phrase.refined.notes,phrase.state.home)
|
||||
entry['score'] = phrase.score
|
||||
phrases.append(entry)
|
||||
return {'instrument_profile': rational(dataclasses.asdict(solo.profile)) if solo.profile else None, 'phrasing': phrasing_report(solo), 'source_comparison': {stage:generator.solo.similarity.compare(tuple(n for p in solo.phrases for n in (p.refined.notes if stage=='plain' and p.refined else tuple(n for d in p.decisions for n in d.notes))),tuple(n for p in solo.phrases if p.initial for n in p.initial.notes)) for stage in ('plain','elaborated')}, 'fretboard': fretboard_report(solo), 'passages': [{'id': p.id, 'start': str(p.start), 'end': str(p.end), 'phrases': list(p.phrase_ids), 'seed': p.seed} for p in solo.passages], 'phrases': phrases, 'enclosures': rational([dataclasses.asdict(e) for e in enclosures]), 'harmonic_roles': harmony.describe(solo.notes(), contracts,enclosures), 'harmonic_exposure': checked.exposure, 'harmonic_valid': checked.valid, 'harmonic_error': checked.error, 'unresolved_treatments': rational([dataclasses.asdict(t) for t in checked.pending]), 'treatments': rational([dataclasses.asdict(t) for t in contracts])}
|
||||
return {'instrument_profile': rational(dataclasses.asdict(solo.profile)) if solo.profile else None, 'phrasing': phrasing_report(solo), 'source_comparison': {stage:generator.solo.similarity.compare(tuple(n for p in solo.phrases for n in (p.refined.notes if stage=='plain' and p.refined else tuple(n for d in p.decisions for n in d.notes))),tuple(n for p in solo.phrases if p.initial for n in p.initial.notes)) for stage in ('plain','elaborated')}, 'fretboard': fretboard_report(solo), 'passages': [{'id': p.id, 'start': str(p.start), 'end': str(p.end), 'phrases': list(p.phrase_ids), 'seed': p.seed} for p in solo.passages], 'phrases': phrases, 'expressions': rational([dataclasses.asdict(e) for e in expressions]), 'enclosures': rational([dataclasses.asdict(e) for e in enclosures]), 'harmonic_roles': harmony.describe(solo.notes(), contracts,enclosures,expressions), 'harmonic_exposure': checked.exposure, 'harmonic_valid': checked.valid, 'harmonic_error': checked.error, 'unresolved_treatments': rational([dataclasses.asdict(t) for t in checked.pending]), 'treatments': rational([dataclasses.asdict(t) for t in contracts])}
|
||||
|
||||
|
||||
def phrasing_report(solo):
|
||||
|
||||
Reference in New Issue
Block a user