def test_get_duration_with_double_dot(self): rest = Rest() rest.add_modifier(RestModifier.DOUBLE_DOT) lengths = [64, 32, 16] for length in lengths: self.assertEqual(length / 4 + length / 8 + length / 16, rest.get_duration(length))
def test_split_to_bars_with_dot(self): self.generator.set_bar_count(2) self.generator.set_shortest_note_duration(16) with_dot = Note('e', base_duration=4) with_dot.add_modifier(NoteModifier.DOT) data: List[Writeable] = [ Note('c', base_duration=2), Note('d'), with_dot, Note('f', base_duration=8), Note('c', base_duration=2), Rest() ] with_tie = Note('e', base_duration=4) with_tie.add_modifier(NoteModifier.TIE) expected: List[List[Writeable]] = [[ Note('c', base_duration=2), Note('d'), with_tie ], [ Note('e', base_duration=8), Note('f', base_duration=8), Note('c', base_duration=2), Rest() ]] bars: List[List[Writeable]] = self.generator.split_to_bars(data) self.assertEqual(expected, bars)
def test_split_note_rests(self): Generator.set_shortest_note_duration(16) note = Rest(base_duration=2) actual = self.generator.split_note(note, 3) expected = [[Rest(base_duration=8, modifiers=[RestModifier.DOT])], [Rest(base_duration=4), Rest(base_duration=16)]] self.assertEqual(expected, actual)
def test_parse(self): bars: List[List[Writeable]] = [ [Note('c'), Note('d'), Note('e'), Note('f')], [Note('c', base_duration=2), Note('d', base_duration=4, modifiers=[NoteModifier.DOT]), Note('e', base_duration=8)], [Rest(), Rest(2), Rest(8, [RestModifier.DOT]), Rest(16)], [Rest(), Note('c'), Rest(), Note('c')], [Note('c', base_duration=2), Note('d', base_duration=2, modifiers=[NoteModifier.TIE])], [Note('d', base_duration=2), Rest(), Note('c', base_duration=8), Rest(8)] ] self.writer.header() self.writer.block_start() self.writer.parse(bars) self.writer.block_end() self.writer.export() output_file = open(f'{self.writer.source_dir}/{self.writer.filename}.ly') expected_file = open('expected/test_parse.ly') self.assertEqual(expected_file.readlines(), output_file.readlines()) output_file.close() expected_file.close() # Cleanup os.remove('{}/{}.ly'.format(self.writer.source_dir, self.writer.filename)) os.removedirs(self.writer.source_dir)
def test_split_to_bars(self): self.generator.set_bar_count(2) self.generator.set_shortest_note_duration(16) notes: List[Writeable] = [Note('c')] * 7 notes.append(Rest()) expected: List[List[Writeable]] = [[Note('c')] * 4, [ Note('c'), Note('c'), Note('c'), Rest() ]] bars: List[List[Writeable]] = self.generator.split_to_bars(notes) self.assertEqual(expected, bars)
def test_split_to_bars_break_rest(self): self.generator.set_bar_count(2) self.generator.set_shortest_note_duration(16) data: List[Writeable] = [ Note('c'), Note('c', base_duration=2), Rest(base_duration=2), Note('c', base_duration=2), Rest() ] expected: List[List[Writeable]] = [[ Note('c'), Note('c', base_duration=2), Rest() ], [Rest(), Note('c', base_duration=2), Rest()]] bars: List[List[Writeable]] = self.generator.split_to_bars(data) self.assertEqual(expected, bars)
def test_add_remove_modifier(self): rest = Rest() rest.add_modifier(RestModifier.DOT) self.assertTrue(RestModifier.DOT in rest.modifiers) rest.remove_modifier(RestModifier.DOT) self.assertTrue(RestModifier.DOT not in rest.modifiers)
def test_add_modifier_double_dot_removes_dot(self): rest = Rest() rest.add_modifier(RestModifier.DOT) rest.add_modifier(RestModifier.DOUBLE_DOT) self.assertTrue(RestModifier.DOUBLE_DOT in rest.modifiers) self.assertTrue(RestModifier.DOT not in rest.modifiers)
def test_split_to_bars_break(self): self.generator.set_bar_count(2) self.generator.set_shortest_note_duration(16) notes: List[Writeable] = [ Note('c'), Note('c', base_duration=2), Note('c', base_duration=2), Note('c', base_duration=2), Rest() ] with_tie = Note('c') with_tie.add_modifier(NoteModifier.TIE) expected: List[List[Writeable]] = [[ Note('c'), Note('c', base_duration=2), with_tie ], [Note('c'), Note('c', base_duration=2), Rest()]] bars: List[List[Writeable]] = self.generator.split_to_bars(notes) self.assertEqual(expected, bars)
def test_split_to_bars_long_note(self): self.generator.set_bar_count(3) data: List[Writeable] = [ Rest(base_duration=2, modifiers=[RestModifier.DOT]), Note('c', base_duration=1, modifiers=[NoteModifier.DOT]), Rest(base_duration=2, modifiers=[RestModifier.DOT]) ] expected: List[List[Writeable]] = [[ Rest(base_duration=2, modifiers=[RestModifier.DOT]), Note('c', base_duration=4, modifiers=[NoteModifier.TIE]) ], [Note('c', base_duration=1, modifiers=[NoteModifier.TIE])], [ Note('c', base_duration=4), Rest(base_duration=2, modifiers=[ RestModifier.DOT ]) ]] bars = self.generator.split_to_bars(data) self.assertEqual(expected, bars)
def get_random_rest(self, longest_duration: Optional[int] = None) -> Rest: """ Wygeneruj pauzę z losowymi parametrami o maksymalnej długości podanej w parametrze Args: longest_duration: Najdłuższa możliwa wartość rytmiczna, która może wystąpić podana w ilości shortest_note_duration. Jeśli nie podano, skrypt zakłada że nuta o każdej długości jest dozwolona. Returns: Pauza z losowymi parametrami o maksymalnej długości wynoszącej longest_duration """ # Jeśli nie był podany parametr najdłuższej możliwej wartości rytmicznej, to zakładamy że nuta o każdej długości # jest dozwolona do wygenerowania if longest_duration is None: longest_duration = self.shortest_note_duration # Pobieramy listę dostępnych wartości rytmicznych i tworzymy listę dostępnych modyfikatorów available_mods = [] base_duration = self.get_random_duration( longest_duration=longest_duration) has_mod = np.random.choice([True, False]) rest = Rest(base_duration=base_duration) # Jeśli długość nuty jest najkrótsza jaką możemy uzyskać, to nie możemy dodać modyfikatora wydłużającego, # gdyż kropka lub podwójna kropka doda mniejszą wartość rytmiczną if base_duration >= self.shortest_note_duration: has_mod = False # Jeśli dostępne miejsce jest większej lub równej długości niż potencjalna pauza z kropką, to do dostępnych # modyfikatorów możemy dodać przedłużenie w postaci kropki if longest_duration >= rest.get_duration( self.shortest_note_duration) * 1.5: available_mods.append(RestModifier.DOT) # Jeśli dostępne miejsce jest większej lub równej długości niż potencjalna pauza z podwójną kropką, to do # dostępnych modyfikatorów możemy dodać przedłużenie w postaci podwójnej kropki. # Sprawdzamy również, czy nie jest to przedostatnia dostępna wartość rytmiczna. Jeśli tak jest, to nie możemy # dodać podwójnej kropki, gdyż skutkowałoby to dodaniem pauzy o połowę mniejszej wartości rytmicznej niż # dozwolona if longest_duration >= rest.get_duration(self.shortest_note_duration) * 1.75 \ and rest.base_duration > 2 * self.shortest_note_duration: available_mods.append(RestModifier.DOUBLE_DOT) if has_mod and len(available_mods) > 0: rest.add_modifier(np.random.choice(available_mods)) return rest
def test_eq(self): rest = Rest(base_duration=8) rest2 = Rest(base_duration=8) self.assertEqual(rest, rest2)
def test_group_bars_4_4(self): self.generator.set_metre(4, 4) self.generator.set_shortest_note_duration(16) bars: List[List[Writeable]] = [ [Note('c', base_duration=1)], [Note('c'), Note('c', base_duration=2), Note('c')], [Note('c', base_duration=2), Note('c', base_duration=2)], [ Note('c', base_duration=2, modifiers=[NoteModifier.DOT]), Note('c') ], [ Note('c', base_duration=2, modifiers=[NoteModifier.DOUBLE_DOT]), Note('c', base_duration=8) ], [ Note('c'), Note('c', base_duration=8), Note('c', modifiers=[NoteModifier.DOT]), Note('c') ], [ Rest(base_duration=8), Note('c', base_duration=8, modifiers=[NoteModifier.DOT]), Note('c', base_duration=16), Note('c', base_duration=16), Note('c', base_duration=8, modifiers=[NoteModifier.DOT]), Rest(base_duration=4, modifiers=[RestModifier.DOT]) ] ] expected: List[List[Writeable]] = [ [ Note('c', base_duration=2, modifiers=[NoteModifier.TIE]), Note('c', base_duration=2) ], [ Note('c'), Note('c', modifiers=[NoteModifier.TIE]), Note('c'), Note('c') ], [Note('c', base_duration=2), Note('c', base_duration=2)], [ Note('c', base_duration=2, modifiers=[NoteModifier.TIE]), Note('c'), Note('c') ], [ Note('c', base_duration=2, modifiers=[NoteModifier.TIE]), Note('c', modifiers=[NoteModifier.DOT]), Note('c', base_duration=8) ], [ Note('c'), Note('c', base_duration=8), Note('c', base_duration=8, modifiers=[NoteModifier.TIE]), Note('c'), Note('c') ], [ Rest(base_duration=8), Note('c', base_duration=8, modifiers=[NoteModifier.DOT]), Note('c', base_duration=16), Note('c', base_duration=16), Note('c', base_duration=16, modifiers=[NoteModifier.TIE]), Note('c', base_duration=8), Rest(base_duration=4, modifiers=[RestModifier.DOT]) ] ] grouped_bars = self.generator.group_bars(bars) self.assertEqual(expected, grouped_bars)
def test_str_with_modifiers(self): rest = Rest() rest.add_modifier(RestModifier.DOUBLE_DOT) self.assertEqual('r4..', str(rest))
def test_str(self): rest = Rest(base_duration=8) self.assertEqual('r8', str(rest))
def test_repr(self): rest = Rest() self.assertEqual('Rest <r4>', repr(rest))
def test_get_duration(self): rest = Rest() lengths = [64, 32, 16, 8, 4] for length in lengths: self.assertEqual(length / 4, rest.get_duration(length))
def test_add_modifier_unique(self): rest = Rest() rest.add_modifier(RestModifier.DOT) rest.add_modifier(RestModifier.DOT) self.assertEqual(1, len(rest.modifiers))
def test_last_note_idx_raises(self): self.generator.generated_data = [Rest(), Rest(), Rest(), Rest()] with self.assertRaises(errors.NoNotesError): self.generator.get_last_note_idx()
def test_init_invalid_duration(self): with self.assertRaises(ValueError): Rest(base_duration=5)
def test_last_note_idx(self): self.generator.generated_data = [Rest(), Rest(), Note('c'), Rest()] idx = self.generator.get_last_note_idx() self.assertEqual(2, idx)
def test_init(self): rest = Rest(base_duration=8) self.assertEqual(8, rest.base_duration) self.assertEqual([], rest.modifiers)