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)
}],
[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| {

View file

@ -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: 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> {
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])

View file

@ -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<MutexGuard<Box<dyn Device>>> {
self.devices.get(i).map(|d|d.state.lock().unwrap())