def test_hammer_on_tie_is_kept_on_first_note(self):
        position = FretPosition(string=3, fret=1)
        notes = [
            Note(order=0,
                 position=position,
                 duration=Beat(3),
                 elapsed_beats=Beat(3),
                 slur=constants.HAMMER_ON),
            Note(order=1,
                 position=position,
                 duration=Beat(1),
                 elapsed_beats=Beat(4)),
        ]

        result = normalise_note_durations(notes)

        expected = [
            Note(order=0,
                 position=position,
                 duration=Beat(1, 2),
                 elapsed_beats=Beat(1, 2),
                 slur=constants.HAMMER_ON),
            Note(order=1,
                 position=position,
                 duration=Beat(1, 4, tie=True),
                 elapsed_beats=Beat(3, 4)),
            Note(order=2,
                 position=position,
                 duration=Beat(1, 4),
                 elapsed_beats=Beat(1, 1)),
        ]

        self.assertEqual(expected, result)
예제 #2
0
    def test_chords_can_have_bends(self):
        duration = Beat(1, 4)

        notes = [
            Note(order=0,
                 position=FretPosition(12, 5),
                 duration=duration,
                 elapsed_beats=Beat(1, 4)),
            Note(order=0,
                 position=FretPosition(12, 4),
                 duration=duration,
                 elapsed_beats=Beat(1, 4)),
            Note(order=1,
                 position=FretPosition(14, 5),
                 duration=duration,
                 elapsed_beats=Beat(2, 4),
                 slur=BEND),
            Note(order=1,
                 position=FretPosition(14, 4),
                 duration=duration,
                 elapsed_beats=Beat(2, 4),
                 slur=BEND),
        ]
        shapes = [GuitarShape(name='shape1', positions=[], category='scale')]
        sequence = Sequence(notes=notes, shapes=shapes)

        vextab = to_vextab(sequence)

        expected = ('tabstave notation=false\n'
                    'notes =|: :q (12/5.12/4) :q b(14/5.14/4) =:|')

        self.assertEqual(expected, vextab)
    def test_split_beats_are_in_ascending_order_if_not_at_start_of_bar(self):
        position = FretPosition(string=3, fret=1)
        notes = [
            Note(order=0,
                 position=position,
                 duration=Beat(1),
                 elapsed_beats=Beat(1)),
            Note(order=1,
                 position=position,
                 duration=Beat(3),
                 elapsed_beats=Beat(4)),
        ]

        result = normalise_note_durations(notes)

        expected = [
            Note(order=0,
                 position=position,
                 duration=Beat(1, 4),
                 elapsed_beats=Beat(1, 4)),
            Note(order=1,
                 position=position,
                 duration=Beat(1, 4),
                 elapsed_beats=Beat(2, 4)),
            Note(order=2,
                 position=position,
                 duration=Beat(2, 4, tie=True),
                 elapsed_beats=Beat(1, 1)),
        ]

        self.assertEqual(expected, result)
예제 #4
0
    def test_half_notes_have_a_h_duration(self):
        position = FretPosition(string=6, fret=5)
        duration = Beat(2, 4)

        notes = [
            Note(order=1,
                 position=position,
                 duration=duration,
                 elapsed_beats=Beat(2, 4)),
            Note(order=2,
                 position=position,
                 duration=duration,
                 elapsed_beats=Beat(4, 4)),
            Note(order=3,
                 position=position,
                 duration=duration,
                 elapsed_beats=Beat(6, 4)),
            Note(order=4,
                 position=position,
                 duration=duration,
                 elapsed_beats=Beat(8, 4)),
        ]
        shapes = [
            GuitarShape(name='shape1', positions=[position], category='scale')
        ]
        sequence = Sequence(notes=notes, shapes=shapes)

        vextab = to_vextab(sequence)

        expected = ('tabstave notation=false\n'
                    'notes =|: :h 5/6 :h 5/6 | :h 5/6 :h 5/6 =:|')
        self.assertEqual(expected, vextab)
    def test_odd_length_quarter_note_is_split(self):
        position = FretPosition(string=3, fret=1)
        notes = [
            Note(order=0,
                 position=position,
                 duration=Beat(3),
                 elapsed_beats=Beat(3)),
            Note(order=1,
                 position=position,
                 duration=Beat(1),
                 elapsed_beats=Beat(4)),
        ]

        result = normalise_note_durations(notes)

        expected = [
            Note(order=0,
                 position=position,
                 duration=Beat(1, 2),
                 elapsed_beats=Beat(1, 2)),
            Note(order=1,
                 position=position,
                 duration=Beat(1, 4, tie=True),
                 elapsed_beats=Beat(3, 4)),
            Note(order=2,
                 position=position,
                 duration=Beat(1, 4),
                 elapsed_beats=Beat(1, 1)),
        ]

        self.assertEqual(expected, result)
