asigalov61 commited on
Commit
38c5961
1 Parent(s): c171914

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +79 -162
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, 0)
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 Harmonization Generator')
84
  print('=' * 70)
85
 
86
  print('=' * 70)
87
- print('Generating...')
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
- matching_long_chords_chunks = []
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
- if not matching_long_chords_chunks:
113
- break
114
 
115
- if len(matching_long_chords_chunks) > minimum_song_length_in_chords_chunks:
116
- break
117
 
118
- schunk = all_long_chords_tokens_chunks[matching_long_chords_chunks[-1]]
119
- trg_long_chunk = np.array(schunk[-chunk_size:])
120
- idxs = np.where((src_long_chunks == trg_long_chunk).all(axis=1))[0].tolist()
121
 
122
- if len(idxs) > 1:
123
 
124
- random.shuffle(idxs)
125
 
126
- eidxs = [i for i in idxs if i not in seen]
127
 
128
- if eidxs:
129
- eidx = eidxs[0]
130
- matching_long_chords_chunks.append(eidx)
131
- seen.append(eidx)
132
- gseen.append(eidx)
133
 
134
- if 0 < chords_chunks_memory_ratio < 1:
135
- seen = random.choices(gseen, k=math.ceil(len(gseen) * chords_chunks_memory_ratio))
136
- elif chords_chunks_memory_ratio == 0:
137
- seen = []
 
138
 
139
- else:
140
- gseen.pop()
141
- matching_long_chords_chunks.pop()
142
 
143
- else:
144
- gseen.pop()
145
- matching_long_chords_chunks.pop()
146
 
 
147
 
148
- if len(matching_long_chords_chunks) > max_song_len:
149
- print('Current song length:', len(matching_long_chords_chunks), 'chords chunks')
150
- print('=' * 70)
151
- final_song = matching_long_chords_chunks
 
 
 
152
 
153
- max_song_len = max(max_song_len, len(matching_long_chords_chunks))
154
 
155
- tries += 1
 
 
 
 
 
 
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
- f_song = []
 
 
167
 
168
- for mat in final_song:
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('Generated final song after', tries, 'tries with', len(final_song), 'chords chunks and', len(f_song), 'chords')
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] = chords_progression_MIDI_patch_number
189
 
190
  if base_MIDI_patch_number > -1:
191
  patches[2] = base_MIDI_patch_number
192
 
193
- if melody_MIDI_patch_number > -1:
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
- chord_str = str(i+1)
205
 
206
- for t in sorted(set([t % 12 for t in s])):
207
- chord_str += '-' + str(t)
208
-
209
- chords_labels.append(['text_event', time, chord_str])
210
 
211
  for p in s:
212
- output_score.append(['note', time, dur, 0, p, max(40, p), chords_progression_MIDI_patch_number])
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(midi_score,
232
- output_signature = 'Pitches Chords Progression',
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
- print('Generated chords progression info and stats:')
262
- print('=' * 70)
263
 
264
- chords_progression_summary_string = '=' * 70
265
- chords_progression_summary_string += '\n'
266
-
267
- all_song_chords = []
268
 
269
- for pc in f_song:
270
- tones_chord = tuple(sorted(set([p % 12 for p in pc])))
271
- all_song_chords.append([pc, tones_chord])
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, chords_progression_summary_string
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