Feat: improving MIDI

This commit is contained in:
2026-02-15 19:06:49 +01:00
parent 160546d64d
commit b23dd85d0f
6 changed files with 304 additions and 98 deletions

View File

@@ -1180,10 +1180,12 @@ fn sequencer_loop(
// Route commands: audio direct to doux, MIDI through dispatcher
for tsc in output.audio_commands {
if let Some((midi_cmd, dur)) = parse_midi_command(&tsc.cmd) {
if let Some((midi_cmd, dur, delta_secs)) = parse_midi_command(&tsc.cmd) {
let target_time_us =
current_time_us + (delta_secs * 1_000_000.0) as SyncTime;
let _ = dispatch_tx.send(TimedMidiCommand {
command: MidiDispatch::Send(midi_cmd.clone()),
target_time_us: current_time_us,
target_time_us,
});
if let (
@@ -1196,7 +1198,7 @@ fn sequencer_loop(
Some(dur_secs),
) = (&midi_cmd, dur)
{
let off_time_us = current_time_us + (dur_secs * 1_000_000.0) as SyncTime;
let off_time_us = target_time_us + (dur_secs * 1_000_000.0) as SyncTime;
let _ = dispatch_tx.send(TimedMidiCommand {
command: MidiDispatch::Send(MidiCommand::NoteOff {
device: *device,
@@ -1229,7 +1231,7 @@ fn sequencer_loop(
}
}
fn parse_midi_command(cmd: &str) -> Option<(MidiCommand, Option<f64>)> {
fn parse_midi_command(cmd: &str) -> Option<(MidiCommand, Option<f64>, f64)> {
if !cmd.starts_with("/midi/") {
return None;
}
@@ -1254,10 +1256,10 @@ fn parse_midi_command(cmd: &str) -> Option<(MidiCommand, Option<f64>)> {
};
let device: u8 = find_param("dev").and_then(|s| s.parse().ok()).unwrap_or(0);
let delta: f64 = find_param("delta").and_then(|s| s.parse().ok()).unwrap_or(0.0);
match parts[1] {
"note" => {
// /midi/note/<note>/vel/<vel>/chan/<chan>/dur/<dur>/dev/<dev>
let note: u8 = parts.get(2)?.parse().ok()?;
let vel: u8 = find_param("vel")?.parse().ok()?;
let chan: u8 = find_param("chan")?.parse().ok()?;
@@ -1270,10 +1272,10 @@ fn parse_midi_command(cmd: &str) -> Option<(MidiCommand, Option<f64>)> {
velocity: vel,
},
dur,
delta,
))
}
"cc" => {
// /midi/cc/<cc>/<val>/chan/<chan>/dev/<dev>
let cc: u8 = parts.get(2)?.parse().ok()?;
let val: u8 = parts.get(3)?.parse().ok()?;
let chan: u8 = find_param("chan")?.parse().ok()?;
@@ -1285,10 +1287,10 @@ fn parse_midi_command(cmd: &str) -> Option<(MidiCommand, Option<f64>)> {
value: val,
},
None,
delta,
))
}
"bend" => {
// /midi/bend/<value>/chan/<chan>/dev/<dev>
let value: u16 = parts.get(2)?.parse().ok()?;
let chan: u8 = find_param("chan")?.parse().ok()?;
Some((
@@ -1298,10 +1300,10 @@ fn parse_midi_command(cmd: &str) -> Option<(MidiCommand, Option<f64>)> {
value,
},
None,
delta,
))
}
"pressure" => {
// /midi/pressure/<value>/chan/<chan>/dev/<dev>
let value: u8 = parts.get(2)?.parse().ok()?;
let chan: u8 = find_param("chan")?.parse().ok()?;
Some((
@@ -1311,10 +1313,10 @@ fn parse_midi_command(cmd: &str) -> Option<(MidiCommand, Option<f64>)> {
value,
},
None,
delta,
))
}
"program" => {
// /midi/program/<value>/chan/<chan>/dev/<dev>
let program: u8 = parts.get(2)?.parse().ok()?;
let chan: u8 = find_param("chan")?.parse().ok()?;
Some((
@@ -1324,12 +1326,13 @@ fn parse_midi_command(cmd: &str) -> Option<(MidiCommand, Option<f64>)> {
program,
},
None,
delta,
))
}
"clock" => Some((MidiCommand::Clock { device }, None)),
"start" => Some((MidiCommand::Start { device }, None)),
"stop" => Some((MidiCommand::Stop { device }, None)),
"continue" => Some((MidiCommand::Continue { device }, None)),
"clock" => Some((MidiCommand::Clock { device }, None, delta)),
"start" => Some((MidiCommand::Start { device }, None, delta)),
"stop" => Some((MidiCommand::Stop { device }, None, delta)),
"continue" => Some((MidiCommand::Continue { device }, None, delta)),
_ => None,
}
}