예제 #6
0
    def test_can_add_two_half_notes_together(self):
        beat1 = Beat(duration=1, division=2)
        beat2 = Beat(duration=1, division=2)

        result = beat1 + beat2

        self.assertEqual(Beat(duration=1, division=1), result)
예제 #7
0
    def test_can_add_two_triplets_together(self):
        beat1 = Beat(duration=1, division=3)
        beat2 = Beat(duration=1, division=3)

        result = beat1 + beat2

        self.assertEqual(Beat(duration=2, division=3), result)
예제 #8
0
    def test_palm_mutes_are_added_to_tab_as_text(self):
        position = FretPosition(string=6, fret=5)
        duration = Beat(1, 8)

        notes = [
            Note(order=0,
                 position=position,
                 duration=duration,
                 elapsed_beats=Beat(1, 4),
                 annotations=[PALM_MUTE]),
            Note(order=1,
                 position=position,
                 duration=duration,
                 elapsed_beats=Beat(2, 4),
                 annotations=[PALM_MUTE]),
        ]
        shapes = [
            GuitarShape(name='shape1', positions=[position], category='scale')
        ]
        sequence = Sequence(notes=notes, shapes=shapes)

        vextab = to_vextab(sequence)

        expected = ('tabstave notation=false\n'
                    'notes =|: :8 5/6 $.top.pm$ :8 5/6 $.top.pm$ =:|')

        self.assertEqual(expected, vextab)
예제 #9
0
    def test_can_palm_mute_and_down_pick_on_tabs(self):
        duration = Beat(1, 4)

        notes = [
            Note(order=0,
                 position=FretPosition(12, 5),
                 duration=duration,
                 elapsed_beats=Beat(1, 4),
                 annotations=[DOWN_PICK, PALM_MUTE]),
            Note(order=1,
                 position=FretPosition(14, 5),
                 duration=duration,
                 elapsed_beats=Beat(2, 4),
                 annotations=[DOWN_PICK, PALM_MUTE]),
        ]
        shapes = [GuitarShape(name='shape1', positions=[], category='scale')]
        sequence = Sequence(notes=notes, shapes=shapes)

        vextab = to_vextab(sequence)

        expected = (
            'tabstave notation=false\n'
            'notes =|: :q 12/5 $.am/top.$ $.top.pm$ :q 14/5 $.am/top.$ $.top.pm$ =:|'
        )

        self.assertEqual(expected, vextab)
예제 #10
0
    def test_shape_is_converted_into_notes(self):
        positions = [
            FretPosition(string=1, fret=1),
            FretPosition(string=1, fret=2),
            FretPosition(string=1, fret=3),
            FretPosition(string=1, fret=4),
        ]
        shape = GuitarShape(name='shape1',
                            positions=positions,
                            category='scale')

        sequence = make_sequence([shape])

        duration = Beat(duration=1)
        expected_notes = [
            Note(order=0,
                 position=positions[0],
                 duration=duration,
                 elapsed_beats=Beat(1)),
            Note(order=1,
                 position=positions[1],
                 duration=duration,
                 elapsed_beats=Beat(2)),
            Note(order=2,
                 position=positions[2],
                 duration=duration,
                 elapsed_beats=Beat(3)),
            Note(order=3,
                 position=positions[3],
                 duration=duration,
                 elapsed_beats=Beat(4)),
        ]
        self.assertEqual(expected_notes, sequence.notes)
        self.assertEqual([shape], sequence.shapes)
예제 #11
0
    def test_taps_are_added_to_tab(self):
        position = FretPosition(string=6, fret=5)
        duration = Beat(1, 8)

        notes = [
            Note(order=0,
                 position=position,
                 duration=duration,
                 elapsed_beats=Beat(1, 4)),
            Note(order=1,
                 position=position,
                 duration=duration,
                 elapsed_beats=Beat(2, 4),
                 slur=TAP),
        ]
        shapes = [
            GuitarShape(name='shape1', positions=[position], category='scale')
        ]
        sequence = Sequence(notes=notes, shapes=shapes)

        vextab = to_vextab(sequence)

        expected = ('tabstave notation=false\n'
                    'notes =|: :8 5/6 t:8: 5/6 =:|')

        self.assertEqual(expected, vextab)
