Spaces:
Sleeping
Sleeping
File size: 9,465 Bytes
c10c249 cc4a711 c10c249 cd1a8cb c10c249 c5824b7 210ae7b c10c249 2dbbde3 c5824b7 6387673 c5824b7 32af644 5791635 a0baf01 5791635 32af644 5791635 32af644 c5824b7 5791635 c5824b7 b3d72a4 0c2c10c b3d72a4 c10c249 b3d72a4 c10c249 7724541 c10c249 7724541 c10c249 7724541 c10c249 72ef07a e9c4cef 72ef07a 5949155 907d5bd b7c7796 21fb761 907d5bd 72ef07a 7648069 c10c249 7648069 500d228 5e34946 7648069 72ef07a 7648069 e9c4cef 7648069 e9c4cef ee46fa2 7648069 ba9437d c10c249 ba9437d 5949155 ba9437d b3d72a4 ba9437d c10c249 e9c4cef 18fbc7d 72ef07a 4d700d3 c10c249 9b74ea3 c5824b7 c10c249 18fbc7d c10c249 c5824b7 7648069 210ae7b 7648069 210ae7b c5824b7 907d5bd b49f486 c10c249 cc4a711 c5a7526 c10c249 58672a4 c10c249 0c2c10c 46493b6 c10c249 5015e4e c10c249 cc4a711 c10c249 a0baf01 e9c4cef 72ef07a d9c1d7b c10c249 b3d72a4 c10c249 72ef07a e9c4cef 72ef07a c10c249 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
#================================================================
# https://huggingface.co/spaces/asigalov61/MIDI-Identification
#================================================================
import os
import hashlib
import time
import datetime
from pytz import timezone
import copy
from collections import Counter
import random
import statistics
import re
import gradio as gr
from huggingface_hub import InferenceClient
from datasets import load_dataset
import TMIDIX
#==========================================================================================================
HF_TOKEN = os.getenv('HF_TOKEN')
#==========================================================================================================
def format_table_data(data_string):
# Split the string into rows based on newlines
rows = data_string.strip().split("\n")
# Initialize a list to store the formatted data
formatted_data = []
for row in rows:
# Split each row into columns based on the separator '|' and strip extra spaces
columns = row.split("|")
formatted_row = [cell.strip() for cell in columns]
# Remove cells with only "-" symbols
formatted_row = [cell for cell in formatted_row if not all(char == '-' for char in cell)]
# Handle uneven rows by ensuring each row has the same number of columns
max_columns = max(len(columns) for columns in formatted_data) if formatted_data else len(columns)
while len(formatted_row) < max_columns:
formatted_row.append("") # Add empty strings to fill the row
formatted_data.append(formatted_row)
# Handle case where new rows have more columns than previous rows
max_columns = max(len(row) for row in formatted_data)
for row in formatted_data:
while len(row) < max_columns:
row.append("") # Add empty strings to fill the row
return formatted_data
#==========================================================================================================
MODELS = {'Mistral Nemo Instruct 2407': 'mistralai/Mistral-Nemo-Instruct-2407'
}
#==========================================================================================================
def ID_MIDI(input_midi, input_model):
print('*' * 70)
print('Req start time: {:%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now(PDT)))
start_time = time.time()
print('=' * 70)
print('Loading MIDI...')
fn = os.path.basename(input_midi)
fn1 = fn.split('.')[0]
fdata = open(input_midi, 'rb').read()
input_midi_md5hash = hashlib.md5(fdata).hexdigest()
print('=' * 70)
print('Requested settings:')
print('=' * 70)
print('Input MIDI file name:', fn)
print('Input MIDI md5 hash', input_midi_md5hash)
print('Input model:', input_model)
print('=' * 70)
print('Processing MIDI...Please wait...')
#=======================================================
# START PROCESSING
new_midi_data = TMIDIX.score2midi(TMIDIX.midi2score(fdata))
new_midi_md5hash = hashlib.md5(new_midi_data).hexdigest()
print('New md5 hash:', new_midi_md5hash)
print('Done!')
print('=' * 70)
print('Processing...Please wait...')
output_str = 'None'
output_midi_records_count = 0
output_midi_src_dataset= 'Unknown'
output_midi_path_str = 'None'
raw_score = TMIDIX.midi2single_track_ms_score(fdata)
escore_notes = TMIDIX.advanced_score_processor(raw_score, return_enhanced_score_notes=True)[0]
escore_notes = TMIDIX.augment_enhanced_score_notes(escore_notes, sort_drums_last=True)
output_midi_src_dataset = 'unknown'
output_midi_path_str = 'none'
if new_midi_md5hash in monster_midi_titles['md5_hashes_titles_dict']:
title = random.choice(monster_midi_titles['md5_hashes_titles_dict'][new_midi_md5hash]).split(' --- ')
song = title[0]
artist = title[1]
song_description = TMIDIX.escore_notes_to_text_description(escore_notes, song_name=song, artist_name=artist)
else:
song_description = TMIDIX.escore_notes_to_text_description(escore_notes)
if new_midi_md5hash in midid_md5_hashes:
midid_entry_idx = midid_md5_hashes.index(new_midi_md5hash)
MIDID_record = midid_dataset[midid_entry_idx]['midid']
output_midi_records_count = len(MIDID_record)
output_entry = random.choice(MIDID_record)
output_midi_src_dataset = output_entry[0]
output_midi_path_str = TMIDIX.clean_string(output_entry[1], regex=r'[^a-zA-Z0-9.() \n]')
client = InferenceClient(api_key=HF_TOKEN)
prompt = "Please create a summary table for a MIDI file based on the following keywords strings, best possible description and best possible summary fields. Please respond with the table only. Do not say anything else. Thank you."
data = 'Source MIDI dataset: ' + output_midi_src_dataset + '\n\n'
data += 'MIDI keywords strings:' + '\n'
data += output_midi_path_str + '\n\n'
data += 'Music description:' + '\n'
data += song_description
messages = [
{
"role": "user",
"content": prompt + "\n\n" + data
}
]
completion = client.chat.completions.create(
#model="Qwen/Qwen2.5-72B-Instruct",
model=MODELS[input_model],
messages=messages,
max_tokens=500
)
output_str = completion.choices[0].message['content']
output_table_data = format_table_data(output_str)
print('Done!')
print('=' * 70)
print('Original MIDI unique records count', output_midi_records_count)
print('Original MIDI dataset', output_midi_src_dataset)
print('Original MIDI path string', data)
print('=' * 70)
print(output_str)
print('=')
#========================================================
output_midi_md5 = str(new_midi_md5hash)
#========================================================
print('Req end time: {:%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now(PDT)))
print('-' * 70)
print('Req execution time:', (time.time() - start_time), 'sec')
print('*' * 70)
#========================================================
return output_midi_md5, output_midi_records_count, output_midi_src_dataset, data, output_table_data
#==========================================================================================================
if __name__ == "__main__":
PDT = timezone('US/Pacific')
print('=' * 70)
print('App start time: {:%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now(PDT)))
print('=' * 70)
print('Loading MIDID database...')
midid_dataset = load_dataset("asigalov61/MIDID")['train']
midid_md5_hashes = midid_dataset['midi_hash']
print('Done!')
print('=' * 70)
print('Loading Monster MIDI titles database...')
monster_midi_titles = TMIDIX.Tegridy_Any_Pickle_File_Reader('Monster_MIDI_Titles_Database_CC_BY_NC_SA.pickle')
print('Done!')
print('=' * 70)
app = gr.Blocks()
with app:
gr.Markdown("<h1 style='text-align: center; margin-bottom: 1rem'>MIDI Identification</h1>")
gr.Markdown("<h1 style='text-align: center; margin-bottom: 1rem'>Identify any MIDI in a comprehensive database of 2.32M+ MIDI records</h1>")
gr.Markdown("This is a demo for tegridy-tools, MIDID and Monster MIDI dataset\n\n"
"Please see [tegridy-tools](https://github.com/asigalov61/tegridy-tools), [MIDID](https://huggingface.co/datasets/asigalov61/MIDID) and [Monster MIDI Dataset](https://github.com/asigalov61/Monster-MIDI-Dataset) repos for more information\n\n"
)
gr.Markdown("## Upload your MIDI")
input_midi = gr.File(label="Input MIDI", file_types=[".midi", ".mid", ".kar"], type="filepath")
input_model = gr.Dropdown(['Mistral Nemo Instruct 2407', 'Mistral Nemo Instruct 2407'],
value='Mistral Nemo Instruct 2407',
label='Select model'
)
submit = gr.Button("Identify MIDI", variant="primary")
gr.Markdown("## MIDI identification results")
output_midi_md5 = gr.Textbox(label="Monster MIDI dataset md5 hash")
output_midi_records_count = gr.Textbox(label="Original MIDI unique records count")
output_midi_src_dataset = gr.Textbox(label="Original MIDI dataset pretty name")
output_midi_path_str = gr.Textbox(label="Original MIDI raw path string")
output_MIDID_results_table = gr.Dataframe(label="MIDID database results table", wrap=True, col_count=(3, 'dynamic'))
run_event = submit.click(ID_MIDI, [input_midi,
input_model
],
[output_midi_md5,
output_midi_records_count,
output_midi_src_dataset,
output_midi_path_str,
output_MIDID_results_table
])
app.queue().launch() |