Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -53,13 +53,14 @@ class MIDIManager:
|
|
| 53 |
self.synthesizer = MidiSynthesizer(self.soundfont_path)
|
| 54 |
self.loaded_midi = {} # midi_id: (file_path, midi_obj)
|
| 55 |
self.modified_files = [] # Stores (midi_base64, audio_base64) tuples
|
|
|
|
| 56 |
self.is_playing = False
|
| 57 |
self.instruments = self.random_instrument_set()
|
| 58 |
self.drum_beat = self.create_drum_beat()
|
| 59 |
self.starter_midi = self.create_starter_midi()
|
| 60 |
-
self.example_files = self.load_example_midis()
|
| 61 |
self.loaded_midi["starter"] = ("Starter MIDI", self.starter_midi)
|
| 62 |
self.preload_default_midi()
|
|
|
|
| 63 |
|
| 64 |
def random_instrument_set(self):
|
| 65 |
instrument_pool = [0, 24, 32, 48] # Piano, Guitar, Bass, Strings
|
|
@@ -69,12 +70,12 @@ class MIDIManager:
|
|
| 69 |
return [(36, 100, 0), (42, 80, 50), (38, 90, 100), (42, 80, 150)] # Kick, hi-hat, snare, hi-hat
|
| 70 |
|
| 71 |
def create_starter_midi(self):
|
| 72 |
-
midi = MIDI.MIDIFile(5)
|
| 73 |
for i, inst in enumerate(self.instruments):
|
| 74 |
midi.addTrack()
|
| 75 |
midi.addProgramChange(i, 0, 0, inst)
|
| 76 |
for t in range(0, 400, 100):
|
| 77 |
-
note = random.randint(60, 84)
|
| 78 |
midi.addNote(i, 0, note, t, 100, 100)
|
| 79 |
midi.addTrack()
|
| 80 |
for note, vel, time in self.drum_beat:
|
|
@@ -97,23 +98,16 @@ class MIDIManager:
|
|
| 97 |
continue
|
| 98 |
midi_id = f"example_{len(examples)}"
|
| 99 |
midi = MIDI.load(file_path)
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
for note, vel, time in notes:
|
| 106 |
-
new_midi.addNote(i, 0, note, time, 100, vel)
|
| 107 |
-
new_midi.addTrack()
|
| 108 |
-
for note, vel, time in self.drum_beat:
|
| 109 |
-
new_midi.addNote(4, 9, note, time, 100, vel)
|
| 110 |
-
examples[midi_id] = (file_path, new_midi)
|
| 111 |
-
self.loaded_midi.update(examples)
|
| 112 |
return examples
|
| 113 |
|
| 114 |
def load_midi(self, file_path):
|
| 115 |
midi = MIDI.load(file_path)
|
| 116 |
-
midi_id = f"midi_{len(self.loaded_midi) - len(self.
|
| 117 |
self.loaded_midi[midi_id] = (file_path, midi)
|
| 118 |
return midi_id
|
| 119 |
|
|
@@ -158,9 +152,8 @@ class MIDIManager:
|
|
| 158 |
with open(temp_midi, 'wb') as f:
|
| 159 |
f.write(midi_output.getvalue())
|
| 160 |
audio_output = io.BytesIO()
|
| 161 |
-
# Placeholder for audio rendering; needs fluidsynth or similar
|
| 162 |
self.synthesizer.play_midi(new_midi)
|
| 163 |
-
audio_data = None #
|
| 164 |
if os.path.exists(temp_midi):
|
| 165 |
os.remove(temp_midi)
|
| 166 |
|
|
@@ -215,6 +208,9 @@ def create_download_list():
|
|
| 215 |
def get_midi_choices():
|
| 216 |
return [(os.path.basename(path), midi_id) for midi_id, (path, _) in midi_processor.loaded_midi.items()]
|
| 217 |
|
|
|
|
|
|
|
|
|
|
| 218 |
if __name__ == "__main__":
|
| 219 |
parser = argparse.ArgumentParser()
|
| 220 |
parser.add_argument("--port", type=int, default=7860)
|
|
@@ -249,20 +245,17 @@ if __name__ == "__main__":
|
|
| 249 |
|
| 250 |
# Tab 2: Examples
|
| 251 |
with gr.Tab("Examples"):
|
| 252 |
-
example_select = gr.Dropdown(label="Select Example", choices=
|
| 253 |
example_output = gr.Audio(label="Example Preview", type="bytes", autoplay=True)
|
| 254 |
|
| 255 |
def load_example(midi_id):
|
| 256 |
-
if not midi_id:
|
| 257 |
return None
|
| 258 |
-
midi_data, audio_data = midi_processor.
|
| 259 |
midi_processor.play_with_loop(midi_data)
|
| 260 |
-
return io.BytesIO(base64.b64decode(midi_data))
|
| 261 |
|
| 262 |
-
example_select.change(load_example, inputs=[example_select],
|
| 263 |
-
outputs=[example_output, "downloads"])
|
| 264 |
-
gr.State(get_midi_choices()).change(lambda choices: gr.update(choices=choices),
|
| 265 |
-
inputs=[gr.State()], outputs=[example_select])
|
| 266 |
|
| 267 |
# Tab 3: Generate & Perform
|
| 268 |
with gr.Tab("Generate & Perform"):
|
|
|
|
| 53 |
self.synthesizer = MidiSynthesizer(self.soundfont_path)
|
| 54 |
self.loaded_midi = {} # midi_id: (file_path, midi_obj)
|
| 55 |
self.modified_files = [] # Stores (midi_base64, audio_base64) tuples
|
| 56 |
+
self.example_variations = {} # midi_id: (midi_base64, audio_base64) for pre-generated examples
|
| 57 |
self.is_playing = False
|
| 58 |
self.instruments = self.random_instrument_set()
|
| 59 |
self.drum_beat = self.create_drum_beat()
|
| 60 |
self.starter_midi = self.create_starter_midi()
|
|
|
|
| 61 |
self.loaded_midi["starter"] = ("Starter MIDI", self.starter_midi)
|
| 62 |
self.preload_default_midi()
|
| 63 |
+
self.load_example_midis() # Pre-generate example variations
|
| 64 |
|
| 65 |
def random_instrument_set(self):
|
| 66 |
instrument_pool = [0, 24, 32, 48] # Piano, Guitar, Bass, Strings
|
|
|
|
| 70 |
return [(36, 100, 0), (42, 80, 50), (38, 90, 100), (42, 80, 150)] # Kick, hi-hat, snare, hi-hat
|
| 71 |
|
| 72 |
def create_starter_midi(self):
|
| 73 |
+
midi = MIDI.MIDIFile(5)
|
| 74 |
for i, inst in enumerate(self.instruments):
|
| 75 |
midi.addTrack()
|
| 76 |
midi.addProgramChange(i, 0, 0, inst)
|
| 77 |
for t in range(0, 400, 100):
|
| 78 |
+
note = random.randint(60, 84)
|
| 79 |
midi.addNote(i, 0, note, t, 100, 100)
|
| 80 |
midi.addTrack()
|
| 81 |
for note, vel, time in self.drum_beat:
|
|
|
|
| 98 |
continue
|
| 99 |
midi_id = f"example_{len(examples)}"
|
| 100 |
midi = MIDI.load(file_path)
|
| 101 |
+
self.loaded_midi[midi_id] = (file_path, midi)
|
| 102 |
+
# Pre-generate variation for each example
|
| 103 |
+
midi_data, audio_data = self.generate_variation(midi_id)
|
| 104 |
+
examples[midi_id] = (midi_data, audio_data)
|
| 105 |
+
self.example_variations = examples
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 106 |
return examples
|
| 107 |
|
| 108 |
def load_midi(self, file_path):
|
| 109 |
midi = MIDI.load(file_path)
|
| 110 |
+
midi_id = f"midi_{len(self.loaded_midi) - len(self.example_variations) - 1}"
|
| 111 |
self.loaded_midi[midi_id] = (file_path, midi)
|
| 112 |
return midi_id
|
| 113 |
|
|
|
|
| 152 |
with open(temp_midi, 'wb') as f:
|
| 153 |
f.write(midi_output.getvalue())
|
| 154 |
audio_output = io.BytesIO()
|
|
|
|
| 155 |
self.synthesizer.play_midi(new_midi)
|
| 156 |
+
audio_data = None # Placeholder; see Notes
|
| 157 |
if os.path.exists(temp_midi):
|
| 158 |
os.remove(temp_midi)
|
| 159 |
|
|
|
|
| 208 |
def get_midi_choices():
|
| 209 |
return [(os.path.basename(path), midi_id) for midi_id, (path, _) in midi_processor.loaded_midi.items()]
|
| 210 |
|
| 211 |
+
def get_example_choices():
|
| 212 |
+
return [(os.path.basename(path), midi_id) for midi_id, (path, _) in midi_processor.loaded_midi.items() if midi_id.startswith("example")]
|
| 213 |
+
|
| 214 |
if __name__ == "__main__":
|
| 215 |
parser = argparse.ArgumentParser()
|
| 216 |
parser.add_argument("--port", type=int, default=7860)
|
|
|
|
| 245 |
|
| 246 |
# Tab 2: Examples
|
| 247 |
with gr.Tab("Examples"):
|
| 248 |
+
example_select = gr.Dropdown(label="Select Example", choices=get_example_choices(), value=None)
|
| 249 |
example_output = gr.Audio(label="Example Preview", type="bytes", autoplay=True)
|
| 250 |
|
| 251 |
def load_example(midi_id):
|
| 252 |
+
if not midi_id or midi_id not in midi_processor.example_variations:
|
| 253 |
return None
|
| 254 |
+
midi_data, audio_data = midi_processor.example_variations[midi_id]
|
| 255 |
midi_processor.play_with_loop(midi_data)
|
| 256 |
+
return io.BytesIO(base64.b64decode(midi_data))
|
| 257 |
|
| 258 |
+
example_select.change(load_example, inputs=[example_select], outputs=[example_output])
|
|
|
|
|
|
|
|
|
|
| 259 |
|
| 260 |
# Tab 3: Generate & Perform
|
| 261 |
with gr.Tab("Generate & Perform"):
|