50 lines
2.6 KiB
Python
50 lines
2.6 KiB
Python
"""Cheap valid notes for renderer/packaging tests; never a production fallback.
|
|
|
|
Learned decoding and authored-repertoire tests separately use the real path.
|
|
"""
|
|
import fractions
|
|
import pathlib
|
|
import unittest.mock
|
|
import generator.production
|
|
import generator.vocabulary
|
|
import generator.harmonic_time
|
|
import generator.solo.types
|
|
import generator.solo.placement
|
|
import generator.solo.profiles
|
|
import generator.solo.learned
|
|
import generator.solo.harmonic
|
|
import dataclasses
|
|
import generator.solo.expressions
|
|
import generator.harmony
|
|
|
|
def compose(analysis, measures, part, end, *, initial=None, start=fractions.Fraction(), **kwargs):
|
|
spans = tuple(dataclasses.replace(s, start=s.start + start, end=s.end + start) for s in generator.harmonic_time.read({'measures': measures}, initial=initial))
|
|
h = generator.solo.harmonic.Harmony(spans)
|
|
notes = []
|
|
for s in h.spans:
|
|
a, b = max(start, s.start), min(end, s.end)
|
|
if a >= b or s.chord == 'N.C.':
|
|
continue
|
|
number = next(n for n in range(55, 72) if n % 12 in s.roles.basic)
|
|
chord = generator.solo.expressions.parsed_chord(s.chord)
|
|
pitch = next(generator.solo.expressions.degree_pitch(chord, d, x, number) for d, x in generator.harmony.degrees(chord).items() if generator.solo.expressions.degree_pitch(chord, d, x, number).number() == number)
|
|
notes.append(generator.solo.types.Note(a, b, pitch, event_id=str(a)))
|
|
placed = generator.solo.placement.place(tuple(notes), analysis.tempo)[1] if notes else ()
|
|
return generator.solo.types.Solo(part, spans, (generator.solo.types.Phrase('fixture', start, end, placed, 'test', 'test', 'handoff'),), analysis.tempo, end, profile=generator.solo.profiles.for_part(part), start=start)
|
|
|
|
def install(test):
|
|
resources = generator.vocabulary.load()
|
|
predictor = generator.solo.learned.Model.load(pathlib.Path(__file__).resolve().parents[1] / 'data/models/solo.json')
|
|
tree = generator.production.generate_tree
|
|
|
|
def serial(*args, **kwargs):
|
|
kwargs['jobs'] = 1
|
|
return tree(*args, **kwargs)
|
|
|
|
test.enterContext(unittest.mock.patch('generator.production.generate_tree', side_effect=serial))
|
|
test.enterContext(unittest.mock.patch('generator.vocabulary.load', return_value=resources))
|
|
test.enterContext(unittest.mock.patch('generator.solo.authored.lookup', return_value=None))
|
|
test.enterContext(unittest.mock.patch('generator.composition._solo_model', return_value=predictor))
|
|
test.enterContext(unittest.mock.patch('generator.composition._resource_key', return_value={'model': 'synthetic infrastructure fixture'}))
|
|
test.enterContext(unittest.mock.patch('generator.solo.composer.compose', side_effect=compose))
|