def test_clip_add_and_compile_note_list(self): clip = Clip("", FunctionRegistry([])) self.assertTrue(clip.is_dirty) p8 = Note(-1, 1 / 8) n604 = Note(60, 1 / 4) n608 = Note(60, 1 / 8) n614 = Note(61, 1 / 4) n618 = Note(61, 1 / 8) # [1:1 C:1/4,p1/8,1/8 C#:p1/8 1/8 1/4] clip.add_sequence(n604, [n604, p8, n608]) clip.add_sequence(n614, [p8, n618, n614]) fpb = 400 signature = 1 / 4 factor = fpb * 1 / signature eighth = int(1 / 8 * factor) fourth = int(1 / 4 * factor) dotted_fourth = int(3 / 8 * factor) expected = ((0, [n604, p8]), (eighth, [n618]), (fourth, [p8, n614]), (dotted_fourth, [n608])) frames = clip.compile(fpb, signature) self.assertEqual(factor * 1 / 2, len(frames)) for e in expected: self.assertEqual(e[1], frames[e[0]])
def do_run(self, called_name: str, groups: dict): matches = interval_regex.match(called_name) index = matches.group(1) mod = matches.group(2) if not mod: mod = default_mods[index] pitches = self.get_notes(index, mod) notes = {} index = 0 for pitch in pitches: if pitch.number not in notes: notes[pitch.number] = [] group_rhythm = groups.get(str(index), groups.get("_", [])) index += 1 for rhythm in group_rhythm: note_number = pitch.number if rhythm["is_pause"]: note_number = -1 note = Note(note_number, rhythm["length"]) notes[pitch.number].append(note) return notes
def do_run(self, groups: dict, **kwargs): sequence = {} for group_name in groups: if group_name not in self.map: raise ValueError( "DrumFunction does not support `{0}`".format(group_name)) note_number = self.map[group_name] sequence[note_number] = [] for s in groups[group_name]: if s["is_pause"]: note = Note(-1) else: note = Note(note_number) note.length = float(s["length"]) sequence[note_number].append(note) return sequence
def get_notes(self, index, mod) -> list: key = self.key_note root = key.number + self._scale[interval_map[index]] mod = chord_mods[mod] notes = [] if not mod: mod = [] for m in mod: note = Note(root + m) notes.append(note) return notes
def test_clip_fill(self): clip = Clip("", FunctionRegistry([])) n604 = Note(60, 1 / 4)
def __init__(self, scale: list = [0, 2, 4, 5, 7, 9, 11]): super().__init__(interval_regex) self._scale = scale self._key_note = Note(60)
def test_get_frame(self): track = Track("test", 0) p8 = Note(-1, 1 / 8) n604 = Note(60, 1 / 4) n608 = Note(60, 1 / 8) n614 = Note(61, 1 / 4) n618 = Note(61, 1 / 8) clip = Clip("", func.FunctionRegistry([])) # [1:1 C:1/4,p1/8,1/8 C#:p1/8 1/8 1/4] clip.add_sequence(n604, [n604, p8, n608]) clip.add_sequence(n614, [p8, n618, n614]) track.add_clip(clip) player = MidiPlayer() player.add_track(track) fpb = 400 signature = 1 / 4 factor = fpb * 1 / signature eighth = int(1 / 8 * factor) fourth = int(1 / 4 * factor) dotted_fourth = int(3 / 8 * factor) m604 = mido.Message('note_on', note=n604.number, velocity=n604.velocity, time=player.length_to_ticks(n604.length), channel=0) mo604 = mido.Message('note_off', note=n604.number, channel=0) m608 = mido.Message('note_on', note=n608.number, velocity=n608.velocity, time=player.length_to_ticks(n608.length), channel=0) mo608 = mido.Message('note_off', note=n608.number, channel=0) m618 = mido.Message('note_on', note=n618.number, velocity=n618.velocity, time=player.length_to_ticks(n618.length), channel=0) mo618 = mido.Message('note_off', note=n618.number, channel=0) m614 = mido.Message('note_on', note=n614.number, velocity=n614.velocity, time=player.length_to_ticks(n614.length), channel=0) mo614 = mido.Message('note_off', note=n614.number, channel=0) expected_length = int(factor * 1 / 2) expected = { 0: [m604], eighth: [m618], fourth - 1: [mo604, mo618], fourth: [m614], fourth + eighth: [m608], (fourth + fourth) - 1: [mo614, mo608] } player.play() for i in range(0, expected_length): messages = player.get_frame() if i in expected: self.assertEqual(expected[i], messages, "Frame mismatch at {0}".format(i))