hexachords / second_version.py
pachet's picture
Update app.py and add second_version.py
07f2491
import gradio as gr
import mido
from mido import Message, MidiFile, MidiTrack
import numpy as np
import os
import matplotlib.pyplot as plt
def generate_chords(hexachord):
# Placeholder for your actual chord generation function
# Assuming hexachord is a list of MIDI note numbers
chords = []
for i in range(4): # Generate 4 chords
chords.append([note + (i * 2) for note in hexachord]) # Simple transposition
return chords
def create_midi(chords):
mid = MidiFile()
track = MidiTrack()
mid.tracks.append(track)
for chord in chords:
for note in chord:
track.append(Message('note_on', note=int(note), velocity=64, time=0))
for note in chord:
track.append(Message('note_off', note=int(note), velocity=64, time=480))
midi_path = "output.mid"
mid.save(midi_path)
return midi_path
def generate_piano_roll(chords):
fig, ax = plt.subplots(figsize=(8, 4))
for i, chord in enumerate(chords):
for note in chord:
ax.broken_barh([(i * 1, 0.8)], (note - 0.4, 0.8), facecolors='blue')
ax.set_xlabel("Chord Progression")
ax.set_ylabel("MIDI Note Number")
ax.set_yticks(range(min(min(chords)), max(max(chords)) + 1, 2))
ax.set_xticks(range(len(chords)))
ax.set_xticklabels([f"Chord {i + 1}" for i in range(len(chords))])
ax.invert_yaxis()
plt.grid(True, linestyle='--', alpha=0.5)
plt.savefig("piano_roll.png")
return "piano_roll.png"
def process_hexachord(note1, note2, note3, note4, note5, note6):
notes = [note1, note2, note3, note4, note5, note6]
notes = [int(note) for note in notes if note is not None] # Convert to int, remove None values
if len(notes) != 6 or len(set(notes)) != 6:
return "Please select exactly 6 unique notes."
chords = generate_chords(notes)
midi_path = create_midi(chords)
piano_roll_path = generate_piano_roll(chords)
return midi_path, piano_roll_path
# UI Components
note_options = list(range(21, 109)) # MIDI note numbers
default_notes = [60, 62, 64, 65, 67, 69] # Default MIDI notes for C major hexachord
with gr.Blocks() as ui:
gr.Markdown("# Hexachord-based Chord Generator")
with gr.Row():
note_inputs = [gr.Dropdown(choices=note_options, label=f"Note {i + 1}", value=default_notes[i]) for i in
range(6)]
generate_button = gr.Button("Generate Chords")
midi_output = gr.File(label="Generated MIDI")
piano_roll_output = gr.Image(label="Piano Roll Visualization")
generate_button.click(
fn=process_hexachord,
inputs=note_inputs,
outputs=[midi_output, piano_roll_output]
)
# Detect if running on Hugging Face Spaces
on_huggingface = "HUGGINGFACE_SPACE" in os.environ
def launch_app():
if on_huggingface:
ui.launch(server_name="0.0.0.0", server_port=7860)
else:
ui.launch()
launch_app()