Sepearate Generation
This commit is contained in:
@@ -148,8 +148,12 @@ class Harmony:
|
||||
intervals.append((upper.start,target.start))
|
||||
return accepted, ''
|
||||
|
||||
def evaluate(self, notes, treatments=(), *, until=None, complete=False, enclosures=()):
|
||||
def evaluate(self, notes, treatments=(), *, until=None, complete=False, enclosures=(), expressions=()):
|
||||
notes = generator.solo.types.sounding_notes(notes)
|
||||
from generator.solo.expressions import validate
|
||||
permissions, expression_error = validate(notes, expressions, self)
|
||||
if expression_error:
|
||||
return Result(False, 0, error=expression_error)
|
||||
until = until if until is not None else max((n.end for n in notes), default=fractions.Fraction())
|
||||
ornaments, error = self.enclosure_events(notes, enclosures, until) if enclosures else ({}, '')
|
||||
if error:
|
||||
@@ -190,13 +194,14 @@ class Harmony:
|
||||
for span, start, end in self.segments(note):
|
||||
contract = next((t for t in valid_contracts if t.pitch == number and t.start <= start and t.end >= end), None)
|
||||
enclosure = ornaments.get(note.event_id)
|
||||
exception = enclosure is not None and note.event_id == enclosure.lower.event_id
|
||||
expression = permissions.get(note.event_id)
|
||||
exception = enclosure is not None and note.event_id == enclosure.lower.event_id or expression is not None and (expression.kind != 'anticipation' or end <= expression.boundary)
|
||||
if start > covered or not span.scale or number % 12 not in span.scale.pitches and not exception:
|
||||
return Result(False, 0, error=f'{note.pitch.label()} at {start}-{end}: outside mapped collection or missing harmony')
|
||||
covered = end
|
||||
function = self.function(number, span)
|
||||
brief_enclosure = enclosure and (exception or enclosure.approach_start is None or enclosure.approach_start == note.start)
|
||||
if function == 'basic' or note.role == 'quote' or brief_enclosure:
|
||||
if function == 'basic' or note.role == 'quote' or brief_enclosure or expression:
|
||||
continue
|
||||
if duration >= generator.solo.policy.DEFAULT.long_note and contract is None:
|
||||
return Result(False, 0, error=f'{note.pitch.label()} at {start}-{end} over {span.chord}: sustained {function} without a planned treatment')
|
||||
@@ -206,8 +211,12 @@ class Harmony:
|
||||
if covered < note.end:
|
||||
return Result(False, 0, error=f'{note.pitch.label()} at {covered}: missing harmonic coverage')
|
||||
return Result(True, exposed / max(sounding, 0.001), tuple(pending))
|
||||
def describe(self, notes, treatments=(), enclosures=()):
|
||||
def describe(self, notes, treatments=(), enclosures=(), expressions=()):
|
||||
notes = generator.solo.types.sounding_notes(notes)
|
||||
from generator.solo.expressions import validate
|
||||
permissions, error = validate(notes, expressions, self)
|
||||
if error:
|
||||
raise ValueError(error)
|
||||
ornaments, error = self.enclosure_events(notes,enclosures) if enclosures else ({}, '')
|
||||
if error:
|
||||
raise ValueError(error)
|
||||
@@ -215,7 +224,8 @@ class Harmony:
|
||||
for index, note in enumerate(notes):
|
||||
for span, start, end in self.segments(note):
|
||||
contracts = [t for t in treatments if t.pitch == note.pitch.number() and t.start <= start and t.end >= end]
|
||||
result.append({'start': str(start), 'end': str(end), 'attack': str(note.start), 'sounding_duration': str(note.end - note.start), 'pitch': note.pitch.label(), 'chord': span.chord, 'function': self.function(note.pitch.number(), span), 'motion': self.connected_motion(notes, index), 'enclosure': ornaments[note.event_id].id if note.event_id in ornaments else '', 'scale_exception': note.event_id in ornaments and self.function(note.pitch.number(), span) == 'outside_collection', 'protected': note.role == 'quote', 'treatments': [t.id for t in contracts]})
|
||||
expression = permissions.get(note.event_id)
|
||||
result.append({'start': str(start), 'end': str(end), 'attack': str(note.start), 'sounding_duration': str(note.end - note.start), 'pitch': note.pitch.label(), 'chord': span.chord, 'function': self.function(note.pitch.number(), span), 'motion': self.connected_motion(notes, index), 'enclosure': ornaments[note.event_id].id if note.event_id in ornaments else '', 'expression': expression.kind if expression else '', 'expression_rule': expression.rule if expression else '', 'scale_exception': bool(note.event_id in ornaments or expression) and self.function(note.pitch.number(), span) == 'outside_collection', 'protected': note.role == 'quote', 'treatments': [t.id for t in contracts]})
|
||||
return result
|
||||
|
||||
def anchor_note(anchor, notes, *, until=None):
|
||||
|
||||
Reference in New Issue
Block a user