Generation
This commit is contained in:
+62
-2
@@ -23,6 +23,7 @@ import generator.musicxml
|
||||
import generator.playback
|
||||
import generator.practice.generate
|
||||
import tests.rhythm_fixtures
|
||||
import tests.test_accompaniment
|
||||
import tests.test_musicxml
|
||||
|
||||
class EngravingTests(unittest.TestCase):
|
||||
@@ -36,6 +37,65 @@ class EngravingTests(unittest.TestCase):
|
||||
return layout
|
||||
def primitives(self, layout, role):
|
||||
return [p for page in layout.pages for p in page.primitives if p.role == role]
|
||||
def test_tab_omits_rests_but_keeps_standard_notation(self):
|
||||
content = tests.test_musicxml.xml_note('E', 2, 'half', octave=5) + '<note><rest/><duration>2</duration><type>half</type></note>'
|
||||
source = tests.test_musicxml.parse(tests.test_musicxml.xml_score(content))
|
||||
document = generator.practice.generate.practice_document(source, 'electric', rhythms=tests.rhythm_fixtures.library())
|
||||
layout = self.layout(document)
|
||||
self.assertEqual(len(self.primitives(layout, 'rest')), 1)
|
||||
self.assertEqual(self.primitives(layout, 'tab-rest'), [])
|
||||
self.assertEqual(len(self.primitives(layout, 'tab')), 1)
|
||||
def assert_paired_pages(self, layout):
|
||||
self.assertTrue(all(len(page.systems) == 2 for page in layout.pages[:-1]))
|
||||
self.assertIn(len(layout.pages[-1].systems), (1, 2))
|
||||
for page in layout.pages:
|
||||
self.assertEqual(len({system.scale for system in page.systems}), 1)
|
||||
for first, second in zip(page.systems, page.systems[1:]):
|
||||
self.assertGreaterEqual(second.box.top - first.box.bottom, layout.style.system_gap - 0.001)
|
||||
def test_guitar_pages_always_pair_systems_including_tall_passages(self):
|
||||
content = tests.test_musicxml.xml_note('E', octave=5)
|
||||
source = tests.test_musicxml.parse(tests.test_accompaniment.xml_bars([content] * 32))
|
||||
document = generator.practice.generate.practice_document(source, 'electric', rhythms=tests.rhythm_fixtures.library())
|
||||
layout = self.layout(document)
|
||||
self.assert_paired_pages(layout)
|
||||
self.assertEqual(layout.style.space, 10)
|
||||
self.assertEqual(layout.style.tab_font_size, 12)
|
||||
wide = tests.test_musicxml.xml_note('E', octave=3) + tests.test_musicxml.xml_note('C', octave=7, prefix='<chord/>')
|
||||
document = tests.test_musicxml.parse(tests.test_accompaniment.xml_bars([wide] * 32))
|
||||
for measure in document['staves'][0]['measures']:
|
||||
measure['transpose']['octave_change'] = -1
|
||||
generator.guitar.place_guitar(document)
|
||||
tall = self.layout(document)
|
||||
self.assertGreater(len(tall.pages), 1)
|
||||
self.assert_paired_pages(tall)
|
||||
self.assertTrue(all(system.scale < 1 for page in tall.pages for system in page.systems))
|
||||
self.assertEqual(tall.style, layout.style)
|
||||
def test_vocal_pages_have_two_systems_and_an_odd_final_system(self):
|
||||
content = tests.test_musicxml.xml_note(extra='<lyric><syllabic>single</syllabic><text>doo</text></lyric>')
|
||||
source = tests.test_musicxml.parse(tests.test_accompaniment.xml_bars([content] * 32))
|
||||
style = generator.engraving.types.Style()
|
||||
systems = generator.engraving.layout.layout_systems(source, style, self.fonts)
|
||||
self.assertGreaterEqual(len(systems), 3)
|
||||
pages = generator.engraving.layout.paginate(systems[:3], source, self.fonts, style)
|
||||
self.assertEqual([len(page.systems) for page in pages], [2, 1])
|
||||
self.assert_paired_pages(self.layout(source))
|
||||
def test_two_voice_acoustic_systems_can_share_a_page(self):
|
||||
harmony = '<harmony><root><root-step>E</root-step></root><kind>major</kind></harmony>'
|
||||
content = harmony + tests.test_musicxml.xml_note('G', 2, 'half', alter=1) + tests.test_musicxml.xml_note('B', 2, 'half', prefix='<chord/>') + '<note><rest/><duration>2</duration><type>half</type></note>'
|
||||
content += '<backup><duration>4</duration></backup>' + tests.test_musicxml.xml_note('E', extra='<voice>2</voice>')
|
||||
document = tests.test_musicxml.parse(tests.test_accompaniment.xml_bars([content] * 16))
|
||||
positions = {'e': {'string': 5, 'fret': 7}, 'g': {'string': 4, 'fret': 6}, 'b': {'string': 3, 'fret': 4}}
|
||||
for measure in document['staves'][0]['measures']:
|
||||
measure['transpose']['octave_change'] = -1
|
||||
for voice in measure['voices']:
|
||||
for note in voice['notes']:
|
||||
for pitch in note['pitches']:
|
||||
pitch['tablature'] = positions[pitch['letter']]
|
||||
generator.guitar.place_guitar(document)
|
||||
layout = self.layout(document)
|
||||
self.assert_paired_pages(layout)
|
||||
self.assertTrue(self.primitives(layout, 'rest'))
|
||||
self.assertFalse(self.primitives(layout, 'tab-rest'))
|
||||
def test_notation_fixture_visual_golden(self):
|
||||
layout = self.layout(generator.musicxml.load_musicxml(pathlib.Path('tests/fixtures/notation.xml')))
|
||||
self.assertEqual(len(layout.pages), 1)
|
||||
@@ -206,7 +266,7 @@ class EngravingTests(unittest.TestCase):
|
||||
def test_wide_pitch_range_can_break_inside_a_measure_vertically(self):
|
||||
source = tests.test_musicxml.parse(tests.test_musicxml.xml_score(tests.test_musicxml.xml_note(duration=2, kind='half', octave=10) + tests.test_musicxml.xml_note(duration=2, kind='half', octave=-1)))
|
||||
layout = self.layout(source)
|
||||
self.assertEqual(len(layout.pages), 2)
|
||||
self.assertEqual([len(page.systems) for page in layout.pages], [2])
|
||||
self.assertEqual(len(self.primitives(layout, 'head')), 2)
|
||||
def test_cue_grace_and_tremolo_are_drawn(self):
|
||||
grace = '<note><grace slash="yes"/><pitch><step>D</step><octave>4</octave></pitch><type>16th</type></note>'
|
||||
@@ -251,7 +311,7 @@ class EngravingTests(unittest.TestCase):
|
||||
for bar, tab in zip(notation, tabs):
|
||||
for (x1, y1), (x2, y2) in zip(bar.points, tab.points):
|
||||
self.assertAlmostEqual(x1, x2)
|
||||
self.assertAlmostEqual((y1 - baselines['staff']) * 5 / 4, y2 - baselines['tab-staff'])
|
||||
self.assertAlmostEqual((y1 - baselines['staff']) * 5 * layout.style.tab_space / (4 * layout.style.space), y2 - baselines['tab-staff'])
|
||||
def test_adjacent_string_tab_numerals_do_not_overlap(self):
|
||||
content = ''.join(tests.test_musicxml.xml_note(step, octave=octave, prefix='<chord/>' if index else '') for index, (step, octave) in enumerate((('G', 3), ('C', 4), ('E', 4), ('G', 4), ('C', 5), ('E', 5))))
|
||||
source = tests.test_musicxml.parse(tests.test_musicxml.xml_score(content))
|
||||
|
||||
Reference in New Issue
Block a user