matthewbarberdev commited on
Commit
7532e43
Ā·
verified Ā·
1 Parent(s): 4b16ae7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +56 -39
app.py CHANGED
@@ -7,14 +7,16 @@ import pretty_midi
7
  import subprocess
8
  import os
9
  from openai import OpenAI
10
- # Audio playback support
11
  try:
12
  import pygame
13
  pygame.mixer.init()
14
- PYGAME_AVAILABLE = True
15
  except Exception as e:
16
- print(f"[WARNING] pygame mixer init failed: {e}")
17
- PYGAME_AVAILABLE = False
 
 
18
 
19
  # === LLM APIs ===
20
  def query_llm(prompt, model_name=None):
@@ -29,7 +31,7 @@ def query_llm(prompt, model_name=None):
29
  api_key=os.environ.get("NEBIUS_API_KEY")
30
  )
31
  response = client.chat.completions.create(
32
- model="meta-llama/Llama-3.3-70B-Instruct",
33
  max_tokens=512,
34
  temperature=0.6,
35
  top_p=0.9,
@@ -115,42 +117,46 @@ def midi_from_plan(melody, tempo):
115
  midi.instruments.append(instrument)
116
  return midi
117
 
118
- # === Generate audio preview from MIDI ===
119
- def midi_to_wav(midi_path):
120
- try:
121
- import tempfile
122
- import subprocess
123
- import os
124
-
125
- # Convert MIDI to WAV using FluidSynth if installed, else fallback to empty
126
- wav_path = tempfile.NamedTemporaryFile(delete=False, suffix=".wav").name
127
-
128
- # Use fluidsynth if available, else skip audio preview
129
- fluidsynth_cmd = ["fluidsynth", "-ni", "/usr/share/sounds/sf2/FluidR3_GM.sf2", midi_path, "-F", wav_path, "-r", "44100"]
130
- result = subprocess.run(fluidsynth_cmd, capture_output=True)
131
- if result.returncode != 0:
132
- print("[WARNING] FluidSynth conversion failed or is not installed.")
133
- return None
134
- return wav_path
135
- except Exception as e:
136
- print(f"[ERROR] midi_to_wav failed: {e}")
137
- return None
138
-
139
- # === Main function to generate MIDI and audio preview ===
140
- def generate_midi_and_audio(prompt, model_name):
141
  intent = get_intent_from_prompt(prompt, model_name)
142
  melody = get_melody_from_intent(intent, model_name)
143
  midi = midi_from_plan(melody, intent.get("tempo", 120))
144
 
145
  with tempfile.NamedTemporaryFile(delete=False, suffix=".mid") as tmp:
146
  midi.write(tmp.name)
147
- midi_path = tmp.name
148
-
149
- audio_path = None
150
- if PYGAME_AVAILABLE:
151
- audio_path = midi_path # We'll use pygame to play midi directly if possible
152
-
153
- return midi_path, audio_path
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
 
155
  # === Get Ollama models ===
156
  def get_ollama_models():
@@ -165,17 +171,28 @@ def get_ollama_models():
165
  models = get_ollama_models()
166
 
167
  demo = gr.Interface(
168
- fn=generate_midi_and_audio,
169
  inputs=[
170
  gr.Textbox(label="Music Prompt"),
171
  gr.Dropdown(choices=models, label="LLM Model", value=models[0])
172
  ],
173
  outputs=[
174
- gr.File(label="šŸŽµ Download MIDI File"),
175
- gr.Audio(label="šŸŽ§ Audio Preview (MIDI Playback, if supported)", type="filepath")
176
  ],
177
  title="šŸŽ¼ Music Command Prompt (MCP Agent)",
178
  description="Describe your music idea and download a generated MIDI file. Choose from local or OpenAI LLMs."
179
  )
180
 
181
- demo.launch(mcp_server=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  import subprocess
8
  import os
9
  from openai import OpenAI
10
+ # Audio support flag
11
  try:
12
  import pygame
13
  pygame.mixer.init()
14
+ AUDIO_AVAILABLE = True
15
  except Exception as e:
16
+ print(f"[WARN] pygame audio init failed: {e}")
17
+ AUDIO_AVAILABLE = False
18
+
19
+ midi_path_global = None
20
 
21
  # === LLM APIs ===
22
  def query_llm(prompt, model_name=None):
 
31
  api_key=os.environ.get("NEBIUS_API_KEY")
32
  )
33
  response = client.chat.completions.create(
34
+ model="Qwen/Qwen3-30B-A3B",
35
  max_tokens=512,
36
  temperature=0.6,
37
  top_p=0.9,
 
117
  midi.instruments.append(instrument)
118
  return midi
119
 
120
+ def generate_midi_from_prompt(prompt, model_name):
121
+ global midi_path_global
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  intent = get_intent_from_prompt(prompt, model_name)
123
  melody = get_melody_from_intent(intent, model_name)
124
  midi = midi_from_plan(melody, intent.get("tempo", 120))
125
 
126
  with tempfile.NamedTemporaryFile(delete=False, suffix=".mid") as tmp:
127
  midi.write(tmp.name)
128
+ midi_path_global = tmp.name
129
+ return midi_path_global
130
+
131
+ def play_audio():
132
+ if not AUDIO_AVAILABLE:
133
+ return "Audio playback not available."
134
+ if midi_path_global is None:
135
+ return "No MIDI file loaded yet."
136
+ try:
137
+ pygame.mixer.music.load(midi_path_global)
138
+ pygame.mixer.music.play()
139
+ return "Playing audio..."
140
+ except Exception as e:
141
+ return f"Error playing audio: {e}"
142
+
143
+ def pause_audio():
144
+ if not AUDIO_AVAILABLE:
145
+ return "Audio playback not available."
146
+ pygame.mixer.music.pause()
147
+ return "Paused."
148
+
149
+ def unpause_audio():
150
+ if not AUDIO_AVAILABLE:
151
+ return "Audio playback not available."
152
+ pygame.mixer.music.unpause()
153
+ return "Unpaused."
154
+
155
+ def stop_audio():
156
+ if not AUDIO_AVAILABLE:
157
+ return "Audio playback not available."
158
+ pygame.mixer.music.stop()
159
+ return "Stopped."
160
 
161
  # === Get Ollama models ===
162
  def get_ollama_models():
 
171
  models = get_ollama_models()
172
 
173
  demo = gr.Interface(
174
+ fn=generate_midi_from_prompt,
175
  inputs=[
176
  gr.Textbox(label="Music Prompt"),
177
  gr.Dropdown(choices=models, label="LLM Model", value=models[0])
178
  ],
179
  outputs=[
180
+ gr.File(label="šŸŽµ Download MIDI File")
 
181
  ],
182
  title="šŸŽ¼ Music Command Prompt (MCP Agent)",
183
  description="Describe your music idea and download a generated MIDI file. Choose from local or OpenAI LLMs."
184
  )
185
 
186
+ with gr.Row():
187
+ with gr.Column(scale=1):
188
+ play_btn = gr.Button("ā–¶ Play")
189
+ pause_btn = gr.Button("āø Pause")
190
+ unpause_btn = gr.Button("ā–¶ Resume")
191
+ stop_btn = gr.Button("ā¹ Stop")
192
+ with gr.Column(scale=3):
193
+ status = gr.Textbox(label="Audio Status", interactive=False)
194
+
195
+ play_btn.click(play_audio, None, status)
196
+ pause_btn.click(pause_audio, None, status)
197
+ unpause_btn.click(unpause_audio, None, status)
198
+ stop_btn.click(stop_audio, None, status)