Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -47,6 +47,7 @@ SOUDFONT_PATH = 'SGM-v2.01-YamahaGrand-Guit-Bass-v2.7.sf2'
|
|
47 |
#==================================================================================
|
48 |
|
49 |
print('Loading MIDI Loops Small Dataset...')
|
|
|
50 |
|
51 |
midi_loops_dataset = TMIDIX.Tegridy_Any_Pickle_File_Reader('MIDI-Loops-Dataset-Small-CC-BY-NC-SA.pickle')
|
52 |
|
@@ -68,6 +69,7 @@ def find_matches(src_array, trg_array):
|
|
68 |
#==================================================================================
|
69 |
|
70 |
def find_closest_tuple(tuples_list, src_tuple):
|
|
|
71 |
def euclidean_distance(t1, t2):
|
72 |
return sum((a - b) ** 2 for a, b in zip(t1, t2)) ** 0.5
|
73 |
|
@@ -119,10 +121,6 @@ def Mix_Loops(input_midi,
|
|
119 |
model_temperature
|
120 |
):
|
121 |
|
122 |
-
#===============================================================================
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
#===============================================================================
|
127 |
|
128 |
print('=' * 70)
|
@@ -143,22 +141,199 @@ def Mix_Loops(input_midi,
|
|
143 |
|
144 |
print('=' * 70)
|
145 |
|
146 |
-
|
147 |
-
|
148 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
149 |
|
150 |
#==================================================================
|
151 |
|
152 |
print('=' * 70)
|
153 |
print('Generating...')
|
154 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
155 |
|
156 |
-
|
157 |
print('=' * 70)
|
158 |
print('Done!')
|
159 |
print('=' * 70)
|
160 |
|
161 |
#===============================================================================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
162 |
|
163 |
print('Rendering results...')
|
164 |
|
@@ -172,7 +347,7 @@ def Mix_Loops(input_midi,
|
|
172 |
|
173 |
fn1 = "MIDI-Loops-Mixer-Composition"
|
174 |
|
175 |
-
detailed_stats = TMIDIX.Tegridy_ms_SONG_to_MIDI_Converter(
|
176 |
output_signature = 'MIDI Loops Mixer',
|
177 |
output_file_name = fn1,
|
178 |
track_name='Project Los Angeles',
|
@@ -194,6 +369,7 @@ def Mix_Loops(input_midi,
|
|
194 |
|
195 |
#========================================================
|
196 |
|
|
|
197 |
output_midi = str(new_fn)
|
198 |
output_audio = (16000, audio)
|
199 |
|
@@ -204,6 +380,7 @@ def Mix_Loops(input_midi,
|
|
204 |
)
|
205 |
|
206 |
print('Output MIDI file name:', output_midi)
|
|
|
207 |
print('=' * 70)
|
208 |
|
209 |
#========================================================
|
@@ -213,7 +390,7 @@ def Mix_Loops(input_midi,
|
|
213 |
print('-' * 70)
|
214 |
print('Req execution time:', (reqtime.time() - start_time), 'sec')
|
215 |
|
216 |
-
return output_audio, output_plot, output_midi
|
217 |
|
218 |
#==================================================================================
|
219 |
|
@@ -256,18 +433,22 @@ with gr.Blocks() as demo:
|
|
256 |
generate_btn = gr.Button("Generate", variant="primary")
|
257 |
|
258 |
gr.Markdown("## Generation results")
|
259 |
-
|
|
|
260 |
output_audio = gr.Audio(label="MIDI audio", format="wav", elem_id="midi_audio")
|
261 |
output_plot = gr.Plot(label="MIDI score plot")
|
262 |
output_midi = gr.File(label="MIDI file", file_types=[".mid"])
|
263 |
|
264 |
generate_btn.click(Mix_Loops,
|
265 |
-
[
|
|
|
266 |
generation_type,
|
267 |
melody_patch,
|
268 |
model_temperature
|
269 |
],
|
270 |
-
[
|
|
|
|
|
271 |
output_plot,
|
272 |
output_midi
|
273 |
]
|
|
|
47 |
#==================================================================================
|
48 |
|
49 |
print('Loading MIDI Loops Small Dataset...')
|
50 |
+
print('-' * 70)
|
51 |
|
52 |
midi_loops_dataset = TMIDIX.Tegridy_Any_Pickle_File_Reader('MIDI-Loops-Dataset-Small-CC-BY-NC-SA.pickle')
|
53 |
|
|
|
69 |
#==================================================================================
|
70 |
|
71 |
def find_closest_tuple(tuples_list, src_tuple):
|
72 |
+
|
73 |
def euclidean_distance(t1, t2):
|
74 |
return sum((a - b) ** 2 for a, b in zip(t1, t2)) ** 0.5
|
75 |
|
|
|
121 |
model_temperature
|
122 |
):
|
123 |
|
|
|
|
|
|
|
|
|
124 |
#===============================================================================
|
125 |
|
126 |
print('=' * 70)
|
|
|
141 |
|
142 |
print('=' * 70)
|
143 |
|
144 |
+
#===============================================================================
|
|
|
145 |
|
146 |
+
chunk_len = 5
|
147 |
+
chunk_chords_set = 13
|
148 |
+
|
149 |
+
all_chords_chunks = []
|
150 |
+
|
151 |
+
midi_loops = [l for l in midi_loops_dataset if len(set(l[1][0])) >= chunk_chords_set]
|
152 |
+
|
153 |
+
for loop in tqdm.tqdm(midi_loops):
|
154 |
+
fn = loop[0]
|
155 |
+
chords = loop[1]
|
156 |
+
score = loop[2]
|
157 |
+
|
158 |
+
for c in chords:
|
159 |
+
all_chords_chunks.append(c[:chunk_len])
|
160 |
+
|
161 |
+
all_chords_chunks = np.array(all_chords_chunks)
|
162 |
|
163 |
#==================================================================
|
164 |
|
165 |
print('=' * 70)
|
166 |
print('Generating...')
|
167 |
|
168 |
+
max_num_loops = 4
|
169 |
+
max_tries = 100
|
170 |
+
loops_mult = 1
|
171 |
+
|
172 |
+
song_loops_counter = 0
|
173 |
+
|
174 |
+
stries = 0
|
175 |
+
|
176 |
+
while song_loops_counter < max_num_loops:
|
177 |
+
|
178 |
+
if stries % 25 == 0:
|
179 |
+
print('Attempt', stries)
|
180 |
+
stries += 1
|
181 |
+
|
182 |
+
midxs = []
|
183 |
+
sidxs = [-1]
|
184 |
+
|
185 |
+
while not midxs:
|
186 |
+
|
187 |
+
song_names = []
|
188 |
+
song_chords = []
|
189 |
+
song_scores = []
|
190 |
+
song_idxs = []
|
191 |
+
sidx = -1
|
192 |
+
|
193 |
+
while sidx in sidxs:
|
194 |
+
sidx = random.randint(0, len(midi_loops)-1)
|
195 |
+
|
196 |
+
song_idxs.append(sidx)
|
197 |
+
sidxs.append(sidx)
|
198 |
+
|
199 |
+
song_names.append(midi_loops[sidx][0])
|
200 |
+
song_chords.append(midi_loops[sidx][1][0][-chunk_len:]) #tv
|
201 |
+
song_scores.append(midi_loops[sidx][2])
|
202 |
+
|
203 |
+
song_midxs = [(song_idxs[-1]*loops_mult)+3]
|
204 |
+
|
205 |
+
midxs = [song_midxs[-1]]
|
206 |
+
|
207 |
+
midxs = find_matches(np.array(song_chords[-1]), all_chords_chunks)
|
208 |
+
midxs = [midx for midx in midxs if midx != song_midxs[-1]]
|
209 |
+
|
210 |
+
song_loops_counter = 1
|
211 |
+
rtries = 0
|
212 |
+
end = False
|
213 |
+
|
214 |
+
while song_loops_counter < max_num_loops and not end:
|
215 |
+
|
216 |
+
midxs = [song_midxs[-1]]
|
217 |
+
midxs = []
|
218 |
+
rmidxs = [-1]
|
219 |
+
|
220 |
+
midxs = find_matches(np.array(song_chords[-1]), all_chords_chunks)
|
221 |
+
midxs = [midx for midx in midxs if midx != song_midxs[-1]]
|
222 |
+
|
223 |
+
if midxs:
|
224 |
+
midx = find_best_midx(midxs, song_midxs[-1])
|
225 |
+
|
226 |
+
else:
|
227 |
+
midx = rmidxs[-1]
|
228 |
+
|
229 |
+
if midx not in rmidxs and midx not in song_midxs:
|
230 |
+
|
231 |
+
song_midxs.append(midx)
|
232 |
+
|
233 |
+
|
234 |
+
sidx = int(midx // loops_mult)
|
235 |
+
song_idxs.append(sidx)
|
236 |
+
|
237 |
+
song = midi_loops[sidx]
|
238 |
+
|
239 |
+
song_names.append(song[0])
|
240 |
+
song_chords.append(song[1][0][-chunk_len:]) # tv
|
241 |
+
song_scores.append(song[2])
|
242 |
+
|
243 |
+
song_loops_counter += 1
|
244 |
+
#print(song_loops_counter)
|
245 |
+
|
246 |
+
else:
|
247 |
+
if len(rmidxs) > 1 and rtries < max_tries:
|
248 |
+
song_idxs.pop()
|
249 |
+
song_midxs.pop()
|
250 |
+
song_names.pop()
|
251 |
+
song_chords.pop()
|
252 |
+
song_scores.pop()
|
253 |
+
#print('revert')
|
254 |
+
song_loops_counter -= 1
|
255 |
+
rtries += 1
|
256 |
+
rmidxs.append(midx)
|
257 |
+
|
258 |
+
else:
|
259 |
+
#print('end')
|
260 |
+
end = True
|
261 |
+
break
|
262 |
+
|
263 |
+
if end:
|
264 |
+
break
|
265 |
|
|
|
266 |
print('=' * 70)
|
267 |
print('Done!')
|
268 |
print('=' * 70)
|
269 |
|
270 |
#===============================================================================
|
271 |
+
|
272 |
+
final_song = []
|
273 |
+
last_max_dur = 0
|
274 |
+
last_dtime = 0
|
275 |
+
mode_dtime = 0
|
276 |
+
mode_dur = 0
|
277 |
+
|
278 |
+
for i, src_score in enumerate(song_scores):
|
279 |
+
|
280 |
+
final_song.append(['text_event', 0, song_names[i]])
|
281 |
+
|
282 |
+
score = copy.deepcopy(src_score)
|
283 |
+
|
284 |
+
for j in range(2):
|
285 |
+
|
286 |
+
if j == 1:
|
287 |
+
|
288 |
+
if i > 0:
|
289 |
+
last_chord = score[[e for e in range(len(score)) if score[e][0] > 0][-1]:]
|
290 |
+
last_dtime = last_chord[0][0]
|
291 |
+
last_max_dur = max([e[1] for e in last_chord])
|
292 |
+
|
293 |
+
dtimes = [e[0] for e in score if e[0] != 0]
|
294 |
+
durs = [e[1] for e in score]
|
295 |
+
|
296 |
+
mode_dtime= statistics.mode(dtimes)
|
297 |
+
mode_dur = statistics.mode(durs)
|
298 |
+
|
299 |
+
score[0][0] = max(mode_dtime, mode_dur)
|
300 |
+
|
301 |
+
rscore = list(reversed(score))
|
302 |
+
|
303 |
+
ccount = 0
|
304 |
+
for r in range(len(rscore)):
|
305 |
+
if rscore[r][0] > 0:
|
306 |
+
ccount += 1
|
307 |
+
|
308 |
+
if ccount == chunk_len:
|
309 |
+
break
|
310 |
+
|
311 |
+
trimmed_score = score[:-(r+1)]
|
312 |
+
|
313 |
+
extended_score = [['note'] + e for e in trimmed_score]
|
314 |
+
|
315 |
+
final_song.extend(extended_score)
|
316 |
+
|
317 |
+
|
318 |
+
else:
|
319 |
+
if i > 0:
|
320 |
+
last_chord = score[[e for e in range(len(score)) if score[e][0] > 0][-1]:]
|
321 |
+
last_dtime = last_chord[0][0]
|
322 |
+
last_max_dur = max([e[1] for e in last_chord])
|
323 |
+
|
324 |
+
dtimes = [e[0] for e in score if e[0] != 0]
|
325 |
+
durs = [e[1] for e in score]
|
326 |
+
|
327 |
+
mode_dtime= statistics.mode(dtimes)
|
328 |
+
mode_dur = statistics.mode(durs)
|
329 |
+
|
330 |
+
score[0][0] = max(mode_dtime, mode_dur)
|
331 |
+
|
332 |
+
extended_score = [['note'] + e for e in score]
|
333 |
+
|
334 |
+
final_song.extend(extended_score)
|
335 |
+
|
336 |
+
#===============================================================================
|
337 |
|
338 |
print('Rendering results...')
|
339 |
|
|
|
347 |
|
348 |
fn1 = "MIDI-Loops-Mixer-Composition"
|
349 |
|
350 |
+
detailed_stats = TMIDIX.Tegridy_ms_SONG_to_MIDI_Converter(output_score,
|
351 |
output_signature = 'MIDI Loops Mixer',
|
352 |
output_file_name = fn1,
|
353 |
track_name='Project Los Angeles',
|
|
|
369 |
|
370 |
#========================================================
|
371 |
|
372 |
+
output_midi_summary = ''
|
373 |
output_midi = str(new_fn)
|
374 |
output_audio = (16000, audio)
|
375 |
|
|
|
380 |
)
|
381 |
|
382 |
print('Output MIDI file name:', output_midi)
|
383 |
+
print('Output MIDI summary:', output_midi_summary)
|
384 |
print('=' * 70)
|
385 |
|
386 |
#========================================================
|
|
|
390 |
print('-' * 70)
|
391 |
print('Req execution time:', (reqtime.time() - start_time), 'sec')
|
392 |
|
393 |
+
return output_midi_summary, output_audio, output_plot, output_midi
|
394 |
|
395 |
#==================================================================================
|
396 |
|
|
|
433 |
generate_btn = gr.Button("Generate", variant="primary")
|
434 |
|
435 |
gr.Markdown("## Generation results")
|
436 |
+
|
437 |
+
output_midi_summary = gr.Textbox(label="MIDI summary")
|
438 |
output_audio = gr.Audio(label="MIDI audio", format="wav", elem_id="midi_audio")
|
439 |
output_plot = gr.Plot(label="MIDI score plot")
|
440 |
output_midi = gr.File(label="MIDI file", file_types=[".mid"])
|
441 |
|
442 |
generate_btn.click(Mix_Loops,
|
443 |
+
[
|
444 |
+
input_midi,
|
445 |
generation_type,
|
446 |
melody_patch,
|
447 |
model_temperature
|
448 |
],
|
449 |
+
[
|
450 |
+
output_midi_summary,
|
451 |
+
output_audio,
|
452 |
output_plot,
|
453 |
output_midi
|
454 |
]
|