asigalov61 commited on
Commit
718967a
1 Parent(s): 9286911

Upload 4 files

Browse files
Files changed (4) hide show
  1. TMIDIX.py +0 -0
  2. app.py +266 -0
  3. packages.txt +1 -0
  4. requirements.txt +3 -0
TMIDIX.py ADDED
The diff for this file is too large to render. See raw diff
 
app.py ADDED
@@ -0,0 +1,266 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # https://huggingface.co/spaces/asigalov61/MIDI-Search
2
+
3
+ import os
4
+
5
+ import time as reqtime
6
+ import datetime
7
+ from pytz import timezone
8
+
9
+ from sentence_transformers import SentenceTransformer
10
+ from sentence_transformers import util
11
+
12
+ import numpy as np
13
+
14
+ import gradio as gr
15
+
16
+ import copy
17
+ import random
18
+ import pickle
19
+
20
+ import zlib
21
+
22
+ from midi_to_colab_audio import midi_to_colab_audio
23
+
24
+ import TMIDIX
25
+
26
+ import matplotlib.pyplot as plt
27
+
28
+ #==========================================================================================================
29
+
30
+ def find_midi(title, artist):
31
+
32
+ print('=' * 70)
33
+ print('Req start time: {:%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now(PDT)))
34
+ start_time = reqtime.time()
35
+
36
+ print('-' * 70)
37
+ print('Req title:', title)
38
+ print('Req artist:', artist)
39
+ print('-' * 70)
40
+
41
+
42
+ input_text = ''
43
+
44
+ if title != '':
45
+ input_text += title
46
+ if artist != '':
47
+ input_text += ' by ' + artist
48
+
49
+ print('Searching...')
50
+
51
+ query_embedding = model.encode([input_text])
52
+
53
+ # Compute cosine similarity between query and each sentence in the corpus
54
+ similarities = util.cos_sim(query_embedding, corpus_embeddings)
55
+
56
+ top_ten_matches_idxs = np.argsort(-similarities)[0][:10].tolist()
57
+
58
+ # Find the index of the most similar sentence
59
+ closest_index = np.argmax(similarities)
60
+ closest_index_match_ratio = max(similarities[0]).tolist()
61
+
62
+ best_corpus_match = all_MIDI_files_names[closest_index]
63
+
64
+ top_ten_matches = ''
65
+
66
+ for t in top_ten_matches_idxs:
67
+ top_ten_matches += str(all_MIDI_files_names[t][0]).title() + '\n'
68
+
69
+ print('Done!')
70
+ print('=' * 70)
71
+
72
+ print('Match corpus index', closest_index)
73
+ print('Match corpus ratio', closest_index_match_ratio)
74
+
75
+ print('=' * 70)
76
+ print('Done!')
77
+ print('=' * 70)
78
+
79
+ song_artist = best_corpus_match[0]
80
+ song_artist_title = str(song_artist).title()
81
+ zlib_file_name = best_corpus_match[1]
82
+
83
+ print('Fetching MIDI score...')
84
+
85
+ with open(zlib_file_name, 'rb') as f:
86
+ compressed_data = f.read()
87
+
88
+ # Decompress the data
89
+ decompressed_data = zlib.decompress(compressed_data)
90
+
91
+ # Convert the bytes back to a list using pickle
92
+ scores_data = pickle.loads(decompressed_data)
93
+
94
+ fnames = [f[0] for f in scores_data]
95
+
96
+ fnameidx = fnames.index(song_artist)
97
+
98
+ MIDI_score_data = scores_data[fnameidx][1]
99
+
100
+ print('Rendering results...')
101
+ print('=' * 70)
102
+ print('MIDi Title:', song_artist_title)
103
+ print('Sample INTs', MIDI_score_data[:12])
104
+ print('=' * 70)
105
+
106
+ if len(MIDI_score_data) != 0:
107
+
108
+ song = MIDI_score_data
109
+ song_f = []
110
+
111
+ time = 0
112
+ dur = 0
113
+ vel = 90
114
+ pitch = 0
115
+ channel = 0
116
+
117
+ patches = [-1] * 16
118
+
119
+ channels = [0] * 16
120
+ channels[9] = 1
121
+
122
+ for ss in song:
123
+
124
+ if 0 <= ss < 256:
125
+
126
+ time += ss * 16
127
+
128
+ if 256 <= ss < 512:
129
+
130
+ dur = (ss-256) * 16
131
+
132
+ if 512 <= ss <= 640:
133
+
134
+ patch = (ss-512)
135
+
136
+ if patch < 128:
137
+
138
+ if patch not in patches:
139
+ if 0 in channels:
140
+ cha = channels.index(0)
141
+ channels[cha] = 1
142
+ else:
143
+ cha = 15
144
+
145
+ patches[cha] = patch
146
+ channel = patches.index(patch)
147
+ else:
148
+ channel = patches.index(patch)
149
+
150
+ if patch == 128:
151
+ channel = 9
152
+
153
+ if 640 < ss < 768:
154
+
155
+ ptc = (ss-640)
156
+
157
+ if 768 < ss < 896:
158
+
159
+ vel = (ss - 768)
160
+
161
+ song_f.append(['note', time, dur, channel, ptc, vel, patch ])
162
+
163
+ patches = [0 if x==-1 else x for x in patches]
164
+
165
+ print('=' * 70)
166
+
167
+ #===============================================================================
168
+
169
+ output_score, patches, overflow_patches = TMIDIX.patch_enhanced_score_notes(song_f)
170
+
171
+ detailed_stats = TMIDIX.Tegridy_ms_SONG_to_MIDI_Converter(output_score,
172
+ output_signature = 'Los Angeles MIDI Dataset Search',
173
+ output_file_name = song_artist_title,
174
+ track_name='Project Los Angeles',
175
+ list_of_MIDI_patches=patches
176
+ )
177
+
178
+ new_fn = song_artist_title + '.mid'
179
+
180
+ audio = midi_to_colab_audio(new_fn,
181
+ soundfont_path=soundfont,
182
+ sample_rate=16000,
183
+ volume_scale=10,
184
+ output_for_gradio=True
185
+ )
186
+
187
+ print('Done!')
188
+ print('=' * 70)
189
+
190
+ #========================================================
191
+
192
+ output_midi_title = str(song_artist_title)
193
+ output_midi_summary = str(top_ten_matches)
194
+ output_midi = str(new_fn)
195
+ output_audio = (16000, audio)
196
+
197
+ output_plot = TMIDIX.plot_ms_SONG(output_score, plot_title=output_midi_title, return_plt=True)
198
+
199
+ print('Output MIDI file name:', output_midi)
200
+ print('Output MIDI title:', output_midi_title)
201
+ print('Output MIDI summary:', output_midi_summary)
202
+ print('=' * 70)
203
+
204
+ #========================================================
205
+
206
+ print('-' * 70)
207
+ print('Req end time: {:%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now(PDT)))
208
+ print('-' * 70)
209
+ print('Req execution time:', (reqtime.time() - start_time), 'sec')
210
+
211
+ return output_midi_title, output_midi_summary, output_midi, output_audio, output_plot
212
+
213
+ #==========================================================================================================
214
+
215
+ if __name__ == "__main__":
216
+
217
+ PDT = timezone('US/Pacific')
218
+
219
+ print('=' * 70)
220
+ print('App start time: {:%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now(PDT)))
221
+ print('=' * 70)
222
+
223
+ soundfont = "SGM-v2.01-YamahaGrand-Guit-Bass-v2.7.sf2"
224
+ print('Loading files list...')
225
+
226
+ all_MIDI_files_names = TMIDIX.Tegridy_Any_Pickle_File_Reader('all_MIDI_files_names')
227
+ print('=' * 70)
228
+
229
+ print('Loading MIDI corpus embeddings...')
230
+
231
+ corpus_embeddings = np.load('MIDI_corpus_embeddings_all-mpnet-base-v2.npz')['data']
232
+ print('Done!')
233
+ print('=' * 70)
234
+
235
+ print('Loading Sentence Transformer model...')
236
+ model = SentenceTransformer('all-mpnet-base-v2')
237
+ print('Done!')
238
+ print('=' * 70)
239
+
240
+ app = gr.Blocks()
241
+
242
+ with app:
243
+ gr.Markdown("<h1 style='text-align: center; margin-bottom: 1rem'>Advanced MIDI Search</h1>")
244
+ gr.Markdown("<h1 style='text-align: center; margin-bottom: 1rem'>Search and explore 179k+ MIDI titles with sentence transformer</h1>")
245
+
246
+ gr.Markdown("![Visitors](https://api.visitorbadge.io/api/visitors?path=asigalov61.MIDI-Search&style=flat)\n\n")
247
+
248
+ gr.Markdown("# Enter any desired title, artist or both\n\n")
249
+
250
+ title = gr.Textbox(label="Song Title", value="Family Guy")
251
+ artist = gr.Textbox(label="Song Artist", value="TV Themes")
252
+ submit = gr.Button(value='Search')
253
+ gr.ClearButton(components=[title, artist])
254
+
255
+ gr.Markdown("# Search results")
256
+
257
+ output_midi_title = gr.Textbox(label="Output MIDI title")
258
+ output_midi_summary = gr.Textbox(label="Top ten MIDI matches")
259
+ output_audio = gr.Audio(label="Output MIDI audio", format="wav", elem_id="midi_audio")
260
+ output_plot = gr.Plot(label="Output MIDI score plot")
261
+ output_midi = gr.File(label="Output MIDI file", file_types=[".mid"])
262
+
263
+ run_event = submit.click(find_midi, [title, artist],
264
+ [output_midi_title, output_midi_summary, output_midi, output_audio, output_plot ])
265
+
266
+ app.launch()
packages.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ fluidsynth
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ gradio
2
+ sentence-transformers
3
+ numpy