From c7047327d56c4fffa2c66aa79deb208c402a8272 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Thu, 4 Jul 2024 19:40:15 +0300 Subject: [PATCH] track init callback --- src/control.rs | 2 +- src/main.rs | 125 ++++++++++++++++++++++++++++--------------------- 2 files changed, 72 insertions(+), 55 deletions(-) diff --git a/src/control.rs b/src/control.rs index 966d8688..28755d74 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)?; + app.add_track(None, 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 c1aef4c0..8184a0c4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -40,60 +40,61 @@ pub fn main () -> Usually<()> { state.scene_cursor = 1; state.note_start = 12; state.time_zoom = 12; - state.midi_in = Some(client.register_port("midi-in", MidiIn)?); - state.transport = Some(client.transport()); - state.playing = Some(TransportState::Stopped); - state.jack = Some(jack); + state.transport = Some(client.transport()); + state.playing = Some(TransportState::Stopped); + state.midi_in = Some(client.register_port("midi-in", MidiIn)?); + state.jack = Some(jack); - let drums = state.add_track(Some("Drums"))?; - drums.add_device(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"), - ])))?); - drums.add_device(Plugin::lv2( - "Panagement", - "file:///home/user/.lv2/Auburn Sounds Panagement 2.lv2" - )?); + state.add_track(Some("Drums"), Some(Box::new(move|client, track|{ + track.add_device(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( + "Panagement", + "file:///home/user/.lv2/Auburn Sounds Panagement 2.lv2" + )?); + client.connect_ports(&track.midi_out, &track.devices[0].midi_ins()?[0])?; + 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() }, + 08 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }, + 12 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }, + })); + track.add_phrase("D-Beat", ppq * 4, Some(phrase! { + 00 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }, + 04 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() }, + 08 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }, + 10 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }, + 12 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() }, + })); + track.add_phrase("Garage", ppq * 4, Some(phrase! { + 00 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }, + 04 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() }, + 11 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }, + 12 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() }, + })); + Ok(()) + })))?; - drums.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() }, - 08 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }, - 12 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }, - })); - drums.add_phrase("D-Beat", ppq * 4, Some(phrase! { - 00 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }, - 04 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() }, - 08 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }, - 10 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }, - 12 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() }, - })); - drums.add_phrase("Garage", ppq * 4, Some(phrase! { - 00 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }, - 04 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() }, - 11 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }, - 12 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() }, - })); - - // FIXME: - drums.sequence = Some(1); - - let bass = state.add_track(Some("Bass"))?; - bass.add_device(Plugin::lv2("Odin2", "file:///home/user/.lv2/Odin2.lv2")?); - bass.add_phrase("Offbeat", ppq * 4, Some(phrase! { - 00 * ppq/4 => MidiMessage::NoteOff { key: 40.into(), vel: 100.into() }, - 02 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() }, - 04 * ppq/4 => MidiMessage::NoteOff { key: 40.into(), vel: 100.into() }, - 06 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() }, - 08 * ppq/4 => MidiMessage::NoteOff { key: 40.into(), vel: 100.into() }, - 10 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() }, - 12 * ppq/4 => MidiMessage::NoteOff { key: 40.into(), vel: 100.into() }, - 14 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() }, - })); - - // FIXME: - bass.sequence = Some(0); + state.add_track(Some("Bass"), Some(Box::new(move|client, track|{ + track.add_device(Plugin::lv2("Odin2", "file:///home/user/.lv2/Odin2.lv2")?); + //client.connect_ports(&track.midi_out, &track.devices[0].midi_ins()?[0])?; + track.sequence = Some(0); // FIXME + track.add_phrase("Offbeat", ppq * 4, Some(phrase! { + 00 * ppq/4 => MidiMessage::NoteOff { key: 40.into(), vel: 100.into() }, + 02 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() }, + 04 * ppq/4 => MidiMessage::NoteOff { key: 40.into(), vel: 100.into() }, + 06 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() }, + 08 * ppq/4 => MidiMessage::NoteOff { key: 40.into(), vel: 100.into() }, + 10 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() }, + 12 * ppq/4 => MidiMessage::NoteOff { key: 40.into(), vel: 100.into() }, + 14 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() }, + })); + Ok(()) + })))?; Ok(()) })) @@ -174,6 +175,14 @@ process!(App |self, _client, scope| { Control::Continue }); impl App { + pub fn client (&self) -> &Client { + self.jack.as_ref().unwrap().as_client() + } + pub fn connect_ports ( + &self, a: &Port, b: &Port + ) -> Usually<()> { + Ok(self.client().connect_ports(a, b)?) + } pub fn toggle_play (&mut self) -> Usually<()> { self.playing = match self.playing.expect("after jack init") { TransportState::Stopped => { @@ -194,9 +203,17 @@ impl App { self.scene_cursor = self.scenes.len(); Ok(&mut self.scenes[self.scene_cursor - 1]) } - pub fn add_track (&mut self, name: Option<&str>) -> Usually<&mut Track> { + 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.jack.as_ref().unwrap().as_client(), None, None)?); + let mut track = Track::new(&name, self.client(), None, None)?; + if let Some(init) = init { + init(self.client(), &mut track)?; + } + self.tracks.push(track); self.track_cursor = self.tracks.len(); Ok(&mut self.tracks[self.track_cursor - 1]) }