def set_melodic_figures(nested_scale_degrees): chosen_figurations = [] melodic_figures = { (2, (1, )): "IPT", (0, (2, 1)): "DCN", (2, (-1, 1)): "OPT", (0, (-1, )): "CN", (1, (-1, )): "PIN", (1, (2, )): "CIN", (1, (-2, -1)): "OPT", (4, (2, )): "IPT", (3, (4, )): "CIN", (3, (1, )): "IPT", (1, (0, )): "RET", (2, (2, )): "ANT", (3, (2, )): "IPT", (3, (1, 3)): "ANT", (2, (2, 3)): "OPT", (4, (1, 2)): "IPT", (1, (-2, )): "OPT", (1, (-1, 0)): "OPT", (3, (1, 2)): "IPT", (5, (3, )): "5PT", (0, (1, )): "CN", (1, (1, )): "ANT" } chord_index = 0 for previous_melody_group, current_melody_group in zip( nested_scale_degrees, nested_scale_degrees[1:]): chord_index += 1 figure_group = [] main_pitch_diff = current_melody_group[0] - previous_melody_group[0] main_pitch_direction = Voice.calculate_slope(main_pitch_diff) main_pitch_diff = abs(main_pitch_diff) embellish_degrees = previous_melody_group[1:] if not embellish_degrees: chosen_figurations.append(None) continue for previous_melody_note in embellish_degrees: pitch_diff = previous_melody_note - previous_melody_group[0] pitch_direction = Voice.calculate_slope(pitch_diff) if pitch_direction == 0: reference_direction = 0 if 0 != main_pitch_direction == pitch_direction: reference_direction = 1 * abs(pitch_diff) elif 0 != main_pitch_direction != pitch_direction: reference_direction = -1 * abs(pitch_diff) elif main_pitch_direction == 0: reference_direction = pitch_diff figure_group.append(reference_direction) figure_group = tuple(figure_group) if chord_index == 8: modifier = "PICK_" else: modifier = "" chosen_figurations.append(modifier + melodic_figures[(main_pitch_diff, figure_group)]) print(chosen_figurations) return chosen_figurations
def has_melody_figure(self): """Check specific melody against figuration options""" last_rhythm_symbol = self.rhythm_symbols[self.chord_index - 1] if last_rhythm_symbol == -1: if self.chord_index == 15: section3 = Voice.merge_lists(*self.nested_scale_degrees[8:12]) section4 = Voice.merge_lists(*self.nested_scale_degrees[12:14]) if max(section3) <= max(section4): return False self.nested_scale_degrees[self.chord_index - 1] = [self.previous_degree_choice] return True if last_rhythm_symbol == -2: self.melody_figure_options[self.chord_index - 1] = (self.get_pickup_sequences( self.current_degree_choice)) return self.add_valid_figure() remaining_figures = self.melody_figure_options[self.chord_index - 1] if remaining_figures: return self.add_valid_figure() degree_mvmt = self.current_degree_choice - self.previous_degree_choice melody_slope = Voice.calculate_slope(degree_mvmt) degree_mvmt = abs(degree_mvmt) embellish_amount = len(self.finalized_rhythms[self.chord_index - 1]) if embellish_amount == 2: all_figurations = self.all_single_figurations elif embellish_amount == 3: all_figurations = self.all_double_figurations possible_scale_degrees = all_figurations[degree_mvmt]( self.previous_degree_choice, self.current_degree_choice, melody_slope) self.melody_figure_options[self.chord_index - 1] = possible_scale_degrees return self.add_valid_figure()
def set_melodic_figures(nested_scale_degrees): """Defines figurations found in actual music""" chosen_figurations = [] """ IPT = inner passing tone OPT = outer passing tone ANT = anticipation RET = retardation CIN = current incomplete neighbor PIN = previous incomplete neighbor DN = double neighbor CN = complete neighbor DCN = double complete neighbor Format of keys: (degree difference between base notes, (figurations)) """ melodic_figures = { (2, (1, )): "IPT", (0, (2, 1)): "DCN", (2, (-1, 1)): "OPT", (0, (-1, )): "CN", (1, (-1, )): "PIN", (1, (2, )): "CIN", (1, (-2, -1)): "OPT", (4, (2, )): "IPT", (3, (4, )): "CIN", (3, (1, )): "IPT", (1, (0, )): "RET", (2, (2, )): "ANT", (3, (2, )): "IPT", (3, (1, 3)): "ANT", (2, (2, 3)): "OPT", (4, (1, 2)): "IPT", (1, (-2, )): "OPT", (1, (-1, 0)): "OPT", (3, (1, 2)): "IPT", (5, (3, )): "5PT", (0, (1, )): "CN", (1, (1, )): "ANT" } chord_index = 0 for previous_melody_group, current_melody_group in zip( nested_scale_degrees, nested_scale_degrees[1:]): chord_index += 1 figure_group = [] main_pitch_diff = current_melody_group[0] - previous_melody_group[0] main_pitch_direction = Voice.calculate_slope(main_pitch_diff) main_pitch_diff = abs(main_pitch_diff) embellish_degrees = previous_melody_group[1:] if not embellish_degrees: chosen_figurations.append(None) continue for previous_melody_note in embellish_degrees: pitch_diff = previous_melody_note - previous_melody_group[0] pitch_direction = Voice.calculate_slope(pitch_diff) if pitch_direction == 0: reference_direction = 0 if 0 != main_pitch_direction == pitch_direction: reference_direction = 1 * abs(pitch_diff) elif 0 != main_pitch_direction != pitch_direction: reference_direction = -1 * abs(pitch_diff) elif main_pitch_direction == 0: reference_direction = pitch_diff figure_group.append(reference_direction) figure_group = tuple(figure_group) if chord_index == 8: modifier = "PICK_" else: modifier = "" chosen_figurations.append(modifier + melodic_figures[(main_pitch_diff, figure_group)]) print(chosen_figurations) return chosen_figurations
def test_slopes(self): self.assertEqual(Voice.calculate_slope(0), 0) self.assertEqual(Voice.calculate_slope(1), 1) self.assertEqual(Voice.calculate_slope(-1), -1) self.assertEqual(Voice.calculate_slope(5), 1) self.assertEqual(Voice.calculate_slope(-3), -1)