Update app.py
Browse files
app.py
CHANGED
@@ -14,6 +14,9 @@ import gradio as gr
|
|
14 |
from x_transformer_1_23_2 import *
|
15 |
import random
|
16 |
|
|
|
|
|
|
|
17 |
import tqdm
|
18 |
|
19 |
from midi_to_colab_audio import midi_to_colab_audio
|
@@ -88,130 +91,201 @@ def GenerateAccompaniment(input_midi, input_num_tokens, input_conditioning_type,
|
|
88 |
print('=' * 70)
|
89 |
|
90 |
#===============================================================================
|
|
|
91 |
raw_score = TMIDIX.midi2single_track_ms_score(input_midi.name)
|
92 |
|
93 |
-
|
94 |
-
# Enhanced score notes
|
95 |
|
96 |
-
escore_notes
|
|
|
|
|
97 |
|
98 |
-
|
99 |
|
100 |
-
|
|
|
101 |
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
clean_cscore = []
|
113 |
-
|
114 |
-
for c in cscore:
|
115 |
-
pitches = []
|
116 |
-
cho = []
|
117 |
-
for cc in c:
|
118 |
-
if cc[4] not in pitches:
|
119 |
-
cho.append(cc)
|
120 |
-
pitches.append(cc[4])
|
121 |
-
|
122 |
-
clean_cscore.append(cho)
|
123 |
-
|
124 |
-
#=======================================================
|
125 |
-
# FINAL PROCESSING
|
126 |
-
|
127 |
-
melody_chords = []
|
128 |
-
chords = []
|
129 |
-
times = [0]
|
130 |
-
durs = []
|
131 |
-
|
132 |
-
#=======================================================
|
133 |
-
# MAIN PROCESSING CYCLE
|
134 |
-
#=======================================================
|
135 |
-
|
136 |
-
pe = clean_cscore[0][0]
|
137 |
-
|
138 |
-
first_chord = True
|
139 |
-
|
140 |
-
for c in clean_cscore:
|
141 |
-
|
142 |
-
# Chords
|
143 |
-
|
144 |
-
c.sort(key=lambda x: x[4], reverse=True)
|
145 |
-
|
146 |
-
tones_chord = sorted(set([cc[4] % 12 for cc in c]))
|
147 |
-
|
148 |
-
try:
|
149 |
-
chord_token = TMIDIX.ALL_CHORDS_SORTED.index(tones_chord)
|
150 |
-
except:
|
151 |
-
checked_tones_chord = TMIDIX.check_and_fix_tones_chord(tones_chord)
|
152 |
-
chord_token = TMIDIX.ALL_CHORDS_SORTED.index(checked_tones_chord)
|
153 |
-
|
154 |
-
melody_chords.extend([chord_token+384])
|
155 |
-
|
156 |
-
if input_strip_notes:
|
157 |
-
if len(tones_chord) > 1:
|
158 |
-
chords.extend([chord_token+384])
|
159 |
-
|
160 |
-
else:
|
161 |
-
chords.extend([chord_token+384])
|
162 |
-
|
163 |
-
if first_chord:
|
164 |
-
melody_chords.extend([0])
|
165 |
-
first_chord = False
|
166 |
-
|
167 |
-
for e in c:
|
168 |
-
|
169 |
#=======================================================
|
170 |
-
#
|
171 |
-
|
172 |
-
time = e[1]-pe[1]
|
173 |
-
|
174 |
-
dur = e[2]
|
175 |
-
|
176 |
-
if time != 0 and time % 2 != 0:
|
177 |
-
time += 1
|
178 |
-
if dur % 2 != 0:
|
179 |
-
dur += 1
|
180 |
-
|
181 |
-
delta_time = int(max(0, min(255, time)) / 2)
|
182 |
-
|
183 |
-
# Durations
|
184 |
-
|
185 |
-
dur = int(max(0, min(255, dur)) / 2)
|
186 |
-
|
187 |
-
# Pitches
|
188 |
-
|
189 |
-
ptc = max(1, min(127, e[4]))
|
190 |
-
|
191 |
#=======================================================
|
192 |
-
#
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
|
|
|
|
|
|
|
|
205 |
else:
|
206 |
-
|
207 |
-
|
208 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
209 |
|
210 |
#==================================================================
|
211 |
|
212 |
print('=' * 70)
|
213 |
|
214 |
-
print('Sample output events', melody_chords[:
|
215 |
print('=' * 70)
|
216 |
print('Generating...')
|
217 |
|
@@ -291,34 +365,50 @@ def GenerateAccompaniment(input_midi, input_num_tokens, input_conditioning_type,
|
|
291 |
channel = 0
|
292 |
|
293 |
patches = [0] * 16
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
for ss in song:
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
314 |
|
315 |
-
fn1 = "Chords-Progressions-Transformer-Composition"
|
316 |
|
317 |
detailed_stats = TMIDIX.Tegridy_ms_SONG_to_MIDI_Converter(song_f,
|
318 |
-
output_signature = 'Chords Progressions Transformer',
|
319 |
output_file_name = fn1,
|
320 |
track_name='Project Los Angeles',
|
321 |
-
list_of_MIDI_patches=patches
|
|
|
322 |
)
|
323 |
|
324 |
new_fn = fn1+'.mid'
|
@@ -341,7 +431,7 @@ def GenerateAccompaniment(input_midi, input_num_tokens, input_conditioning_type,
|
|
341 |
output_midi = str(new_fn)
|
342 |
output_audio = (16000, audio)
|
343 |
|
344 |
-
output_plot = TMIDIX.plot_ms_SONG(song_f, plot_title=output_midi, return_plt=True)
|
345 |
|
346 |
print('Output MIDI file name:', output_midi)
|
347 |
print('Output MIDI title:', output_midi_title)
|
|
|
14 |
from x_transformer_1_23_2 import *
|
15 |
import random
|
16 |
|
17 |
+
import statistics
|
18 |
+
import copy
|
19 |
+
|
20 |
import tqdm
|
21 |
|
22 |
from midi_to_colab_audio import midi_to_colab_audio
|
|
|
91 |
print('=' * 70)
|
92 |
|
93 |
#===============================================================================
|
94 |
+
|
95 |
raw_score = TMIDIX.midi2single_track_ms_score(input_midi.name)
|
96 |
|
97 |
+
escore_notes = TMIDIX.advanced_score_processor(raw_score, return_enhanced_score_notes=True)
|
|
|
98 |
|
99 |
+
if escore_notes:
|
100 |
+
|
101 |
+
escore_notes = TMIDIX.augment_enhanced_score_notes(escore_notes[0], timings_divider=32, legacy_timings=True)
|
102 |
|
103 |
+
if escore_notes:
|
104 |
|
105 |
+
#=======================================================
|
106 |
+
# PRE-PROCESSING
|
107 |
|
108 |
+
# checking number of instruments in a composition
|
109 |
+
instruments_list = sorted(set([e[6] for e in escore_notes]))
|
110 |
+
instruments_list_without_drums = sorted(set([e[6] for e in escore_notes if e[3] != 9]))
|
111 |
+
main_instruments_list = sorted(set([e[6] for e in escore_notes if e[6] < 80]))
|
112 |
+
|
113 |
+
comp_times = [e[1] for e in escore_notes if e[6] < 80]
|
114 |
+
|
115 |
+
comp_dtimes = [max(1, min(127, b-a)) for a, b in zip(comp_times[:-1], comp_times[1:]) if b-a != 0]
|
116 |
+
avg_comp_dtime = max(0, min(127, int(sum(comp_dtimes) / len(comp_dtimes))))
|
117 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
118 |
#=======================================================
|
119 |
+
# FINAL PROCESSING
|
120 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
#=======================================================
|
122 |
+
# Adjusting avg velocity
|
123 |
+
|
124 |
+
vels = [e[5] for e in escore_notes]
|
125 |
+
avg_vel = int(sum(vels) / len(vels))
|
126 |
+
|
127 |
+
if avg_vel < 60:
|
128 |
+
TMIDIX.adjust_score_velocities(escore_notes, avg_vel * 2)
|
129 |
+
|
130 |
+
melody_chords = []
|
131 |
+
melody_chords2 = []
|
132 |
+
mel_cho = []
|
133 |
+
|
134 |
+
#=======================================================
|
135 |
+
# Break between compositions / Intro seq
|
136 |
+
|
137 |
+
if 128 in instruments_list:
|
138 |
+
drums_present = 1931 # Yes
|
139 |
else:
|
140 |
+
drums_present = 1930 # No
|
141 |
+
|
142 |
+
melody_chords.extend([1929, drums_present])
|
143 |
+
mel_cho.extend([1929, drums_present])
|
144 |
+
|
145 |
+
#=======================================================
|
146 |
+
# Composition patches list
|
147 |
+
|
148 |
+
melody_chords.extend([i+1932 for i in instruments_list_without_drums])
|
149 |
+
mel_cho.extend([i+1932 for i in instruments_list_without_drums])
|
150 |
+
#=======================================================
|
151 |
+
# Composition avg pitch and dtime
|
152 |
+
|
153 |
+
mode_instruments_pitch = statistics.mode([e[4] for e in escore_notes if e[6] < 80])
|
154 |
+
|
155 |
+
melody_chords.extend([2060+mode_instruments_pitch, 2188+avg_comp_dtime])
|
156 |
+
mel_cho.extend([2060+mode_instruments_pitch, 2188+avg_comp_dtime])
|
157 |
+
|
158 |
+
melody_chords2.append(mel_cho)
|
159 |
+
|
160 |
+
#=======================================================
|
161 |
+
# MAIN PROCESSING CYCLE
|
162 |
+
#=======================================================
|
163 |
+
|
164 |
+
cscore = TMIDIX.chordify_score([1000, escore_notes])
|
165 |
+
|
166 |
+
pc = cscore[0] # Previous chord
|
167 |
+
|
168 |
+
for i, c in enumerate(cscore):
|
169 |
+
|
170 |
+
c.sort(key=lambda x: x[6]) # Sorting by patch
|
171 |
+
|
172 |
+
#=======================================================
|
173 |
+
# Outro seq
|
174 |
+
|
175 |
+
#if len(cscore) > 256:
|
176 |
+
# if len(cscore) - i == 64:
|
177 |
+
# melody_chords.extend([2236])
|
178 |
+
|
179 |
+
#=======================================================
|
180 |
+
# Timings...
|
181 |
+
|
182 |
+
# Cliping all values...
|
183 |
+
delta_time = max(0, min(127, c[0][1]-pc[0][1]))
|
184 |
+
|
185 |
+
#=======================================================
|
186 |
+
# Chords...
|
187 |
+
|
188 |
+
cpitches = sorted([e[4] for e in c if e[3] != 9])
|
189 |
+
dpitches = [e[4] for e in c if e[3] == 9]
|
190 |
+
|
191 |
+
tones_chord = sorted(set([p % 12 for p in cpitches]))
|
192 |
+
|
193 |
+
if tones_chord:
|
194 |
+
|
195 |
+
if tones_chord not in TMIDIX.ALL_CHORDS_SORTED:
|
196 |
+
tones_chord_tok = 644
|
197 |
+
tones_chord_tok = TMIDIX.ALL_CHORDS_SORTED.index(TMIDIX.advanced_check_and_fix_tones_chord(tones_chord, cpitches[-1]))
|
198 |
+
|
199 |
+
else:
|
200 |
+
tones_chord_tok = TMIDIX.ALL_CHORDS_SORTED.index(tones_chord) # 321
|
201 |
+
|
202 |
+
if dpitches:
|
203 |
+
|
204 |
+
if tones_chord_tok == 644:
|
205 |
+
tones_chord_tok = 645
|
206 |
+
else:
|
207 |
+
tones_chord_tok += 321
|
208 |
+
|
209 |
+
else:
|
210 |
+
tones_chord_tok = 643 # Drums-only chord
|
211 |
+
|
212 |
+
#=======================================================
|
213 |
+
# Writing chord/time...
|
214 |
+
|
215 |
+
melody_chords.extend([tones_chord_tok, delta_time+646])
|
216 |
+
|
217 |
+
mel_cho = []
|
218 |
+
mel_cho.extend([tones_chord_tok, delta_time+646])
|
219 |
+
|
220 |
+
#=======================================================
|
221 |
+
# Notes...
|
222 |
+
|
223 |
+
pp = -1
|
224 |
+
|
225 |
+
for e in c:
|
226 |
+
|
227 |
+
#=======================================================
|
228 |
+
# Duration
|
229 |
+
dur = max(0, min(63, int(max(0, e[2] // 4) * 2)))
|
230 |
+
|
231 |
+
# Pitch
|
232 |
+
ptc = max(1, min(127, e[4]))
|
233 |
+
|
234 |
+
# Octo-velocity
|
235 |
+
vel = max(8, min(127, (max(1, e[5] // 8) * 8)))
|
236 |
+
velocity = round(vel / 15)-1
|
237 |
+
|
238 |
+
# Patch
|
239 |
+
pat = max(0, min(128, e[6]))
|
240 |
+
|
241 |
+
if 7 < pat < 80:
|
242 |
+
ptc += 128
|
243 |
+
|
244 |
+
elif 79 < pat < 128:
|
245 |
+
ptc += 256
|
246 |
+
|
247 |
+
elif pat == 128:
|
248 |
+
ptc += 384
|
249 |
+
|
250 |
+
#=======================================================
|
251 |
+
# FINAL NOTE SEQ
|
252 |
+
|
253 |
+
# Writing final note asynchronously
|
254 |
+
|
255 |
+
dur_vel = (8 * dur) + velocity # 512
|
256 |
+
|
257 |
+
if pat != pp:
|
258 |
+
melody_chords.extend([pat+774, ptc+904, dur_vel+1416]) # 1928
|
259 |
+
mel_cho.extend([pat+774, ptc+904, dur_vel+1416])
|
260 |
+
|
261 |
+
else:
|
262 |
+
melody_chords.extend([ptc+904, dur_vel+1416])
|
263 |
+
mel_cho.extend([ptc+904, dur_vel+1416])
|
264 |
+
|
265 |
+
pp = pat
|
266 |
+
|
267 |
+
pc = c
|
268 |
+
|
269 |
+
melody_chords2.append(mel_cho)
|
270 |
+
|
271 |
+
#=======================================================
|
272 |
+
|
273 |
+
#melody_chords.extend([2237]) # EOS
|
274 |
+
|
275 |
+
#=======================================================
|
276 |
+
# TOTAL DICTIONARY SIZE 2237+1=2238
|
277 |
+
#=======================================================
|
278 |
+
|
279 |
+
print('Done!')
|
280 |
+
print('=' * 70)
|
281 |
+
print(len(melody_chords))
|
282 |
+
print('=' * 70)
|
283 |
|
284 |
#==================================================================
|
285 |
|
286 |
print('=' * 70)
|
287 |
|
288 |
+
print('Sample output events', melody_chords[:12])
|
289 |
print('=' * 70)
|
290 |
print('Generating...')
|
291 |
|
|
|
365 |
channel = 0
|
366 |
|
367 |
patches = [0] * 16
|
368 |
+
patches[9] = 9
|
369 |
+
|
|
|
370 |
for ss in song:
|
371 |
+
|
372 |
+
if 645 < ss < 774:
|
373 |
+
|
374 |
+
time += (ss-646)
|
375 |
+
|
376 |
+
if 773 < ss < 904:
|
377 |
+
|
378 |
+
pat = (ss - 774)
|
379 |
+
|
380 |
+
chan = (pat // 8)
|
381 |
+
|
382 |
+
if 0 <= chan < 9:
|
383 |
+
channel = chan
|
384 |
+
|
385 |
+
elif 8 < chan < 15:
|
386 |
+
channel = chan + 1
|
387 |
+
|
388 |
+
elif chan == 16:
|
389 |
+
channel = 9
|
390 |
+
|
391 |
+
if 903 < ss < 1416:
|
392 |
+
|
393 |
+
pitch = (ss-904) % 128
|
394 |
+
|
395 |
+
if 1415 < ss < 1928:
|
396 |
+
|
397 |
+
dur = (((ss-1416) // 8)+1) * 2
|
398 |
+
vel = (((ss-1416) % 8)+1) * 15
|
399 |
+
|
400 |
+
song_f.append(['note', time, dur, channel, pitch, vel, pat])
|
401 |
+
|
402 |
+
song_f, patches, overflow_patches = TMIDIX.patch_enhanced_score_notes(song_f)
|
403 |
|
404 |
+
fn1 = "Ultimate-Chords-Progressions-Transformer-Composition"
|
405 |
|
406 |
detailed_stats = TMIDIX.Tegridy_ms_SONG_to_MIDI_Converter(song_f,
|
407 |
+
output_signature = 'Ultimate Chords Progressions Transformer',
|
408 |
output_file_name = fn1,
|
409 |
track_name='Project Los Angeles',
|
410 |
+
list_of_MIDI_patches=patches,
|
411 |
+
timings_multiplier=32
|
412 |
)
|
413 |
|
414 |
new_fn = fn1+'.mid'
|
|
|
431 |
output_midi = str(new_fn)
|
432 |
output_audio = (16000, audio)
|
433 |
|
434 |
+
output_plot = TMIDIX.plot_ms_SONG(song_f, plot_title=output_midi, return_plt=True, timings_multiplier=32)
|
435 |
|
436 |
print('Output MIDI file name:', output_midi)
|
437 |
print('Output MIDI title:', output_midi_title)
|