예제 #12
0
    def test_shape_name_is_not_added_if_short_name_is_none(self):
        positions = [
            FretPosition(0, 6),
            FretPosition(2, 5),
        ]
        shapes = [
            GuitarShape(category='chord',
                        name='E5 Power Chord',
                        positions=positions)
        ]

        result = make_sequence(shapes,
                               pick_pattern=pickpatterns.strum,
                               tab_labels=True,
                               rhythm=[Beat(4)])

        expected = [
            Note(position=positions[0],
                 duration=Beat(4),
                 elapsed_beats=Beat(1, 1),
                 order=0),
            Note(position=positions[1],
                 duration=Beat(4),
                 elapsed_beats=Beat(1, 1),
                 order=0),
        ]

        self.assertEqual(expected, result.notes)
예제 #13
0
    def test_shape_name_is_added_to_annotations(self):
        positions = [
            FretPosition(0, 6),
            FretPosition(2, 5),
        ]
        shapes = [
            GuitarShape(category='chord',
                        name='E5 Power Chord',
                        positions=positions,
                        short_name='E5')
        ]

        sequence = make_sequence(shapes,
                                 pick_pattern=pickpatterns.strum,
                                 tab_labels=True,
                                 rhythm=[Beat(4)])

        expected_notes = [
            Note(position=positions[0],
                 duration=Beat(4),
                 elapsed_beats=Beat(1, 1),
                 order=0,
                 annotations=['label:E5']),
            Note(position=positions[1],
                 duration=Beat(4),
                 elapsed_beats=Beat(1, 1),
                 order=0,
                 annotations=['label:E5']),
        ]

        self.assertEqual(expected_notes, sequence.notes)
        self.assertEqual(shapes, sequence.shapes)
예제 #14
0
    def test_can_add_to_zero_duration_beat(self):
        beat1 = Beat(duration=0, division=1)
        beat2 = Beat(duration=1, division=1)

        result = beat1 + beat2

        self.assertEqual(Beat(duration=1, division=1), result)
예제 #15
0
    def test_can_add_a_half_and_whole_note_together(self):
        beat1 = Beat(duration=1, division=2)
        beat2 = Beat(duration=1, division=1)

        result = beat1 + beat2

        self.assertEqual(Beat(duration=3, division=2), result)
    def test_ties_are_not_added_to_rests(self):
        position = FretPosition(string=3, fret=1)
        notes = [
            Note(order=0,
                 position=None,
                 duration=Beat(3, rest=True),
                 elapsed_beats=Beat(3)),
            Note(order=1,
                 position=position,
                 duration=Beat(1),
                 elapsed_beats=Beat(4)),
        ]

        result = normalise_note_durations(notes)

        expected = [
            Note(order=0,
                 position=None,
                 duration=Beat(1, 2, rest=True),
                 elapsed_beats=Beat(1, 2)),
            Note(order=1,
                 position=None,
                 duration=Beat(1, 4, rest=True),
                 elapsed_beats=Beat(3, 4)),
            Note(order=2,
                 position=position,
                 duration=Beat(1, 4),
                 elapsed_beats=Beat(1, 1)),
        ]

        self.assertEqual(expected, result)
예제 #17
0
    def test_rest_beats_are_added_to_sequence_and_ignored_by_pick_pattern(
            self):
        rhythm = [
            Beat(duration=1),
            Beat(duration=1, rest=True),
            Beat(duration=1),
        ]
        pattern = make_single_position_pattern(length=2)

        notes = apply_rhythm(pattern, rhythm)

        self.assertEqual(3, len(notes))
        self.assertEqual(
            Note(position=pattern[0][0],
                 duration=Beat(1),
                 order=0,
                 elapsed_beats=Beat(1)), notes[0])
        self.assertEqual(
            Note(position=None,
                 duration=Beat(1, rest=True),
                 order=1,
                 elapsed_beats=Beat(2)), notes[1])
        self.assertEqual(
            Note(position=pattern[1][0],
                 duration=Beat(1),
                 order=2,
                 elapsed_beats=Beat(3)), notes[2])
