callback api for tracks and devices

This commit is contained in:
🪞👃🪞 2024-07-04 20:46:31 +03:00
parent f2774e67a6
commit f928b026ed
3 changed files with 62 additions and 37 deletions

View file

@ -51,7 +51,7 @@ const KEYMAP: &'static [KeyBinding<App>] = keymap!(App {
Ok(true) Ok(true)
}], }],
[Char('t'), CONTROL, "add_track", "add a new track", |app: &mut App| { [Char('t'), CONTROL, "add_track", "add a new track", |app: &mut App| {
app.add_track(None, None)?; app.add_track(None)?;
Ok(true) Ok(true)
}], }],
[Char('`'), NONE, "switch_mode", "switch the display mode", |app: &mut App| { [Char('`'), NONE, "switch_mode", "switch the display mode", |app: &mut App| {

View file

@ -45,40 +45,47 @@ pub fn main () -> Usually<()> {
state.midi_in = Some(client.register_port("midi-in", MidiIn)?); state.midi_in = Some(client.register_port("midi-in", MidiIn)?);
state.jack = Some(jack); state.jack = Some(jack);
state.add_track(Some("Drums"), Some(Box::new(move|client, track|{ state.add_track_with_cb(Some("Drums"), |client: &Client, track: &mut Track|{
track.add_device(Sampler::new("Sampler", Some(BTreeMap::from([
track.add_device_with_cb(Sampler::new("Sampler", Some(BTreeMap::from([
sample!(36, "Kick", "/home/user/Lab/Music/pak/kik.wav"), sample!(36, "Kick", "/home/user/Lab/Music/pak/kik.wav"),
sample!(40, "Snare", "/home/user/Lab/Music/pak/sna.wav"), sample!(40, "Snare", "/home/user/Lab/Music/pak/sna.wav"),
sample!(44, "Hihat", "/home/user/Lab/Music/pak/chh.wav"), sample!(44, "Hihat", "/home/user/Lab/Music/pak/chh.wav"),
])))?); ])))?, |track: &Track, device: &mut JackDevice|{
track.add_device(Plugin::lv2( client.connect_ports(
&track.midi_out, &device.midi_ins()?[0]
)?;
Ok(())
})?;
track.add_device_with_cb(Plugin::lv2(
"Panagement", "Panagement",
"file:///home/user/.lv2/Auburn Sounds Panagement 2.lv2" "file:///home/user/.lv2/Auburn Sounds Panagement 2.lv2"
)?); )?, |track: &Track, device: &mut JackDevice|{
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() {
client.connect_ports( client.connect_ports(
&track.devices[1].audio_outs()?[0], &output_left &track.devices[0].audio_outs()?[0], &device.audio_ins()?[0]
)?; )?;
} let output_left = client
let output_right = client.ports(Some("Komplete.+:playback_FR"), None, PortFlags::empty()); .ports(Some("Komplete.+:playback_FL"), None, PortFlags::empty())
if let Some( .get(0)
output_right .map(|name|client.port_by_name(&name))
) = output_right.get(0).map(|name|client.port_by_name(&name)).flatten() { .flatten();
client.connect_ports( if let Some(output_left) = output_left {
&track.devices[1].audio_outs()?[0], &output_right 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.sequence = Some(1); // FIXME
track.add_phrase("4 kicks", ppq * 4, Some(phrase! { track.add_phrase("4 kicks", ppq * 4, Some(phrase! {
00 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }, 00 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() },
04 * 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() }, 12 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() },
})); }));
Ok(()) Ok(())
})))?; })?;
state.add_track(Some("Bass"), Some(Box::new(move|client, track|{ 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.add_device(Plugin::lv2("Odin2", "file:///home/user/.lv2/Odin2.lv2")?)?;
track.sequence = Some(0); // FIXME track.sequence = Some(0); // FIXME
//client.connect_ports(&track.midi_out, &track.devices[0].midi_ins()?[0])?; //client.connect_ports(&track.midi_out, &track.devices[0].midi_ins()?[0])?;
//let output_left = client.ports(Some(".+:playback_FL"), None, PortFlags::empty()); //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() }, 14 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() },
})); }));
Ok(()) Ok(())
})))?; })?;
Ok(()) Ok(())
})) }))
@ -244,13 +251,20 @@ impl App {
pub fn add_track ( pub fn add_track (
&mut self, &mut self,
name: Option<&str>, name: Option<&str>,
init: Option<Box<dyn FnOnce(&Client, &mut Track)->Usually<()>>>, ) -> 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> { ) -> Usually<&mut Track> {
let name = name.ok_or_else(||format!("Track {}", self.tracks.len() + 1))?; let name = name.ok_or_else(||format!("Track {}", self.tracks.len() + 1))?;
let mut track = Track::new(&name, self.client(), None, None)?; 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.tracks.push(track);
self.track_cursor = self.tracks.len(); self.track_cursor = self.tracks.len();
Ok(&mut self.tracks[self.track_cursor - 1]) Ok(&mut self.tracks[self.track_cursor - 1])

View file

@ -121,11 +121,22 @@ impl Track {
write_midi_output(&mut self.midi_out.writer(scope), &output, frames); write_midi_output(&mut self.midi_out.writer(scope), &output, frames);
} }
pub fn add_device ( pub fn add_device (
&mut self, device: JackDevice &mut self,
) -> &mut JackDevice { mut device: JackDevice,
) -> Usually<&mut JackDevice> {
self.devices.push(device); self.devices.push(device);
let index = self.devices.len() - 1; 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<MutexGuard<Box<dyn Device>>> { pub fn get_device (&self, i: usize) -> Option<MutexGuard<Box<dyn Device>>> {
self.devices.get(i).map(|d|d.state.lock().unwrap()) self.devices.get(i).map(|d|d.state.lock().unwrap())