From f928b026edb94df86072ccd71d4dad3f6ce911a9 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Thu, 4 Jul 2024 20:46:31 +0300 Subject: [PATCH] callback api for tracks and devices --- src/control.rs | 2 +- src/main.rs | 80 +++++++++++++++++++++++++++------------------- src/model/track.rs | 17 ++++++++-- 3 files changed, 62 insertions(+), 37 deletions(-) diff --git a/src/control.rs b/src/control.rs index bfe8d834..98b6734e 100644 --- a/src/control.rs +++ b/src/control.rs @@ -51,7 +51,7 @@ const KEYMAP: &'static [KeyBinding] = keymap!(App { Ok(true) }], [Char('t'), CONTROL, "add_track", "add a new track", |app: &mut App| { - app.add_track(None, None)?; + app.add_track(None)?; Ok(true) }], [Char('`'), NONE, "switch_mode", "switch the display mode", |app: &mut App| { diff --git a/src/main.rs b/src/main.rs index 30a39800..0ced8af7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -45,40 +45,47 @@ pub fn main () -> Usually<()> { state.midi_in = Some(client.register_port("midi-in", MidiIn)?); state.jack = Some(jack); - state.add_track(Some("Drums"), Some(Box::new(move|client, track|{ - track.add_device(Sampler::new("Sampler", Some(BTreeMap::from([ + state.add_track_with_cb(Some("Drums"), |client: &Client, track: &mut Track|{ + + track.add_device_with_cb(Sampler::new("Sampler", Some(BTreeMap::from([ sample!(36, "Kick", "/home/user/Lab/Music/pak/kik.wav"), sample!(40, "Snare", "/home/user/Lab/Music/pak/sna.wav"), sample!(44, "Hihat", "/home/user/Lab/Music/pak/chh.wav"), - ])))?); - track.add_device(Plugin::lv2( + ])))?, |track: &Track, device: &mut JackDevice|{ + client.connect_ports( + &track.midi_out, &device.midi_ins()?[0] + )?; + Ok(()) + })?; + + track.add_device_with_cb(Plugin::lv2( "Panagement", "file:///home/user/.lv2/Auburn Sounds Panagement 2.lv2" - )?); - client.connect_ports( - &track.midi_out, &track.devices[0].midi_ins()?[0] - )?; - client.connect_ports( - &track.devices[0].audio_outs()?[0], &track.devices[1].audio_ins()?[0] - )?; - let output_left = client.ports(Some("Komplete.+:playback_FL"), None, PortFlags::empty()); - if let Some( - output_left - ) = output_left.get(0).map(|name|client.port_by_name(&name)).flatten() { + )?, |track: &Track, device: &mut JackDevice|{ client.connect_ports( - &track.devices[1].audio_outs()?[0], &output_left + &track.devices[0].audio_outs()?[0], &device.audio_ins()?[0] )?; - } - let output_right = client.ports(Some("Komplete.+:playback_FR"), None, PortFlags::empty()); - if let Some( - output_right - ) = output_right.get(0).map(|name|client.port_by_name(&name)).flatten() { - client.connect_ports( - &track.devices[1].audio_outs()?[0], &output_right - )?; - } + let output_left = client + .ports(Some("Komplete.+:playback_FL"), None, PortFlags::empty()) + .get(0) + .map(|name|client.port_by_name(&name)) + .flatten(); + if let Some(output_left) = output_left { + client.connect_ports(&device.audio_outs()?[0], &output_left)?; + } + let output_right = client + .ports(Some("Komplete.+:playback_FR"), None, PortFlags::empty()) + .get(0) + .map(|name|client.port_by_name(&name)) + .flatten(); + if let Some(output_right) = output_right { + client.connect_ports(&device.audio_outs()?[0], &output_right)?; + } + Ok(()) + })?; track.sequence = Some(1); // FIXME + track.add_phrase("4 kicks", ppq * 4, Some(phrase! { 00 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }, 04 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }, @@ -99,10 +106,10 @@ pub fn main () -> Usually<()> { 12 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() }, })); Ok(()) - })))?; + })?; - state.add_track(Some("Bass"), Some(Box::new(move|client, track|{ - track.add_device(Plugin::lv2("Odin2", "file:///home/user/.lv2/Odin2.lv2")?); + state.add_track_with_cb(Some("Bass"), |_client: &Client, track: &mut Track|{ + track.add_device(Plugin::lv2("Odin2", "file:///home/user/.lv2/Odin2.lv2")?)?; track.sequence = Some(0); // FIXME //client.connect_ports(&track.midi_out, &track.devices[0].midi_ins()?[0])?; //let output_left = client.ports(Some(".+:playback_FL"), None, PortFlags::empty()); @@ -132,7 +139,7 @@ pub fn main () -> Usually<()> { 14 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() }, })); Ok(()) - })))?; + })?; Ok(()) })) @@ -244,13 +251,20 @@ impl App { pub fn add_track ( &mut self, name: Option<&str>, - init: OptionUsually<()>>>, + ) -> Usually<&mut Track> { + let name = name.ok_or_else(||format!("Track {}", self.tracks.len() + 1))?; + self.tracks.push(Track::new(&name, self.client(), None, None)?); + self.track_cursor = self.tracks.len(); + Ok(&mut self.tracks[self.track_cursor - 1]) + } + pub fn add_track_with_cb ( + &mut self, + name: Option<&str>, + init: impl Fn(&Client, &mut Track)->Usually<()>, ) -> Usually<&mut Track> { let name = name.ok_or_else(||format!("Track {}", self.tracks.len() + 1))?; let mut track = Track::new(&name, self.client(), None, None)?; - if let Some(init) = init { - init(self.client(), &mut track)?; - } + init(self.client(), &mut track)?; self.tracks.push(track); self.track_cursor = self.tracks.len(); Ok(&mut self.tracks[self.track_cursor - 1]) diff --git a/src/model/track.rs b/src/model/track.rs index 7573c5e4..da7bdc1c 100644 --- a/src/model/track.rs +++ b/src/model/track.rs @@ -121,11 +121,22 @@ impl Track { write_midi_output(&mut self.midi_out.writer(scope), &output, frames); } pub fn add_device ( - &mut self, device: JackDevice - ) -> &mut JackDevice { + &mut self, + mut device: JackDevice, + ) -> Usually<&mut JackDevice> { self.devices.push(device); let index = self.devices.len() - 1; - &mut self.devices[index] + Ok(&mut self.devices[index]) + } + pub fn add_device_with_cb ( + &mut self, + mut device: JackDevice, + init: impl Fn(&Self, &mut JackDevice)->Usually<()> + ) -> Usually<&mut JackDevice> { + init(&self, &mut device)?; + self.devices.push(device); + let index = self.devices.len() - 1; + Ok(&mut self.devices[index]) } pub fn get_device (&self, i: usize) -> Option>> { self.devices.get(i).map(|d|d.state.lock().unwrap())