+55
-54
@@ -1,77 +1,78 @@
|
||||
import copy
|
||||
from fractions import Fraction
|
||||
from pathlib import Path
|
||||
import fractions
|
||||
import pathlib
|
||||
import unittest
|
||||
|
||||
from generator.engraving import Fonts, Style, layout_score
|
||||
from generator.engraving.layout import make_system
|
||||
from generator.engraving.notation import ScoreIndex
|
||||
from generator.model import rational
|
||||
from generator.playback import compile_timeline
|
||||
from generator.scat import add_scat, pulse, syllable
|
||||
from tests.test_musicxml import notes, parse, xml_note, xml_score
|
||||
import generator.engraving.fonts
|
||||
import generator.engraving.layout
|
||||
import generator.engraving.notation
|
||||
import generator.engraving.types
|
||||
import generator.model
|
||||
import generator.playback
|
||||
import generator.scat
|
||||
import tests.test_musicxml
|
||||
|
||||
class ScatTests(unittest.TestCase):
|
||||
def test_syllables_use_duration_pulse_phrase_and_previous_consonant(self):
|
||||
self.assertEqual(syllable(Fraction(2), Fraction(1), False, True, ''), 'doo')
|
||||
self.assertEqual(syllable(Fraction(1, 2), Fraction(1), True, False, ''), 'ba')
|
||||
self.assertEqual(syllable(Fraction(1, 2), Fraction(1), False, False, ''), 'dit')
|
||||
self.assertEqual(syllable(Fraction(1, 2), Fraction(1), False, False, 'dit'), 'da')
|
||||
self.assertEqual(syllable(Fraction(1, 2), Fraction(1), True, True, ''), 'dat')
|
||||
self.assertEqual(syllable(Fraction(1, 2), None, False, False, ''), 'ba')
|
||||
self.assertEqual(generator.scat.syllable(fractions.Fraction(2), fractions.Fraction(1), False, True, ''), 'doo')
|
||||
self.assertEqual(generator.scat.syllable(fractions.Fraction(1, 2), fractions.Fraction(1), True, False, ''), 'ba')
|
||||
self.assertEqual(generator.scat.syllable(fractions.Fraction(1, 2), fractions.Fraction(1), False, False, ''), 'dit')
|
||||
self.assertEqual(generator.scat.syllable(fractions.Fraction(1, 2), fractions.Fraction(1), False, False, 'dit'), 'da')
|
||||
self.assertEqual(generator.scat.syllable(fractions.Fraction(1, 2), fractions.Fraction(1), True, True, ''), 'dat')
|
||||
self.assertEqual(generator.scat.syllable(fractions.Fraction(1, 2), None, False, False, ''), 'ba')
|
||||
def test_compound_additive_meter_and_pickups(self):
|
||||
measure = {'meter': {'groups': [{'beats': [6], 'unit': 8}]}, 'duration': rational(3)}
|
||||
self.assertEqual(pulse(measure, Fraction(3, 2)), (Fraction(3, 2), True))
|
||||
measure = {'meter': {'groups': [{'beats': [6], 'unit': 8}]}, 'duration': generator.model.rational(3)}
|
||||
self.assertEqual(generator.scat.pulse(measure, fractions.Fraction(3, 2)), (fractions.Fraction(3, 2), True))
|
||||
measure['meter']['groups'][0]['beats'] = [3, 2]
|
||||
self.assertEqual(pulse(measure, Fraction(3, 2)), (Fraction(1), True))
|
||||
measure.update(implicit=True, duration=rational(Fraction(1, 2)))
|
||||
self.assertEqual(pulse(measure, Fraction()), (Fraction(1), False))
|
||||
self.assertEqual(generator.scat.pulse(measure, fractions.Fraction(3, 2)), (fractions.Fraction(1), True))
|
||||
measure.update(implicit=True, duration=generator.model.rational(fractions.Fraction(1, 2)))
|
||||
self.assertEqual(generator.scat.pulse(measure, fractions.Fraction()), (fractions.Fraction(1), False))
|
||||
def test_ties_sustain_one_syllable_and_stop_before_rests(self):
|
||||
content = xml_note(duration=1, kind='quarter', extra='<tie type="start"/>') + xml_note(duration=1, kind='quarter', extra='<tie type="stop"/>')
|
||||
content = tests.test_musicxml.xml_note(duration=1, kind='quarter', extra='<tie type="start"/>') + tests.test_musicxml.xml_note(duration=1, kind='quarter', extra='<tie type="stop"/>')
|
||||
content += '<note><rest/><duration>2</duration><type>half</type></note>'
|
||||
document = parse(xml_score(content))
|
||||
document = tests.test_musicxml.parse(tests.test_musicxml.xml_score(content))
|
||||
original = copy.deepcopy(document)
|
||||
before = compile_timeline(document)
|
||||
add_scat(document)
|
||||
self.assertEqual(compile_timeline(document), before)
|
||||
self.assertEqual(notes(document)[0]['lyric'], 'doo')
|
||||
self.assertEqual(notes(document)[0]['lyrics'][0]['extend_to'], rational(2))
|
||||
self.assertNotIn('lyric', notes(document)[1])
|
||||
self.assertNotIn('lyrics', notes(document)[2])
|
||||
before = generator.playback.compile_timeline(document)
|
||||
generator.scat.add_scat(document)
|
||||
self.assertEqual(generator.playback.compile_timeline(document), before)
|
||||
self.assertEqual(tests.test_musicxml.notes(document)[0]['lyric'], 'doo')
|
||||
self.assertEqual(tests.test_musicxml.notes(document)[0]['lyrics'][0]['extend_to'], generator.model.rational(2))
|
||||
self.assertNotIn('lyric', tests.test_musicxml.notes(document)[1])
|
||||
self.assertNotIn('lyrics', tests.test_musicxml.notes(document)[2])
|
||||
again = copy.deepcopy(original)
|
||||
add_scat(again)
|
||||
generator.scat.add_scat(again)
|
||||
self.assertEqual(document, again)
|
||||
fonts = Fonts(Path('package/assets/fonts/petaluma'))
|
||||
layout = layout_score(document, Style(), fonts)
|
||||
fonts = generator.engraving.fonts.Fonts(pathlib.Path('package/assets/fonts/petaluma'))
|
||||
layout = generator.engraving.layout.layout_score(document, generator.engraving.types.Style(), fonts)
|
||||
system = layout.pages[0].systems[0]
|
||||
rest = next(a.x for a in system.anchors if a.fragment.kind == 'rest')
|
||||
self.assertTrue(all(p.box.right < rest for p in system.primitives if p.role == 'lyric-extension'))
|
||||
def test_cross_bar_tie_has_one_lyric_and_page_continuations(self):
|
||||
text = xml_score(xml_note(extra='<tie type="start"/>'))
|
||||
text = text.replace('</measure></part>', '</measure><measure number="2">' + xml_note(extra='<tie type="stop"/>') + '</measure></part>')
|
||||
document = parse(text)
|
||||
add_scat(document)
|
||||
self.assertEqual(sum(bool(n.get('lyric')) for n in notes(document)), 1)
|
||||
fonts = Fonts(Path('package/assets/fonts/petaluma'))
|
||||
text = tests.test_musicxml.xml_score(tests.test_musicxml.xml_note(extra='<tie type="start"/>'))
|
||||
text = text.replace('</measure></part>', '</measure><measure number="2">' + tests.test_musicxml.xml_note(extra='<tie type="stop"/>') + '</measure></part>')
|
||||
document = tests.test_musicxml.parse(text)
|
||||
generator.scat.add_scat(document)
|
||||
self.assertEqual(sum(bool(n.get('lyric')) for n in tests.test_musicxml.notes(document)), 1)
|
||||
fonts = generator.engraving.fonts.Fonts(pathlib.Path('package/assets/fonts/petaluma'))
|
||||
for start, end in ((0, 4), (4, 8)):
|
||||
system = make_system(ScoreIndex(document), start, end, fonts, Style())
|
||||
system = generator.engraving.layout.make_system(generator.engraving.notation.ScoreIndex(document), start, end, fonts, generator.engraving.types.Style())
|
||||
self.assertTrue(any(p.role == 'lyric-extension' for p in system.primitives))
|
||||
def test_long_tie_chain_draws_one_extender_per_system(self):
|
||||
text = xml_score(xml_note(extra='<tie type="start"/>'))
|
||||
text = text.replace('</measure></part>', '</measure><measure number="2">' + xml_note(extra='<tie type="stop"/><tie type="start"/>') + '</measure><measure number="3">' + xml_note(extra='<tie type="stop"/>') + '</measure></part>')
|
||||
document = parse(text)
|
||||
add_scat(document)
|
||||
fonts = Fonts(Path('package/assets/fonts/petaluma'))
|
||||
index = ScoreIndex(document)
|
||||
text = tests.test_musicxml.xml_score(tests.test_musicxml.xml_note(extra='<tie type="start"/>'))
|
||||
text = text.replace('</measure></part>', '</measure><measure number="2">' + tests.test_musicxml.xml_note(extra='<tie type="stop"/><tie type="start"/>') + '</measure><measure number="3">' + tests.test_musicxml.xml_note(extra='<tie type="stop"/>') + '</measure></part>')
|
||||
document = tests.test_musicxml.parse(text)
|
||||
generator.scat.add_scat(document)
|
||||
fonts = generator.engraving.fonts.Fonts(pathlib.Path('package/assets/fonts/petaluma'))
|
||||
index = generator.engraving.notation.ScoreIndex(document)
|
||||
for start, end in ((0, 4), (4, 8), (8, 12), (0, 12)):
|
||||
system = make_system(index, start, end, fonts, Style())
|
||||
system = generator.engraving.layout.make_system(index, start, end, fonts, generator.engraving.types.Style())
|
||||
self.assertEqual(sum(p.role == 'lyric-extension' for p in system.primitives), 1)
|
||||
def test_straight_offbeat_attacks_and_cues(self):
|
||||
document = parse(xml_score(''.join(xml_note(duration=1, kind='eighth') for _ in range(8)), divisions=2))
|
||||
before = compile_timeline(document)
|
||||
add_scat(document)
|
||||
self.assertEqual([n['lyric'] for n in notes(document)], ['ba', 'dit', 'ba', 'dit', 'ba', 'dit', 'ba', 'dat'])
|
||||
self.assertEqual(compile_timeline(document), before)
|
||||
document = parse(xml_score(xml_note(prefix='<cue/>')))
|
||||
add_scat(document)
|
||||
self.assertNotIn('lyrics', notes(document)[0])
|
||||
document = tests.test_musicxml.parse(tests.test_musicxml.xml_score(''.join(tests.test_musicxml.xml_note(duration=1, kind='eighth') for _ in range(8)), divisions=2))
|
||||
before = generator.playback.compile_timeline(document)
|
||||
generator.scat.add_scat(document)
|
||||
self.assertEqual([n['lyric'] for n in tests.test_musicxml.notes(document)], ['ba', 'dit', 'ba', 'dit', 'ba', 'dit', 'ba', 'dat'])
|
||||
self.assertEqual(generator.playback.compile_timeline(document), before)
|
||||
document = tests.test_musicxml.parse(tests.test_musicxml.xml_score(tests.test_musicxml.xml_note(prefix='<cue/>')))
|
||||
generator.scat.add_scat(document)
|
||||
self.assertNotIn('lyrics', tests.test_musicxml.notes(document)[0])
|
||||
|
||||
Reference in New Issue
Block a user