예제 #18
0
    def test_can_set_rhythm_for_sequence(self):
        rhythm = [
            Beat(duration=1, division=4),
            Beat(duration=1, division=2),
            Beat(duration=1, division=4),
        ]

        positions = [
            FretPosition(string=1, fret=1),
            FretPosition(string=1, fret=2),
            FretPosition(string=1, fret=3),
        ]
        shape = GuitarShape(name='shape1',
                            positions=positions,
                            category='scale')

        sequence = make_sequence([shape], rhythm=rhythm)

        expected_notes = [
            Note(order=0,
                 position=positions[0],
                 duration=Beat(1),
                 elapsed_beats=Beat(1)),
            Note(order=1,
                 position=positions[1],
                 duration=Beat(1, 2),
                 elapsed_beats=Beat(3, 4)),
            Note(order=2,
                 position=positions[2],
                 duration=Beat(1, 4),
                 elapsed_beats=Beat(4, 4)),
        ]
        self.assertEqual(expected_notes, sequence.notes)
        self.assertEqual([shape], sequence.shapes)
예제 #19
0
    def test_rhythm_is_repeated_when_shorter_than_pattern(self):
        rhythm = [
            Beat(duration=1),
        ]
        pattern = make_single_position_pattern(length=4)

        notes = apply_rhythm(pattern, rhythm)

        self.assertEqual(4, len(notes))
        self.assertEqual(
            Note(position=pattern[0][0],
                 duration=Beat(1),
                 order=0,
                 elapsed_beats=Beat(1)), notes[0])
        self.assertEqual(
            Note(position=pattern[1][0],
                 duration=Beat(1),
                 order=1,
                 elapsed_beats=Beat(2)), notes[1])
        self.assertEqual(
            Note(position=pattern[2][0],
                 duration=Beat(1),
                 order=2,
                 elapsed_beats=Beat(3)), notes[2])
        self.assertEqual(
            Note(position=pattern[3][0],
                 duration=Beat(1),
                 order=3,
                 elapsed_beats=Beat(4)), notes[3])
예제 #20
0
def eighth_chugs() -> Dict:
    return {
        'shapes': [
            open_string(),
            open_string(),
        ],
        'rhythm': [
            Beat(1, 8),
            Beat(1, 8),
        ],
    }
예제 #21
0
def down_pick_alternating_beats(notes: List[Note],
                                shapes: List[GuitarShape]) -> List[Note]:
    prev_elapsed_beat = Beat(0, 1)

    for note in notes:
        beat_division = (prev_elapsed_beat + Beat(1, 1)).division
        if beat_division == 2 or beat_division == 1:
            note.annotations.append(DOWN_PICK)

        prev_elapsed_beat = note.elapsed_beats

    return notes
예제 #22
0
    def test_multi_bar_beats_are_broken_down(self):
        duration = Beat(5, 1) + Beat(1, 2)
        result = duration.tie_split()

        expected = [
            Beat(1, 1),
            Beat(1, 1),
            Beat(1, 1),
            Beat(1, 1),
            Beat(1, 1),
            Beat(1, 2)
        ]
        self.assertEqual(expected, result)
예제 #23
0
    def test_hammer_on_tie_is_added_to_asc_positions(self):
        notes = [
            Note(order=0, position=FretPosition(5, 6), duration=Beat(1), elapsed_beats=Beat(1)),
            Note(order=1, position=FretPosition(7, 6), duration=Beat(1), elapsed_beats=Beat(2)),
        ]

        result = hammer_on_asc(notes, None)

        expected = [
            Note(order=0, position=FretPosition(5, 6), duration=Beat(1), elapsed_beats=Beat(1)),
            Note(order=1, position=FretPosition(7, 6), duration=Beat(1), elapsed_beats=Beat(2), slur=HAMMER_ON),
        ]

        self.assertEqual(expected, result)
예제 #24
0
    def test_can_apply_rhythm_to_chords_and_individual_notes(self):
        pattern = [
            [
                FretPosition(string=6, fret=1),
                FretPosition(string=5, fret=3),
            ],
            [FretPosition(string=6, fret=0)],
        ]

        rhythm = [
            Beat(duration=1),
            Beat(duration=1),
        ]

        notes = apply_rhythm(pattern, rhythm)

        self.assertEqual(3, len(notes))
        self.assertEqual(
            Note(position=pattern[0][0],
                 duration=Beat(1),
                 order=0,
                 elapsed_beats=Beat(1)), notes[0])
        self.assertEqual(
            Note(position=pattern[0][1],
                 duration=Beat(1),
                 order=0,
                 elapsed_beats=Beat(1)), notes[1])
        self.assertEqual(
            Note(position=pattern[1][0],
                 duration=Beat(1),
                 order=1,
                 elapsed_beats=Beat(2)), notes[2])
