+33
-13
@@ -82,22 +82,22 @@ class VoicingTests(unittest.TestCase):
|
||||
self.assertEqual(generator.guitar.voicing_cost(grip((fret,) * 4)).effort, 2 * max(0, fret - 12))
|
||||
crossing = grip((11, 12, 13, 14))
|
||||
self.assertEqual(generator.guitar.voicing_cost(crossing).effort, 7)
|
||||
for profile in ('electric', 'acoustic'):
|
||||
self.assertEqual(generator.guitar.voicing_cost(crossing, profile).effort, 33)
|
||||
self.assertEqual(generator.guitar.voicing_cost(crossing, 'electric').effort, 33)
|
||||
self.assertEqual(generator.guitar.voicing_cost(crossing, 'acoustic').effort, 24)
|
||||
def test_chord_shape_and_height_share_one_effort_cost(self):
|
||||
shape = grip((1, 3, 4, 5))
|
||||
self.assertEqual(generator.guitar.voicing_cost(shape).effort, 4)
|
||||
for profile in ('electric', 'acoustic'):
|
||||
self.assertEqual(generator.guitar.voicing_cost(shape, profile).effort, 23)
|
||||
self.assertEqual(generator.guitar.voicing_cost(shape, 'electric').effort, 23)
|
||||
self.assertEqual(generator.guitar.voicing_cost(shape, 'acoustic').effort, 11)
|
||||
for profile in ('', 'electric', 'acoustic'):
|
||||
self.assertLess(generator.guitar.voicing_cost(grip((4, 4, 4, 4)), profile), generator.guitar.voicing_cost(grip((2, 4, 1, 3)), profile))
|
||||
def test_distinct_frets_add_difficulty_even_with_the_same_span(self):
|
||||
simple, varied = grip((3, 3, 5, 5)), grip((3, 4, 5, 5))
|
||||
for profile in ('electric', 'acoustic'):
|
||||
self.assertEqual(generator.guitar.voicing_cost(simple, profile).effort, 13)
|
||||
self.assertEqual(generator.guitar.voicing_cost(varied, profile).effort, 15)
|
||||
for profile, expected in (('electric', 13), ('acoustic', 7)):
|
||||
self.assertEqual(generator.guitar.voicing_cost(simple, profile).effort, expected)
|
||||
self.assertEqual(generator.guitar.voicing_cost(varied, profile).effort, expected + 2)
|
||||
self.assertEqual(generator.guitar.voicing_cost(simple).effort, generator.guitar.voicing_cost(varied).effort)
|
||||
def test_compact_mid_neck_acoustic_pair_beats_high_and_stretched_low_pairs(self):
|
||||
def test_acoustic_reach_excludes_stretched_low_pair_before_scoring(self):
|
||||
high = [grip((12, 12, 12, 11), (6, 4, 3, 2)), grip((12, 11, 12, 11), (6, 4, 3, 2))]
|
||||
requested = [grip((7, 8, 7, 8), (5, 4, 3, 2)), grip((7, 8, 6, 8), (5, 4, 3, 2))]
|
||||
low = [grip((6, 5, 3, 3), (6, 4, 3, 2)), grip((5, 5, 3, 2), (6, 4, 3, 2))]
|
||||
@@ -108,20 +108,40 @@ class VoicingTests(unittest.TestCase):
|
||||
self.assertIn(shape, candidates)
|
||||
self.assertEqual({p.midi % 12 for p in upper}, {p.midi % 12 for p in middle})
|
||||
self.assertEqual(min(p.midi for p in upper), min(p.midi for p in middle))
|
||||
preferred = generator.guitar.acoustic_positions(requirements)
|
||||
self.assertIn(middle, preferred)
|
||||
self.assertIn(upper, preferred)
|
||||
self.assertNotIn(lower, preferred)
|
||||
costs = [sum(generator.guitar.voicing_cost(s, 'acoustic').effort for s in pair) + 2 * generator.guitar.acoustic_movement(*pair) for pair in (requested, high, low)]
|
||||
self.assertEqual(costs, [33, 36, 41])
|
||||
def test_real_autumn_leaves_lead_in_uses_requested_compact_grips(self):
|
||||
self.assertEqual(costs, [24, 30, 23])
|
||||
def test_real_autumn_leaves_cadences_use_comfortable_inversions_and_complete_triads(self):
|
||||
source = generator.musicxml.load_musicxml(pathlib.Path('data/songs/autumn-leaves.xml'))
|
||||
before = copy.deepcopy(source)
|
||||
result = generator.arrange.generate.arrange_document(source, 'acoustic', rhythms=generator.rhythm.load_library(pathlib.Path('data/rhythms')))
|
||||
generator.model.validate_document(result)
|
||||
measures = result['staves'][0]['measures'][:2]
|
||||
measures = result['staves'][0]['measures']
|
||||
self.assertEqual(measures[0]['section_label'], 'Rhythm Lead-in')
|
||||
for measure, symbol, expected in zip(measures, ('Em7b5', 'A7b9'), (((5, 7), (4, 8), (3, 7), (2, 8)), ((5, 7), (4, 8), (3, 6), (2, 8)))):
|
||||
with self.subTest(chord=symbol):
|
||||
for index, symbol, expected in ((0, 'Em7b5', ((6, 3), (4, 2), (3, 3), (2, 3))), (1, 'A7b9', ((6, 3), (4, 2), (3, 3), (2, 2))), (4, 'Em7b5', ((6, 3), (4, 2), (3, 3), (2, 3))), (5, 'A7b9', ((6, 3), (4, 2), (3, 3), (2, 2)))):
|
||||
measure = measures[index]
|
||||
with self.subTest(measure=measure['number'], chord=symbol):
|
||||
self.assertEqual(generator.harmony.symbol(measure['harmonies'][0]), symbol)
|
||||
positions = {(p['tablature']['string'], p['tablature']['fret']) for v in measure['voices'] for n in v['notes'] for p in n['pitches']}
|
||||
self.assertEqual(tuple(sorted(positions, reverse=True)), expected)
|
||||
checked = set()
|
||||
for measure in measures:
|
||||
if measure['number'] not in ('26', '27', '30', '31', '32', '33'):
|
||||
continue
|
||||
pitches = [p for v in measure['voices'] for n in v['notes'] for p in n['pitches']]
|
||||
if not pitches:
|
||||
continue
|
||||
positions = tuple(generator.guitar.TabPosition(p['tablature']['string'], p['tablature']['fret'], int(generator.model.pitch_number(p)) - 12) for p in pitches)
|
||||
self.assertLessEqual(generator.guitar.physical_reach(positions), generator.guitar.PREFERRED_ACOUSTIC_REACH, measure['id'])
|
||||
self.assertTrue(all('tie_from' not in p and 'tie_to' not in p for p in pitches))
|
||||
if measure['number'] in ('32', '33'):
|
||||
self.assertEqual({p.midi % 12 for p in positions}, {2, 5, 9})
|
||||
checked.add(measure['number'])
|
||||
self.assertEqual(checked, {'26', '27', '30', '31', '32', '33'})
|
||||
self.assertEqual(result, generator.arrange.generate.arrange_document(source, 'acoustic', rhythms=generator.rhythm.load_library(pathlib.Path('data/rhythms'))))
|
||||
self.assertEqual(source, before)
|
||||
def test_acoustic_simpler_three_note_shape_can_beat_four_notes(self):
|
||||
candidates = ranked('Csus', profile='acoustic')
|
||||
|
||||
Reference in New Issue
Block a user