Sustained Rhythm
ci / checks (push) Successful in 47m43s

This commit is contained in:
khodowany
2026-09-30 02:18:31 -05:00
parent 8a23fa0fc2
commit 923b7f14e2
826 changed files with 57641 additions and 35 deletions
+24 -2
View File
@@ -170,9 +170,31 @@ class GuitarPartTests(unittest.TestCase):
expected = 76 if part == 'electric' else 64
self.assertEqual({generator.model.pitch_number(n['pitches'][0]) for n in notes}, {expected})
self.assertEqual(source, before)
def test_electric_stabs_are_capped_and_do_not_continue(self):
def test_electric_whole_notes_are_uncapped_but_do_not_continue(self):
source = tests.test_accompaniment.melody_measures(1)[0]
for continuation in (False, True):
bar = generator.rhythm.Bar((generator.rhythm.Event(fractions.Fraction(), fractions.Fraction(4), True, 'whole', continuation=continuation),), fractions.Fraction(4))
events = generator.accompaniment.realize(source, bar, None, lane='electric')
self.assertEqual(tests.test_accompaniment.timing(events), [(0, 4, 'rest')] if continuation else [(0, 1, 'note'), (1, 3, 'rest')])
self.assertEqual(tests.test_accompaniment.timing(events), [(0, 4, 'rest')] if continuation else [(0, 4, 'note')])
def test_long_electric_accompaniment_preserves_playback_durations_without_ties(self):
content = tests.test_parts.xml_harmony() + tests.test_musicxml.xml_note('E', octave=4)
source = tests.test_musicxml.parse(tests.test_accompaniment.xml_bars([content] * 8))
bar = generator.rhythm.Bar((generator.rhythm.Event(fractions.Fraction(), fractions.Fraction(4), True, 'whole'),), fractions.Fraction(4))
library = generator.rhythm.Library((generator.rhythm.Snippet('4-4/3/whole', '4/4', (bar,)),))
result = generator.arrange.generate.arrange_document(source, 'electric', rhythms=library)
generator.model.validate_document(result)
durations = {}
section = ''
for measure in result['staves'][0]['measures']:
section = measure.get('section_label') or section
if section not in ('Vocal Melody', 'Ending'):
continue
notes = measure['voices'][0]['notes']
self.assertEqual(tests.test_accompaniment.timing(notes), [(0, 4, 'note')])
for pitch in notes[0]['pitches']:
self.assertNotIn('tie_from', pitch)
self.assertNotIn('tie_to', pitch)
durations[pitch['id']] = generator.model.fraction(pitch['duration'])
self.assertTrue(durations)
timeline = generator.playback.compile_timeline(result)['events']
self.assertEqual({e['id']: generator.model.fraction(e['duration']) for e in timeline if e['id'] in durations}, durations)