-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathc_melody_gen.py
148 lines (130 loc) · 4.61 KB
/
c_melody_gen.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import random
from fractions import Fraction
import copy
import re
from notation import *
def rhythm_generation(all_rhythm_list, number_of_beat=4, lowertime=4):
available_list = copy.copy(all_rhythm_list[:])
beat_amount = Fraction(1, lowertime)
melody = []
melody_duration_sum = 0
while melody_duration_sum < (number_of_beat * beat_amount):
if not available_list:
raise ValueError("No available rhythm")
rhythm_choice = random.choice(available_list)
melody.append(rhythm_choice)
melody_duration_sum += durations_fraction[rhythm_choice]
remaining_beat = number_of_beat * beat_amount - melody_duration_sum
available_list = []
for rhythm in all_rhythm_list:
if durations_fraction[rhythm] <= remaining_beat:
available_list.append(rhythm)
return melody
def insert_note_rest(rhythm_in_melody,
compound,
pitch_a=4,
max_attempts=10,
current_attempt=0):
lily_melody = []
pitch_c = 0
rest_c = 0
for rhythm in rhythm_in_melody:
if random.randint(0, 3) == 0:
#if (rhythm not in dotted_rest and compound is False) or (compound is True):
note_with_rhythm = f"r{rhythm}"
lily_melody.append(note_with_rhythm)
rest_c += 1
else:
# If the random condition for rest was not met, just add a pitch note
note_pitch = random.choice(pitch)
note_with_rhythm = f"{note_pitch}{rhythm}"
lily_melody.append(note_with_rhythm)
pitch_c += 1
if (pitch_c < pitch_a
or rest_c < pitch_a / 2) and current_attempt < max_attempts:
return insert_note_rest(rhythm_in_melody,
compound,
pitch_a=pitch_a,
max_attempts=max_attempts,
current_attempt=current_attempt + 1)
elif current_attempt >= max_attempts:
lily_melody = []
return False
return lily_melody
def note_with_fraction(melody):
result = []
for note in melody:
rhythm_value = ''.join(filter(str.isdigit, note))
dots = note.count('.')
if rhythm_value: # Check if we have a numeric rhythm value
rhythm_fraction = Fraction(1, int(rhythm_value))
for _ in range(dots):
rhythm_fraction += rhythm_fraction / 2
elif "3(" and ")" in note:
print("triplet found")
else:
raise ValueError(f"No rhythm value found in note '{note}'")
result.append([note, rhythm_fraction])
value = 0
for note in result:
value += note[1]
return result
def check_compound_time(uppertime,lowertime):
simple_list=[2,3,4]
compound_list = [6,9,12]
if uppertime in simple_list:
compound = False
return uppertime, lowertime, compound
elif uppertime in compound_list:
uppertime = uppertime//3
lowertime = durations_fraction[str(lowertime//2)+"."]
lowertime = Fraction(1,lowertime)
compound = True
return uppertime, lowertime, compound
else:
raise ValueError(f"Irregular time signature. {uppertime}/{lowertime}")
def convert_to_list(melody_input):
return [note.strip() for note in melody_input.split()]
def convert_nplet_list(melody_input):
melody = []
for note in melody_input:
melody.append(note)
note_list = []
i = 0
while i < len(melody):
if ("3"and"(" in melody[i]) or ("2"and"("in melody[i]):
triplet ="3("
i += 1
while ")" not in melody[i]:
triplet +=melody[i]
i += 1
triplet += ")"
note_list.append(triplet)
elif melody[i] in pitch and melody[i+1] in rhythm_list:
note_list.append(melody[i]+melody[i+1])
i += 1
return note_list
def get_nplet_duration(note=str):
value_list = []
#for note in melody:
if note.startswith("3("):
for el in note:
if el in rhythm_list:
value_list.append(Fraction(1, int(el)))
return sum(value_list) * Fraction(2, 3)
elif note.startswith("2("):
for el in note:
if el in rhythm_list:
value_list.append(Fraction(1, int(el)))
return sum(value_list) * Fraction(3, 2)
def main_generation(rhythm_list, uppertime,lowertime ):
luppertime,llowertime,compound = check_compound_time(uppertime,lowertime)
melody = rhythm_generation(rhythm_list, luppertime, llowertime)
melody_rest = insert_note_rest(melody, luppertime,compound)
if luppertime <=3:
melody_len = 4
else:
melody_len = 8
while len(melody_rest) < melody_len or len(melody_rest)>melody_len*2:
return main_generation(rhythm_list, uppertime,lowertime)
return note_with_fraction(melody_rest), luppertime, llowertime,compound