Load a SoundFont (.sf2) for realistic instruments, otherwise uses synthesis.
"""
# Define the Gradio Interface
with gr.Blocks(title="MIDI Player & Visualizer") as demo:
gr.Markdown("# 🎹 MIDI Player & Visualizer")
gr.Markdown("Upload a MIDI file to play. Optionally upload a SoundFont (.sf2) for improved synthesis logic (simulated here).")
with gr.Row():
with gr.Column():
midi_input = gr.File(label="Upload MIDI (.mid)", file_types=[".mid", ".midi"])
sf2_input = gr.File(label="Upload SoundFont (.sf2) [Optional]", file_types=[".sf2"])
with gr.Column():
# The HTML component renders our visualizer and controls
gr.HTML(html_template)
#
def process_midi(file):
if file is None: return None
with open(file, "rb") as f:
return base64.b64encode(f.read()).decode("utf-8")
def process_sf2(file):
if file is None: return None
with open(file, "rb") as f:
return base64.b64encode(f.read()).decode("utf-8")
# We use hidden components to transfer data
midi_b64 = gr.Textbox(visible=False)
sf2_b64 = gr.Textbox(visible=False)
# Logic flow:
# Upload -> Process Function -> Hidden Textbox -> JS Change Event
midi_input.upload(process_midi, midi_input, midi_b64)
sf2_input.upload(process_sf2, sf2_input, sf2_b64)
# JS to handle the base64 data from the hidden textboxes
# We append this script to the main HTML to listen to Gradio events
js_handler = """
"""
# Append the handler script
demo.load(None, None, None, js=js_handler)
if __name__ == "__main__":
demo.launch(css=css)