"""One complete-event evaluator, including the declared musical relationships. The inputs are realized notes and independently planned obligations. Action counts and constructor-family labels never award musical credit. """ import collections import fractions import generator.solo.harmonic import generator.solo.scoring import generator.solo.types VERSION = 'directed-phrases-2' WEIGHTS = {'continuity': 2, 'repetition': 3, 'interruption': 2, 'activity': 2, 'harmony': 2, 'register': 1, 'identity': 3, 'arrival': 2} def signature(notes): notes = generator.solo.types.sounding_notes(notes) if not notes: return () return tuple((n.start-notes[0].start, n.end-n.start, n.pitch.number()-notes[0].pitch.number()) for n in notes) def theme_distance(home, sample, purpose): if not home or purpose not in ('return','develop','answer','extend'): return fractions.Fraction() # Returns preserve the whole introduced signature; development preserves # its selected opening intervals, allowing the rhythm and conclusion to change. count = len(home) if purpose=='return' else min(3,len(home)) if count<3 or len(sample)start for s in harmony.spans) activity = max(0,density-7)+(2 if active and not notes else 0) if notes and sounding