asigalov61
commited on
Commit
•
38c5961
1
Parent(s):
c171914
Update app.py
Browse files
app.py
CHANGED
@@ -20,6 +20,21 @@ from midi_to_colab_audio import midi_to_colab_audio
|
|
20 |
|
21 |
# =================================================================================================
|
22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
def Harmonize_Melody(source_melody_transpose_value,
|
24 |
harmonizer_melody_chunk_size,
|
25 |
harmonizer_max_matches_count,
|
@@ -66,7 +81,7 @@ def Harmonize_Melody(source_melody_transpose_value,
|
|
66 |
|
67 |
mel_score = TMIDIX.fix_monophonic_score_durations(TMIDIX.recalculate_score_timings(cscore))
|
68 |
|
69 |
-
mel_score = TMIDIX.transpose_escore_notes(mel_score,
|
70 |
|
71 |
print('=' * 70)
|
72 |
print('Done!')
|
@@ -80,97 +95,73 @@ def Harmonize_Melody(source_melody_transpose_value,
|
|
80 |
#==================================================================
|
81 |
|
82 |
print('=' * 70)
|
83 |
-
print('Melody
|
84 |
print('=' * 70)
|
85 |
|
86 |
print('=' * 70)
|
87 |
-
print('
|
88 |
print('=' * 70)
|
89 |
-
|
90 |
-
matching_long_chords_chunks = []
|
91 |
-
|
92 |
-
ridx = random.randint(0, len(all_long_chords_tokens_chunks)-1)
|
93 |
-
|
94 |
-
matching_long_chords_chunks.append(ridx)
|
95 |
-
|
96 |
-
max_song_len = 0
|
97 |
-
|
98 |
-
tries = 0
|
99 |
-
|
100 |
-
while len(matching_long_chords_chunks) < minimum_song_length_in_chords_chunks:
|
101 |
|
102 |
-
|
103 |
-
|
104 |
-
ridx = random.randint(0, len(all_long_chords_tokens_chunks)-1)
|
105 |
-
|
106 |
-
matching_long_chords_chunks.append(ridx)
|
107 |
-
seen = [ridx]
|
108 |
-
gseen = [ridx]
|
109 |
-
|
110 |
-
for a in range(minimum_song_length_in_chords_chunks * 10):
|
111 |
|
112 |
-
|
113 |
-
break
|
114 |
|
115 |
-
|
116 |
-
|
117 |
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
|
122 |
-
|
123 |
|
124 |
-
|
125 |
|
126 |
-
|
127 |
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
gseen.append(eidx)
|
133 |
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
|
|
138 |
|
139 |
-
|
140 |
-
gseen.pop()
|
141 |
-
matching_long_chords_chunks.pop()
|
142 |
|
143 |
-
|
144 |
-
gseen.pop()
|
145 |
-
matching_long_chords_chunks.pop()
|
146 |
|
|
|
147 |
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
|
|
|
|
|
|
152 |
|
153 |
-
|
154 |
|
155 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
156 |
|
157 |
-
if tries % 500 == 0:
|
158 |
-
print('Number of passed tries:', tries)
|
159 |
-
print('=' * 70)
|
160 |
-
|
161 |
-
if len(matching_long_chords_chunks) > max_song_len:
|
162 |
-
print('Current song length:', len(matching_long_chords_chunks), 'chords chunks')
|
163 |
-
print('=' * 70)
|
164 |
-
final_song = matching_long_chords_chunks
|
165 |
|
166 |
-
|
|
|
|
|
167 |
|
168 |
-
|
169 |
-
f_song.extend(all_long_good_chords_chunks[mat][:-chunk_size])
|
170 |
-
f_song.extend(all_long_good_chords_chunks[mat][-chunk_size:])
|
171 |
|
172 |
-
print('
|
173 |
-
print('=' * 70)
|
174 |
|
175 |
print('Done!')
|
176 |
print('=' * 70)
|
@@ -185,51 +176,30 @@ def Harmonize_Melody(source_melody_transpose_value,
|
|
185 |
time = 0
|
186 |
|
187 |
patches = [0] * 16
|
188 |
-
patches[0] =
|
189 |
|
190 |
if base_MIDI_patch_number > -1:
|
191 |
patches[2] = base_MIDI_patch_number
|
192 |
|
193 |
-
|
194 |
-
patches[3] = melody_MIDI_patch_number
|
195 |
-
|
196 |
-
chords_labels = []
|
197 |
-
|
198 |
-
for i, s in enumerate(f_song):
|
199 |
-
|
200 |
-
time += chord_time_step
|
201 |
-
|
202 |
-
dur = chord_time_step
|
203 |
|
204 |
-
|
205 |
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
|
211 |
for p in s:
|
212 |
-
output_score.append(['note', time, dur, 0, p, max(40, p),
|
213 |
|
214 |
if base_MIDI_patch_number > -1:
|
215 |
output_score.append(['note', time, dur, 2, (s[-1] % 12)+24, 120-(s[-1] % 12), base_MIDI_patch_number])
|
216 |
-
|
217 |
-
if melody_MIDI_patch_number > -1:
|
218 |
-
output_score = TMIDIX.add_melody_to_enhanced_score_notes(output_score,
|
219 |
-
melody_patch=melody_MIDI_patch_number,
|
220 |
-
melody_notes_max_duration=max(merge_chords_notes, chord_time_step)
|
221 |
-
)
|
222 |
-
|
223 |
-
if merge_chords_notes > 0:
|
224 |
-
escore_matrix = TMIDIX.escore_notes_to_escore_matrix(output_score)
|
225 |
-
output_score = TMIDIX.escore_matrix_to_merged_escore_notes(escore_matrix, max_note_duration=merge_chords_notes)
|
226 |
-
|
227 |
-
midi_score = sorted(chords_labels + output_score, key=lambda x: x[1])
|
228 |
|
229 |
fn1 = "Pitches-Chords-Progression-Composition"
|
230 |
|
231 |
-
detailed_stats = TMIDIX.Tegridy_ms_SONG_to_MIDI_Converter(
|
232 |
-
output_signature = '
|
233 |
output_file_name = fn1,
|
234 |
track_name='Project Los Angeles',
|
235 |
list_of_MIDI_patches=patches
|
@@ -254,73 +224,20 @@ def Harmonize_Melody(source_melody_transpose_value,
|
|
254 |
output_plot = TMIDIX.plot_ms_SONG(output_score, plot_title=output_midi, return_plt=True)
|
255 |
|
256 |
print('Done!')
|
257 |
-
print('=' * 70)
|
258 |
|
259 |
#========================================================
|
260 |
|
261 |
-
|
262 |
-
|
263 |
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
all_song_chords = []
|
268 |
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
|
273 |
-
print('=' * 70)
|
274 |
-
print('Total number of chords:', len(all_song_chords))
|
275 |
-
chords_progression_summary_string += 'Total number of chords: ' + str(len(all_song_chords)) + '\n'
|
276 |
-
chords_progression_summary_string += '=' * 70
|
277 |
-
chords_progression_summary_string += '\n'
|
278 |
-
print('=' * 70)
|
279 |
-
print('Most common pitches chord:', list(Counter(tuple([a[0] for a in all_song_chords])).most_common(1)[0][0]), '===', Counter(tuple([a[0] for a in all_song_chords])).most_common(1)[0][1], 'count')
|
280 |
-
chords_progression_summary_string += 'Most common pitches chord: ' + str(list(Counter(tuple([a[0] for a in all_song_chords])).most_common(1)[0][0])) + ' === ' + str(Counter(tuple([a[0] for a in all_song_chords])).most_common(1)[0][1]) + ' count' + '\n'
|
281 |
-
chords_progression_summary_string += '=' * 70
|
282 |
-
chords_progression_summary_string += '\n'
|
283 |
-
print('=' * 70)
|
284 |
-
print('Most common tones chord:', list(Counter(tuple([a[1] for a in all_song_chords])).most_common(1)[0][0]), '===', Counter(tuple([a[1] for a in all_song_chords])).most_common(1)[0][1], 'count')
|
285 |
-
chords_progression_summary_string += 'Most common tones chord: ' + str(list(Counter(tuple([a[1] for a in all_song_chords])).most_common(1)[0][0])) + ' === ' + str(Counter(tuple([a[1] for a in all_song_chords])).most_common(1)[0][1]) + ' count' + '\n'
|
286 |
-
chords_progression_summary_string += '=' * 70
|
287 |
-
chords_progression_summary_string += '\n'
|
288 |
-
print('=' * 70)
|
289 |
-
print('Sorted unique songs chords set:', len(sorted(set(tuple([a[1] for a in all_song_chords])))), 'count')
|
290 |
-
chords_progression_summary_string += 'Sorted unique songs chords set: ' + str(len(sorted(set(tuple([a[1] for a in all_song_chords]))))) + ' count' + '\n'
|
291 |
-
chords_progression_summary_string += '=' * 70
|
292 |
-
chords_progression_summary_string += '\n'
|
293 |
-
#print('=' * 70)
|
294 |
-
for c in sorted(set(tuple([a[1] for a in all_song_chords]))):
|
295 |
-
#print(list(c))
|
296 |
-
chords_progression_summary_string += str(list(c)) + '\n'
|
297 |
-
chords_progression_summary_string += '=' * 70
|
298 |
-
chords_progression_summary_string += '\n'
|
299 |
-
print('=' * 70)
|
300 |
-
print('Grouped songs chords set:', len(TMIDIX.grouped_set(tuple([a[1] for a in all_song_chords]))), 'count')
|
301 |
-
chords_progression_summary_string += 'Grouped songs chords set: ' + str(len(TMIDIX.grouped_set(tuple([a[1] for a in all_song_chords])))) + ' count' + '\n'
|
302 |
-
chords_progression_summary_string += '=' * 70
|
303 |
-
chords_progression_summary_string += '\n'
|
304 |
-
print('=' * 70)
|
305 |
-
for c in TMIDIX.grouped_set(tuple([a[1] for a in all_song_chords])):
|
306 |
-
#print(list(c))
|
307 |
-
chords_progression_summary_string += str(list(c)) + '\n'
|
308 |
-
chords_progression_summary_string += '=' * 70
|
309 |
-
chords_progression_summary_string += '\n'
|
310 |
-
#print('=' * 70)
|
311 |
-
#print('All songs chords')
|
312 |
-
chords_progression_summary_string += 'All songs chords' + '\n'
|
313 |
-
chords_progression_summary_string += '=' * 70
|
314 |
-
chords_progression_summary_string += '\n'
|
315 |
-
#print('=' * 70)
|
316 |
-
for i, pc_tc in enumerate(all_song_chords):
|
317 |
-
#print('Song chord #', i)
|
318 |
-
chords_progression_summary_string += 'Song chord # ' + str(i) + '\n'
|
319 |
-
#print(list(pc_tc[0]), '===', list(pc_tc[1]))
|
320 |
-
chords_progression_summary_string += str(list(pc_tc[0])) + ' === ' + str(list(pc_tc[1])) + '\n'
|
321 |
-
#print('=' * 70)
|
322 |
-
chords_progression_summary_string += '=' * 70
|
323 |
-
chords_progression_summary_string += '\n'
|
324 |
#========================================================
|
325 |
|
326 |
print('-' * 70)
|
@@ -328,7 +245,7 @@ def Harmonize_Melody(source_melody_transpose_value,
|
|
328 |
print('-' * 70)
|
329 |
print('Req execution time:', (reqtime.time() - start_time), 'sec')
|
330 |
|
331 |
-
return output_audio, output_plot, output_midi,
|
332 |
|
333 |
# =================================================================================================
|
334 |
|
|
|
20 |
|
21 |
# =================================================================================================
|
22 |
|
23 |
+
def find_best_match(matches):
|
24 |
+
|
25 |
+
mlens = []
|
26 |
+
|
27 |
+
for sidx in matches:
|
28 |
+
mlen = len(TMIDIX.flatten(long_chords_chunks_mult[sidx[0]][sidx[1]:sidx[1]+(csize // 2)]))
|
29 |
+
mlens.append(mlen)
|
30 |
+
|
31 |
+
max_len = max(mlens)
|
32 |
+
max_len_idx = mlens.index(max_len)
|
33 |
+
|
34 |
+
return matches[max_len_idx]
|
35 |
+
|
36 |
+
# =================================================================================================
|
37 |
+
|
38 |
def Harmonize_Melody(source_melody_transpose_value,
|
39 |
harmonizer_melody_chunk_size,
|
40 |
harmonizer_max_matches_count,
|
|
|
81 |
|
82 |
mel_score = TMIDIX.fix_monophonic_score_durations(TMIDIX.recalculate_score_timings(cscore))
|
83 |
|
84 |
+
mel_score = TMIDIX.transpose_escore_notes(mel_score, source_melody_transpose_value)
|
85 |
|
86 |
print('=' * 70)
|
87 |
print('Done!')
|
|
|
95 |
#==================================================================
|
96 |
|
97 |
print('=' * 70)
|
98 |
+
print('Melody Harmonizer')
|
99 |
print('=' * 70)
|
100 |
|
101 |
print('=' * 70)
|
102 |
+
print('Harmonizing...')
|
103 |
print('=' * 70)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
104 |
|
105 |
+
#===============================================================================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
|
107 |
+
song = []
|
|
|
108 |
|
109 |
+
csize = harmonizer_melody_chunk_size
|
110 |
+
matches_mem_size = harmonizer_max_matches_count
|
111 |
|
112 |
+
i = 0
|
113 |
+
dev = 0
|
114 |
+
dchunk = []
|
115 |
|
116 |
+
#===============================================================================
|
117 |
|
118 |
+
while i < len(mel_pitches):
|
119 |
|
120 |
+
matches = []
|
121 |
|
122 |
+
for midx, mel in enumerate(long_mels_chunks_mult):
|
123 |
+
if len(mel) >= csize:
|
124 |
+
schunk = mel_pitches[i:i+csize]
|
125 |
+
idx = HaystackSearch.HaystackSearch(schunk, mel)
|
|
|
126 |
|
127 |
+
if idx != -1:
|
128 |
+
matches.append([midx, idx])
|
129 |
+
if matches_mem_size > -1:
|
130 |
+
if len(matches) > matches_mem_size:
|
131 |
+
break
|
132 |
|
133 |
+
if matches:
|
|
|
|
|
134 |
|
135 |
+
sidx = find_best_match(matches)
|
|
|
|
|
136 |
|
137 |
+
fchunk = long_chords_chunks_mult[sidx[0]][sidx[1]:sidx[1]+csize]
|
138 |
|
139 |
+
song.extend(fchunk[:(csize // 2)])
|
140 |
+
i += (csize // 2)
|
141 |
+
dchunk = fchunk
|
142 |
+
dev = 0
|
143 |
+
print('step', i)
|
144 |
+
|
145 |
+
else:
|
146 |
|
147 |
+
if dchunk:
|
148 |
|
149 |
+
song.append(dchunk[(csize // 2)+dev])
|
150 |
+
dev += 1
|
151 |
+
i += 1
|
152 |
+
print('dead chord', i, dev)
|
153 |
+
else:
|
154 |
+
print('DEAD END!!!')
|
155 |
+
break
|
156 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
157 |
|
158 |
+
if dev == csize // 2:
|
159 |
+
print('DEAD END!!!')
|
160 |
+
break
|
161 |
|
162 |
+
song = song[:len(mel_pitches)]
|
|
|
|
|
163 |
|
164 |
+
print('Harmonized', len(song), 'out of', len(mel_pitches), 'notes')
|
|
|
165 |
|
166 |
print('Done!')
|
167 |
print('=' * 70)
|
|
|
176 |
time = 0
|
177 |
|
178 |
patches = [0] * 16
|
179 |
+
patches[0] = harmonized_accompaniment_MIDI_patch_number
|
180 |
|
181 |
if base_MIDI_patch_number > -1:
|
182 |
patches[2] = base_MIDI_patch_number
|
183 |
|
184 |
+
patches[3] = melody_MIDI_patch_number
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
185 |
|
186 |
+
for i, s in enumerate(song):
|
187 |
|
188 |
+
time = mel_score[i][1] * 16
|
189 |
+
dur = mel_score[i][2] * 16
|
190 |
+
|
191 |
+
output_score.append(['note', time, dur, 3, mel_score[i][4], 115+(mel_score[i][4] % 12), 40])
|
192 |
|
193 |
for p in s:
|
194 |
+
output_score.append(['note', time, dur, 0, p, max(40, p), harmonized_accompaniment_MIDI_patch_number])
|
195 |
|
196 |
if base_MIDI_patch_number > -1:
|
197 |
output_score.append(['note', time, dur, 2, (s[-1] % 12)+24, 120-(s[-1] % 12), base_MIDI_patch_number])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
198 |
|
199 |
fn1 = "Pitches-Chords-Progression-Composition"
|
200 |
|
201 |
+
detailed_stats = TMIDIX.Tegridy_ms_SONG_to_MIDI_Converter(output_score,
|
202 |
+
output_signature = 'Monophonic MIDI Melody Harmonizer',
|
203 |
output_file_name = fn1,
|
204 |
track_name='Project Los Angeles',
|
205 |
list_of_MIDI_patches=patches
|
|
|
224 |
output_plot = TMIDIX.plot_ms_SONG(output_score, plot_title=output_midi, return_plt=True)
|
225 |
|
226 |
print('Done!')
|
|
|
227 |
|
228 |
#========================================================
|
229 |
|
230 |
+
harmonization_summary_string = '=' * 70
|
231 |
+
harmonization_summary_string += '\n'
|
232 |
|
233 |
+
harmonization_summary_string += 'Source melody has ' + str(len(mel_pitches)) + ' monophonic pitches'
|
234 |
+
harmonization_summary_string += '=' * 70
|
235 |
+
harmonization_summary_string += '\n'
|
|
|
236 |
|
237 |
+
harmonization_summary_string += 'Harmonized ' + str(len(song)) + ' out of ' + str(len(mel_pitches)) + ' source melody pitches')
|
238 |
+
harmonization_summary_string += '=' * 70
|
239 |
+
harmonization_summary_string += '\n'
|
240 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
241 |
#========================================================
|
242 |
|
243 |
print('-' * 70)
|
|
|
245 |
print('-' * 70)
|
246 |
print('Req execution time:', (reqtime.time() - start_time), 'sec')
|
247 |
|
248 |
+
return output_audio, output_plot, output_midi, harmonization_summary_string
|
249 |
|
250 |
# =================================================================================================
|
251 |
|