asigalov61 commited on
Commit
8fb3b92
·
verified ·
1 Parent(s): e44e474

Upload 6 files

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ SGM-v2.01-YamahaGrand-Guit-Bass-v2.7.sf2 filter=lfs diff=lfs merge=lfs -text
SGM-v2.01-YamahaGrand-Guit-Bass-v2.7.sf2 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cd41a4639c9e7a96413b4b22540d48e6741e24bcdabcb2eff22cd65929df3cfa
3
+ size 553961496
TMIDIX.py ADDED
The diff for this file is too large to render. See raw diff
 
app.py ADDED
@@ -0,0 +1,417 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os.path
2
+
3
+ import time as reqtime
4
+ import datetime
5
+ from pytz import timezone
6
+
7
+ import torch
8
+
9
+ import spaces
10
+ import gradio as gr
11
+
12
+ from x_transformer_1_23_2 import *
13
+ import random
14
+ import tqdm
15
+
16
+ from midi_to_colab_audio import midi_to_colab_audio
17
+ import TMIDIX
18
+
19
+ import matplotlib.pyplot as plt
20
+
21
+ in_space = os.getenv("SYSTEM") == "spaces"
22
+
23
+ # =================================================================================================
24
+
25
+ @spaces.GPU
26
+ def GenerateAccompaniment(input_midi, input_num_tokens, input_conditioning_type, input_strip_notes):
27
+ print('=' * 70)
28
+ print('Req start time: {:%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now(PDT)))
29
+ start_time = reqtime.time()
30
+
31
+ print('Loading model...')
32
+
33
+ SEQ_LEN = 8192 # Models seq len
34
+ PAD_IDX = 707 # Models pad index
35
+ DEVICE = 'cuda' # 'cuda'
36
+
37
+ # instantiate the model
38
+
39
+ model = TransformerWrapper(
40
+ num_tokens = PAD_IDX+1,
41
+ max_seq_len = SEQ_LEN,
42
+ attn_layers = Decoder(dim = 2048, depth = 4, heads = 16, attn_flash = True)
43
+ )
44
+
45
+ model = AutoregressiveWrapper(model, ignore_index = PAD_IDX)
46
+
47
+ model.to(DEVICE)
48
+ print('=' * 70)
49
+
50
+ print('Loading model checkpoint...')
51
+
52
+ model.load_state_dict(
53
+ torch.load('Chords_Progressions_Transformer_Small_2048_Trained_Model_12947_steps_0.9316_loss_0.7386_acc.pth',
54
+ map_location=DEVICE))
55
+ print('=' * 70)
56
+
57
+ model.eval()
58
+
59
+ if DEVICE == 'cpu':
60
+ dtype = torch.bfloat16
61
+ else:
62
+ dtype = torch.float16
63
+
64
+ ctx = torch.amp.autocast(device_type=DEVICE, dtype=dtype)
65
+
66
+ print('Done!')
67
+ print('=' * 70)
68
+
69
+ fn = os.path.basename(input_midi.name)
70
+ fn1 = fn.split('.')[0]
71
+
72
+ input_num_tokens = max(4, min(128, input_num_tokens))
73
+
74
+ print('-' * 70)
75
+ print('Input file name:', fn)
76
+ print('Req num toks:', input_num_tokens)
77
+ print('Conditioning type:', input_conditioning_type)
78
+ print('Strip notes:', input_strip_notes)
79
+ print('-' * 70)
80
+
81
+ #===============================================================================
82
+ raw_score = TMIDIX.midi2single_track_ms_score(input_midi.name)
83
+
84
+ #===============================================================================
85
+ # Enhanced score notes
86
+
87
+ escore_notes = TMIDIX.advanced_score_processor(raw_score, return_enhanced_score_notes=True)[0]
88
+
89
+ no_drums_escore_notes = [e for e in escore_notes if e[6] < 80]
90
+
91
+ if len(no_drums_escore_notes) > 0:
92
+
93
+ #=======================================================
94
+ # PRE-PROCESSING
95
+
96
+ #===============================================================================
97
+ # Augmented enhanced score notes
98
+
99
+ no_drums_escore_notes = TMIDIX.augment_enhanced_score_notes(no_drums_escore_notes)
100
+
101
+ cscore = TMIDIX.chordify_score([1000, no_drums_escore_notes])
102
+
103
+ clean_cscore = []
104
+
105
+ for c in cscore:
106
+ pitches = []
107
+ cho = []
108
+ for cc in c:
109
+ if cc[4] not in pitches:
110
+ cho.append(cc)
111
+ pitches.append(cc[4])
112
+
113
+ clean_cscore.append(cho)
114
+
115
+ #=======================================================
116
+ # FINAL PROCESSING
117
+
118
+ melody_chords = []
119
+ chords = []
120
+ times = [0]
121
+ durs = []
122
+
123
+ #=======================================================
124
+ # MAIN PROCESSING CYCLE
125
+ #=======================================================
126
+
127
+ pe = clean_cscore[0][0]
128
+
129
+ first_chord = True
130
+
131
+ for c in clean_cscore:
132
+
133
+ # Chords
134
+
135
+ c.sort(key=lambda x: x[4], reverse=True)
136
+
137
+ tones_chord = sorted(set([cc[4] % 12 for cc in c]))
138
+
139
+ try:
140
+ chord_token = TMIDIX.ALL_CHORDS_SORTED.index(tones_chord)
141
+ except:
142
+ checked_tones_chord = TMIDIX.check_and_fix_tones_chord(tones_chord)
143
+ chord_token = TMIDIX.ALL_CHORDS_SORTED.index(checked_tones_chord)
144
+
145
+ melody_chords.extend([chord_token+384])
146
+
147
+ if input_strip_notes:
148
+ if len(tones_chord) > 1:
149
+ chords.extend([chord_token+384])
150
+
151
+ else:
152
+ chords.extend([chord_token+384])
153
+
154
+ if first_chord:
155
+ melody_chords.extend([0])
156
+ first_chord = False
157
+
158
+ for e in c:
159
+
160
+ #=======================================================
161
+ # Timings...
162
+
163
+ time = e[1]-pe[1]
164
+
165
+ dur = e[2]
166
+
167
+ if time != 0 and time % 2 != 0:
168
+ time += 1
169
+ if dur % 2 != 0:
170
+ dur += 1
171
+
172
+ delta_time = int(max(0, min(255, time)) / 2)
173
+
174
+ # Durations
175
+
176
+ dur = int(max(0, min(255, dur)) / 2)
177
+
178
+ # Pitches
179
+
180
+ ptc = max(1, min(127, e[4]))
181
+
182
+ #=======================================================
183
+ # FINAL NOTE SEQ
184
+
185
+ # Writing final note asynchronously
186
+
187
+ if delta_time != 0:
188
+ melody_chords.extend([delta_time, dur+128, ptc+256])
189
+ if input_strip_notes:
190
+ if len(c) > 1:
191
+ times.append(delta_time)
192
+ durs.append(dur+128)
193
+ else:
194
+ times.append(delta_time)
195
+ durs.append(dur+128)
196
+ else:
197
+ melody_chords.extend([dur+128, ptc+256])
198
+
199
+ pe = e
200
+
201
+ #==================================================================
202
+
203
+ print('=' * 70)
204
+
205
+ print('Sample output events', melody_chords[:5])
206
+ print('=' * 70)
207
+ print('Generating...')
208
+
209
+ output = []
210
+
211
+ max_chords_limit = 8
212
+ temperature=0.9
213
+ num_memory_tokens=4096
214
+
215
+ output = []
216
+
217
+ idx = 0
218
+
219
+ for c in chords[:input_num_tokens]:
220
+
221
+ output.append(c)
222
+
223
+ if input_conditioning_type == 'Chords-Times' or input_conditioning_type == 'Chords-Times-Durations':
224
+ output.append(times[idx])
225
+
226
+ if input_conditioning_type == 'Chords-Times-Durations':
227
+ output.append(durs[idx])
228
+
229
+ x = torch.tensor([output] * 1, dtype=torch.long, device='cuda')
230
+
231
+ o = 0
232
+
233
+ ncount = 0
234
+
235
+ while o < 384 and ncount < max_chords_limit:
236
+ with ctx:
237
+ out = model.generate(x[-num_memory_tokens:],
238
+ 1,
239
+ temperature=temperature,
240
+ return_prime=False,
241
+ verbose=False)
242
+
243
+ o = out.tolist()[0][0]
244
+
245
+ if 256 <= o < 384:
246
+ ncount += 1
247
+
248
+ if o < 384:
249
+ x = torch.cat((x, out), 1)
250
+
251
+ outy = x.tolist()[0][len(output):]
252
+
253
+ output.extend(outy)
254
+
255
+ idx += 1
256
+
257
+ if idx == len(chords[:input_num_tokens])-1:
258
+ break
259
+
260
+ print('=' * 70)
261
+ print('Done!')
262
+ print('=' * 70)
263
+
264
+ #===============================================================================
265
+ print('Rendering results...')
266
+
267
+ print('=' * 70)
268
+ print('Sample INTs', output[:12])
269
+ print('=' * 70)
270
+
271
+ out1 = output
272
+
273
+ if len(out1) != 0:
274
+
275
+ song = out1
276
+ song_f = []
277
+
278
+ time = 0
279
+ dur = 0
280
+ vel = 90
281
+ pitch = 0
282
+ channel = 0
283
+
284
+ patches = [0] * 16
285
+
286
+ channel = 0
287
+
288
+ for ss in song:
289
+
290
+ if 0 <= ss < 128:
291
+
292
+ time += ss * 32
293
+
294
+ if 128 <= ss < 256:
295
+
296
+ dur = (ss-128) * 32
297
+
298
+ if 256 <= ss < 384:
299
+
300
+ pitch = (ss-256)
301
+
302
+ vel = max(40, pitch)
303
+
304
+ song_f.append(['note', time, dur, channel, pitch, vel, 0])
305
+
306
+ fn1 = "Chords-Progressions-Transformer-Composition"
307
+
308
+ detailed_stats = TMIDIX.Tegridy_ms_SONG_to_MIDI_Converter(song_f,
309
+ output_signature = 'Chords Progressions Transformer',
310
+ output_file_name = fn1,
311
+ track_name='Project Los Angeles',
312
+ list_of_MIDI_patches=patches
313
+ )
314
+
315
+ new_fn = fn1+'.mid'
316
+
317
+
318
+ audio = midi_to_colab_audio(new_fn,
319
+ soundfont_path=soundfont,
320
+ sample_rate=16000,
321
+ volume_scale=10,
322
+ output_for_gradio=True
323
+ )
324
+
325
+ print('Done!')
326
+ print('=' * 70)
327
+
328
+ #========================================================
329
+
330
+ output_midi_title = str(fn1)
331
+ output_midi_summary = str(song_f[:3])
332
+ output_midi = str(new_fn)
333
+ output_audio = (16000, audio)
334
+
335
+ output_plot = TMIDIX.plot_ms_SONG(song_f, plot_title=output_midi, return_plt=True)
336
+
337
+ print('Output MIDI file name:', output_midi)
338
+ print('Output MIDI title:', output_midi_title)
339
+ print('Output MIDI summary:', '')
340
+ print('=' * 70)
341
+
342
+
343
+ #========================================================
344
+
345
+ print('-' * 70)
346
+ print('Req end time: {:%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now(PDT)))
347
+ print('-' * 70)
348
+ print('Req execution time:', (reqtime.time() - start_time), 'sec')
349
+
350
+ return output_midi_title, output_midi_summary, output_midi, output_audio, output_plot
351
+
352
+ # =================================================================================================
353
+
354
+ if __name__ == "__main__":
355
+
356
+ PDT = timezone('US/Pacific')
357
+
358
+ print('=' * 70)
359
+ print('App start time: {:%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now(PDT)))
360
+ print('=' * 70)
361
+
362
+ soundfont = "SGM-v2.01-YamahaGrand-Guit-Bass-v2.7.sf2"
363
+
364
+ app = gr.Blocks()
365
+ with app:
366
+ gr.Markdown("<h1 style='text-align: center; margin-bottom: 1rem'>Chords Progressions Transformer</h1>")
367
+ gr.Markdown("<h1 style='text-align: center; margin-bottom: 1rem'>Chords-conditioned music transformer</h1>")
368
+ gr.Markdown(
369
+ "![Visitors](https://api.visitorbadge.io/api/visitors?path=asigalov61.Chords-Progressions-Transformer&style=flat)\n\n"
370
+ "Generate music based on chords progressions\n\n"
371
+ "Check out [Chords Progressions Transformer](https://github.com/asigalov61/Chords-Progressions-Transformer) on GitHub!\n\n"
372
+ "[Open In Colab]"
373
+ "(https://colab.research.google.com/github/asigalov61/Chords-Progressions-Transformer/blob/main/Chords_Progressions_Transformer.ipynb)"
374
+ " for faster execution and endless generation"
375
+ )
376
+ gr.Markdown("## Upload your MIDI or select a sample example MIDI")
377
+
378
+ input_midi = gr.File(label="Input MIDI", file_types=[".midi", ".mid", ".kar"])
379
+ input_num_tokens = gr.Slider(4, 128, value=32, step=1, label="Number of composition chords to generate progression for")
380
+ input_conditioning_type = gr.Radio(["Chords", "Chords-Times", "Chords-Times-Durations"], label="Conditioning type")
381
+ input_strip_notes = gr.Checkbox(label="Strip notes from the composition")
382
+
383
+ run_btn = gr.Button("generate", variant="primary")
384
+
385
+ gr.Markdown("## Generation results")
386
+
387
+ output_midi_title = gr.Textbox(label="Output MIDI title")
388
+ output_midi_summary = gr.Textbox(label="Output MIDI summary")
389
+ output_audio = gr.Audio(label="Output MIDI audio", format="wav", elem_id="midi_audio")
390
+ output_plot = gr.Plot(label="Output MIDI score plot")
391
+ output_midi = gr.File(label="Output MIDI file", file_types=[".mid"])
392
+
393
+
394
+ run_event = run_btn.click(GenerateAccompaniment, [input_midi, input_num_tokens, input_conditioning_type, input_strip_notes],
395
+ [output_midi_title, output_midi_summary, output_midi, output_audio, output_plot])
396
+
397
+ gr.Examples(
398
+ [["Chords-Progressions-Transformer-Piano-Seed-1.mid", 128, "Chords", False],
399
+ ["Chords-Progressions-Transformer-Piano-Seed-2.mid", 128, "Chords-Times", False],
400
+ ["Chords-Progressions-Transformer-Piano-Seed-3.mid", 128, "Chords-Times-Durations", False],
401
+ ["Chords-Progressions-Transformer-Piano-Seed-4.mid", 128, "Chords", False],
402
+ ["Chords-Progressions-Transformer-Piano-Seed-5.mid", 128, "Chords-Times", False],
403
+ ["Chords-Progressions-Transformer-Piano-Seed-6.mid", 128, "Chords-Times-Durations", False],
404
+ ["Chords-Progressions-Transformer-MI-Seed-1.mid", 128, "Chords", False],
405
+ ["Chords-Progressions-Transformer-MI-Seed-2.mid", 128, "Chords-Times", False],
406
+ ["Chords-Progressions-Transformer-MI-Seed-3.mid", 128, "Chords-Times-Durations", False],
407
+ ["Chords-Progressions-Transformer-MI-Seed-4.mid", 128, "Chords-Times", False],
408
+ ["Chords-Progressions-Transformer-MI-Seed-5.mid", 128, "Chords", False],
409
+ ["Chords-Progressions-Transformer-MI-Seed-6.mid", 128, "Chords-Times-Durations", False]
410
+ ],
411
+ [input_midi, input_num_tokens, input_conditioning_type, input_strip_notes],
412
+ [output_midi_title, output_midi_summary, output_midi, output_audio, output_plot],
413
+ GenerateAccompaniment,
414
+ cache_examples=True,
415
+ )
416
+
417
+ app.queue().launch()
midi_to_colab_audio.py ADDED
The diff for this file is too large to render. See raw diff
 
packages.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ fluidsynth
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ torch
2
+ gradio
3
+ einops