multimodalart HF Staff commited on
Commit
1e4533e
·
verified ·
1 Parent(s): 360cb36

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +45 -6
app.py CHANGED
@@ -8,6 +8,7 @@ import sys
8
  import io
9
  import json
10
  import re
 
11
  from pathlib import Path
12
 
13
  from safetensors.torch import load_file
@@ -89,8 +90,40 @@ INSTRUMENT_CHOICES = sorted(MT3_FULL_PLUS_GROUP_NAMES.keys(), key=lambda k: MT3_
89
  CSS = """
90
  #col-container { max-width: 1100px; margin: 0 auto; }
91
  .dark .gradio-container { color: var(--body-text-color); }
 
 
92
  """
93
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
 
95
  @spaces.GPU(duration=120)
96
  def transcribe_audio(
@@ -115,7 +148,7 @@ def transcribe_audio(
115
  temperature: Sampling temperature (only used when use_sampling is True).
116
  """
117
  if audio_path is None:
118
- return None, "Please upload an audio file first."
119
 
120
  t0 = time.perf_counter()
121
 
@@ -128,7 +161,7 @@ def transcribe_audio(
128
  temperature=temperature,
129
  )
130
  except Exception as e:
131
- return None, f"Transcription failed: {e}"
132
 
133
  elapsed = time.perf_counter() - t0
134
 
@@ -154,10 +187,12 @@ def transcribe_audio(
154
  summary = (
155
  f"Transcription complete in {elapsed:.1f}s. "
156
  f"Found {note_count} notes across {len(instrument_set)} instrument program(s). "
157
- f"Download the MIDI file below."
158
  )
159
 
160
- return tmp.name, summary
 
 
161
 
162
 
163
  with gr.Blocks() as demo:
@@ -204,13 +239,14 @@ with gr.Blocks() as demo:
204
 
205
  transcribe_btn = gr.Button("Transcribe", variant="primary")
206
 
 
207
  midi_output = gr.File(label="Download MIDI file")
208
  summary_output = gr.Textbox(label="Summary", interactive=False)
209
 
210
  transcribe_btn.click(
211
  fn=transcribe_audio,
212
  inputs=[audio_input, instrument_checkbox, use_sampling, temperature],
213
- outputs=[midi_output, summary_output],
214
  api_name="transcribe",
215
  )
216
 
@@ -218,9 +254,12 @@ with gr.Blocks() as demo:
218
  examples=[
219
  ["example_piano.wav", [], False, 1.0],
220
  ["example_melody.wav", [], False, 1.0],
 
 
 
221
  ],
222
  inputs=[audio_input, instrument_checkbox, use_sampling, temperature],
223
- outputs=[midi_output, summary_output],
224
  fn=transcribe_audio,
225
  cache_examples=True,
226
  cache_mode="lazy",
 
8
  import io
9
  import json
10
  import re
11
+ import base64
12
  from pathlib import Path
13
 
14
  from safetensors.torch import load_file
 
90
  CSS = """
91
  #col-container { max-width: 1100px; margin: 0 auto; }
92
  .dark .gradio-container { color: var(--body-text-color); }
93
+ midi-player { width: 100%; display: block; margin-bottom: 8px; }
94
+ midi-visualizer { width: 100%; display: block; overflow: auto; }
95
  """
96
 
97
+ # Loads the html-midi-player web components (<midi-player> / <midi-visualizer>)
98
+ # from Magenta.js + Tone.js via jsDelivr. Injected once alongside the player.
99
+ _MIDI_PLAYER_SCRIPT = (
100
+ '<script src="https://cdn.jsdelivr.net/combine/'
101
+ "npm/tone@14.7.58,"
102
+ "npm/@magenta/music@1.23.1/es6/core.js,"
103
+ 'npm/html-midi-player@1.5.0"></script>'
104
+ )
105
+
106
+
107
+ def _midi_player_html(midi_bytes: bytes | None) -> str:
108
+ """Build an HTML snippet that visualizes and plays back a MIDI file.
109
+
110
+ The MIDI data is embedded directly as a base64 data URI so it needs no
111
+ separate file-serving route. Uses the html-midi-player web components
112
+ (Magenta.js <midi-player> / <midi-visualizer>).
113
+ """
114
+ if not midi_bytes:
115
+ return ""
116
+ b64 = base64.b64encode(midi_bytes).decode("ascii")
117
+ src = f"data:audio/midi;base64,{b64}"
118
+ return (
119
+ f"{_MIDI_PLAYER_SCRIPT}"
120
+ '<div class="midi-player-container">'
121
+ f'<midi-player src="{src}" sound-font '
122
+ 'visualizer=".midi-visualizer"></midi-player>'
123
+ '<midi-visualizer class="midi-visualizer" type="piano-roll"></midi-visualizer>'
124
+ "</div>"
125
+ )
126
+
127
 
128
  @spaces.GPU(duration=120)
129
  def transcribe_audio(
 
148
  temperature: Sampling temperature (only used when use_sampling is True).
149
  """
150
  if audio_path is None:
151
+ return None, "Please upload an audio file first.", ""
152
 
153
  t0 = time.perf_counter()
154
 
 
161
  temperature=temperature,
162
  )
163
  except Exception as e:
164
+ return None, f"Transcription failed: {e}", ""
165
 
166
  elapsed = time.perf_counter() - t0
167
 
 
187
  summary = (
188
  f"Transcription complete in {elapsed:.1f}s. "
189
  f"Found {note_count} notes across {len(instrument_set)} instrument program(s). "
190
+ f"Play it back below or download the MIDI file."
191
  )
192
 
193
+ player_html = _midi_player_html(midi_bytes)
194
+
195
+ return tmp.name, summary, player_html
196
 
197
 
198
  with gr.Blocks() as demo:
 
239
 
240
  transcribe_btn = gr.Button("Transcribe", variant="primary")
241
 
242
+ midi_player = gr.HTML(label="MIDI playback & visualization")
243
  midi_output = gr.File(label="Download MIDI file")
244
  summary_output = gr.Textbox(label="Summary", interactive=False)
245
 
246
  transcribe_btn.click(
247
  fn=transcribe_audio,
248
  inputs=[audio_input, instrument_checkbox, use_sampling, temperature],
249
+ outputs=[midi_output, summary_output, midi_player],
250
  api_name="transcribe",
251
  )
252
 
 
254
  examples=[
255
  ["example_piano.wav", [], False, 1.0],
256
  ["example_melody.wav", [], False, 1.0],
257
+ ["example_medicine.mp3", [], False, 1.0],
258
+ ["example_organic_flow.mp3", [], False, 1.0],
259
+ ["example_water_afro_pop.mp3", [], False, 1.0],
260
  ],
261
  inputs=[audio_input, instrument_checkbox, use_sampling, temperature],
262
+ outputs=[midi_output, summary_output, midi_player],
263
  fn=transcribe_audio,
264
  cache_examples=True,
265
  cache_mode="lazy",