예제 #25
0
    def test_hammer_on_is_not_added_after_string_change(self):
        notes = [
            Note(order=0, position=FretPosition(string=6, fret=5), duration=Beat(1), elapsed_beats=Beat(1)),
            Note(order=1, position=FretPosition(string=5, fret=5), duration=Beat(1), elapsed_beats=Beat(2)),
        ]

        result = hammer_on_asc(notes, None)

        expected = [
            Note(order=0, position=FretPosition(string=6, fret=5), duration=Beat(1), elapsed_beats=Beat(1)),
            Note(order=1, position=FretPosition(string=5, fret=5), duration=Beat(1), elapsed_beats=Beat(2)),
        ]

        self.assertEqual(expected, result)
예제 #26
0
    def test_rests_are_added_to_incomplete_bars_at_the_end(self):
        rhythm = [
            Beat(duration=1, division=1),
            Beat(duration=1, division=4),
        ]

        positions = [
            FretPosition(string=1, fret=1),
            FretPosition(string=1, fret=2),
        ]
        shape = GuitarShape(name='shape1',
                            positions=positions,
                            category='scale')

        sequence = make_sequence([shape], rhythm=rhythm)

        expected_notes = [
            Note(order=0,
                 position=positions[0],
                 duration=Beat(1, 1),
                 elapsed_beats=Beat(1, 1)),
            Note(order=1,
                 position=positions[1],
                 duration=Beat(1, 4),
                 elapsed_beats=Beat(5, 4)),
            Note(order=2,
                 position=None,
                 duration=Beat(3, 4, rest=True),
                 elapsed_beats=Beat(2, 1)),
        ]
        self.assertEqual(expected_notes, sequence.notes)
        self.assertEqual([shape], sequence.shapes)
예제 #27
0
    def test_pull_off_tie_is_not_added_to_asc_positions(self):
        notes = [
            Note(order=0, position=FretPosition(5, 6), duration=Beat(1), elapsed_beats=Beat(1)),
            Note(order=1, position=FretPosition(7, 6), duration=Beat(1), elapsed_beats=Beat(2)),
        ]

        result = pull_off_desc(notes, None)

        expected = [
            Note(order=0, position=FretPosition(5, 6), duration=Beat(1), elapsed_beats=Beat(1)),
            Note(order=1, position=FretPosition(7, 6), duration=Beat(1), elapsed_beats=Beat(2)),
        ]

        self.assertEqual(expected, result)
예제 #28
0
    def test_tie_split_breaks_down_quarter_notes(self):
        calculations = [
            (Beat(1, 4), [Beat(1, 4)]),
            (Beat(2, 4), [Beat(1, 2)]),
            (Beat(3, 4), [Beat(1, 2), Beat(1, 4)]),
            (Beat(4, 4), [Beat(1, 1)]),
        ]

        for calculation in calculations:
            split = calculation[0].tie_split()
            self.assertEqual(calculation[1], split)
    def test_individual_notes_are_returned_in_order(self):
        position = FretPosition(string=3, fret=1)

        duration = Beat(1)
        notes = [
            Note(order=1,
                 position=position,
                 duration=duration,
                 elapsed_beats=Beat(1)),
            Note(order=2,
                 position=position,
                 duration=duration,
                 elapsed_beats=Beat(2)),
            Note(order=3,
                 position=position,
                 duration=duration,
                 elapsed_beats=Beat(3)),
            Note(order=4,
                 position=position,
                 duration=duration,
                 elapsed_beats=Beat(4)),
        ]

        result = group_notes(notes)

        expected = {
            1: [
                Note(order=1,
                     position=position,
                     duration=duration,
                     elapsed_beats=Beat(1))
            ],
            2: [
                Note(order=2,
                     position=position,
                     duration=duration,
                     elapsed_beats=Beat(2))
            ],
            3: [
                Note(order=3,
                     position=position,
                     duration=duration,
                     elapsed_beats=Beat(3))
            ],
            4: [
                Note(order=4,
                     position=position,
                     duration=duration,
                     elapsed_beats=Beat(4))
            ],
        }

        self.assertEqual(expected, result)
예제 #30
0
    def test_level_one_has_eighth_notes(self):
        random.seed(10)

        result = technique_hammers_pulls(variation='level-1')

        self.assertEqual(8, len(result.notes))
        self.assertTrue(
            all(Beat(1, 8) == note.duration for note in result.notes))