hayaton0005 commited on
Commit
d4b96ca
·
verified ·
1 Parent(s): 025a8c9

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +23 -37
  2. replay.html +58 -0
app.py CHANGED
@@ -1,46 +1,32 @@
1
  import gradio as gr
2
  import os
3
- import subprocess
4
  from infer import infer_midi_from_wav
5
 
6
  BASE_DIR = os.path.dirname(os.path.abspath(__file__))
7
 
8
- # MIDI → WAV 変換関数(fluidsynth使用)
9
- def convert_midi_to_wav(midi_path):
10
- soundfont_path = os.path.join(BASE_DIR, "soundfont.sf2") # SoundFontファイルが必要
11
- wav_path = os.path.join(BASE_DIR, "synth_output.wav")
12
-
13
- command = [
14
- "fluidsynth",
15
- "-ni",
16
- soundfont_path,
17
- midi_path,
18
- "-F",
19
- wav_path,
20
- "-r",
21
- "44100"
22
- ]
23
- result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
24
- if result.returncode != 0:
25
- raise RuntimeError("fluidsynth conversion failed:\n" + result.stderr.decode())
26
- return wav_path
27
-
28
- # 推論関数
29
- def transcribe_and_play(audio_path):
30
  midi_path = infer_midi_from_wav(audio_path)
31
- wav_output_path = convert_midi_to_wav(midi_path)
32
- return wav_output_path, midi_path
 
 
33
 
34
  # Gradio インターフェース
35
- interface = gr.Interface(
36
- fn=transcribe_and_play,
37
- inputs=gr.Audio(type="filepath", label="音声録音(マイク入力)", interactive=True), # ✅ 最新仕様
38
- outputs=[
39
- gr.Audio(label="ピアノ音で再生"),
40
- gr.File(label="MIDIダウンロード")
41
- ],
42
- title="鼻歌からのMIDI変換デモ",
43
- description="録音した音声をMIDIに変換し、ピアノ音で再生します。"
44
- )
45
-
46
- interface.launch()
 
 
 
 
 
 
1
  import gradio as gr
2
  import os
 
3
  from infer import infer_midi_from_wav
4
 
5
  BASE_DIR = os.path.dirname(os.path.abspath(__file__))
6
 
7
+ # 推論関数(MIDI生成のみ)
8
+ def transcribe(audio_path):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  midi_path = infer_midi_from_wav(audio_path)
10
+ return midi_path
11
+
12
+ # HTML再生用(replay.htmlを読み込む)
13
+ replay_html = open(os.path.join(BASE_DIR, "replay.html")).read()
14
 
15
  # Gradio インターフェース
16
+ with gr.Blocks() as demo:
17
+ gr.Markdown("## 鼻歌からのMIDI変換デモ")
18
+ gr.Markdown("録音した音声をMIDIに変換し、ブラウザで再生できます。")
19
+
20
+ with gr.Row():
21
+ audio_input = gr.Audio(type="filepath", label="マイク録音")
22
+ midi_output = gr.File(label="変換されたMIDI")
23
+
24
+ run_btn = gr.Button("▶️ 変換")
25
+
26
+ # MIDI変換ボタンを押すとMIDIファイルを出力
27
+ run_btn.click(fn=transcribe, inputs=audio_input, outputs=midi_output)
28
+
29
+ # HTMLによるMIDI再生UI
30
+ gr.HTML(replay_html)
31
+
32
+ demo.launch()
replay.html ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>MIDI Player</title>
5
+ </head>
6
+ <body>
7
+ <h3>MIDIファイルをブラウザで再生</h3>
8
+ <input type="file" id="midi-upload" accept=".mid"/>
9
+ <br/><br/>
10
+ <button onclick="playMIDI()">▶️ 再生</button>
11
+ <button onclick="stopMIDI()">⏹ 停止</button>
12
+ <p id="status"></p>
13
+
14
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/MIDI.min.js"></script>
15
+ <script>
16
+ let isLoaded = false;
17
+
18
+ MIDI.loadPlugin({
19
+ soundfontUrl: "https://gleitz.github.io/midi-js-soundfonts/FluidR3_GM/",
20
+ instrument: "acoustic_grand_piano",
21
+ onsuccess: function() {
22
+ isLoaded = true;
23
+ document.getElementById("status").innerText = "✅ サウンドフォント読み込み完了";
24
+ }
25
+ });
26
+
27
+ function playMIDI() {
28
+ if (!isLoaded) {
29
+ alert("サウンドフォント読み込み中です。少し待ってから再度お試しください。");
30
+ return;
31
+ }
32
+
33
+ const fileInput = document.getElementById("midi-upload");
34
+ const file = fileInput.files[0];
35
+
36
+ if (!file) {
37
+ alert("MIDIファイルを選択してください。");
38
+ return;
39
+ }
40
+
41
+ const reader = new FileReader();
42
+ reader.onload = function(e) {
43
+ const base64data = e.target.result.split(',')[1];
44
+ MIDI.Player.loadFile("data:audio/midi;base64," + base64data, () => {
45
+ MIDI.Player.start();
46
+ document.getElementById("status").innerText = "🎵 再生中...";
47
+ });
48
+ };
49
+ reader.readAsDataURL(file);
50
+ }
51
+
52
+ function stopMIDI() {
53
+ MIDI.Player.stop();
54
+ document.getElementById("status").innerText = "⏹ 停止しました";
55
+ }
56
+ </script>
57
+ </body>
58
+ </html>