PC から外部のシンセサイザーや音源モジュールを制御するために MIDI 信号を送信します。
1. 依存関係の追加
src-tauri ディレクトリで以下のコマンドを実行します。
cargo add midir
2. 実装コード
use midir::{MidiOutput, MidiOutputConnection};
use std::sync::Mutex;
use tauri::State;
struct MidiOutState {
conn: Mutex<Option<MidiOutputConnection>>,
}
#[tauri::command]
fn open_midi_out(state: State<MidiOutState>, port_index: usize) -> Result<String, String> {
let midi_out = MidiOutput::new("My MIDI Output").map_err(|e| e.to_string())?;
let ports = midi_out.ports();
let port = ports.get(port_index).ok_or("Invalid port index")?;
let port_name = midi_out.port_name(port).unwrap_or_default();
let conn_out = midi_out.connect(port, "tauri-midi-output").map_err(|e| e.to_string())?;
*state.conn.lock().unwrap() = Some(conn_out);
Ok(format!("Opened {}", port_name))
}
#[tauri::command]
fn send_midi_note(state: State<MidiOutState>, note: u8, velocity: u8) -> Result<(), String> {
let mut guard = state.conn.lock().unwrap();
if let Some(conn) = guard.as_mut() {
// Note On メッセージ (Channel 1)
// [Status Byte (0x90 = Note On, Ch1), Note Number, Velocity]
const NOTE_ON: u8 = 0x90;
conn.send(&[NOTE_ON, note, velocity]).map_err(|e| e.to_string())?;
Ok(())
} else {
Err("Port not open".to_string())
}
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.manage(MidiOutState {
conn: Mutex::new(None),
})
.invoke_handler(tauri::generate_handler![open_midi_out, send_midi_note])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
3. 注意点
- Windows では一部の MIDI ポートが「排他モード」でしか開けない場合があり、他のアプリ(DAWなど)が使用中だと接続に失敗することがあります。
- 仮想 MIDI ポート(loopBe1など)を使えば、同じPC内の DAW に対して MIDI を送ることが可能です。