refactor: jack proto-lib

This commit is contained in:
🪞👃🪞 2024-07-04 15:32:41 +03:00
parent 4aadc712b8
commit fe6ffea5df
12 changed files with 467 additions and 441 deletions

View file

@ -3,7 +3,7 @@
#![allow(macro_expanded_macro_exports_accessed_by_absolute_paths)]
extern crate clap;
extern crate jack;
extern crate jack as _jack;
extern crate crossterm;
pub mod cli;
@ -12,6 +12,7 @@ pub mod control;
pub mod core;
pub mod model;
pub mod view;
pub mod jack;
use crate::{core::*, model::*};
@ -35,48 +36,6 @@ pub fn main () -> Usually<()> {
let client = jack.as_client();
let timebase = &state.timebase;
let ppq = timebase.ppq() as usize;
state.tracks = vec![
Track::new("Drums", &jack.as_client(), Some(vec![
Phrase::new("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() },
})),
]), Some(vec![
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"),
])))?,
Plugin::lv2(
"Panagement",
"file:///home/user/.lv2/Auburn Sounds Panagement 2.lv2"
)?,
]),)?,
Track::new("Bass", &jack.as_client(), Some(vec![
Phrase::new("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() },
})),
]), Some(vec![
Plugin::lv2("Odin2", "file:///home/user/.lv2/Odin2.lv2")?,
]))?,
];
//for track in state.tracks.iter() {
//if let Some(port) = track.midi_ins()?.get(0) {
//client.connect_ports(&track.midi_out, port)?;
//}
//}
state.tracks[0].sequence = Some(0);
state.tracks[1].sequence = Some(0);
state.track_cursor = 1;
@ -87,6 +46,51 @@ pub fn main () -> Usually<()> {
state.transport = Some(client.transport());
state.playing = Some(TransportState::Stopped);
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"
)?);
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() },
}));
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() },
}));
Ok(())
}))
}
@ -205,6 +209,47 @@ impl App {
};
Ok(())
}
pub fn add_scene (&mut self, name: Option<&str>) -> Usually<&mut Scene> {
let name = name.ok_or_else(||format!("Scene {}", self.scenes.len() + 1))?;
self.scenes.push(Scene::new(&name, vec![]));
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> {
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)?);
self.track_cursor = self.tracks.len();
Ok(&mut self.tracks[self.track_cursor - 1])
}
pub fn track (&self) -> Option<(usize, &Track)> {
match self.track_cursor { 0 => None, _ => {
let id = self.track_cursor as usize - 1;
self.tracks.get(id).map(|t|(id, t))
} }
}
pub fn track_mut (&mut self) -> Option<(usize, &mut Track)> {
match self.track_cursor { 0 => None, _ => {
let id = self.track_cursor as usize - 1;
self.tracks.get_mut(id).map(|t|(id, t))
} }
}
pub fn scene (&self) -> Option<(usize, &Scene)> {
match self.scene_cursor { 0 => None, _ => {
let id = self.scene_cursor as usize - 1;
self.scenes.get(id).map(|t|(id, t))
} }
}
pub fn scene_mut (&mut self) -> Option<(usize, &mut Scene)> {
match self.scene_cursor { 0 => None, _ => {
let id = self.scene_cursor as usize - 1;
self.scenes.get_mut(id).map(|t|(id, t))
} }
}
pub fn phrase_id (&self) -> Option<usize> {
let (track_id, _) = self.track()?;
let (_, scene) = self.scene()?;
*scene.clips.get(track_id)?
}
pub fn connect_tracks (&self) -> Usually<()> {
//let (client, _status) = Client::new(
//&format!("{}-init", &self.name), ClientOptions::NO_START_SERVER
@ -233,45 +278,4 @@ impl App {
//}
Ok(())
}
pub fn add_scene (&mut self, name: Option<&str>) -> Usually<&mut Scene> {
let name = name.ok_or_else(||format!("Scene {}", self.scenes.len() + 1))?;
self.scenes.push(Scene::new(&name, vec![]));
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> {
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)?);
self.track_cursor = self.tracks.len();
Ok(&mut self.tracks[self.track_cursor - 1])
}
pub fn track (&self) -> Option<(usize, &Track)> {
match self.track_cursor { 0 => None, _ => {
let id = self.track_cursor as usize - 1;
self.tracks.get(id).map(|t|(id, t))
} }
}
pub fn track_mut (&mut self) -> Option<(usize, &mut Track)> {
match self.track_cursor { 0 => None, _ => {
let id = self.track_cursor as usize - 1;
self.tracks.get_mut(id).map(|t|(id, t))
} }
}
pub fn scene (&self) -> Option<(usize, &Scene)> {
match self.scene_cursor { 0 => None, _ => {
let id = self.scene_cursor as usize - 1;
self.scenes.get(id).map(|t|(id, t))
} }
}
pub fn scene_mut (&mut self) -> Option<(usize, &mut Scene)> {
match self.scene_cursor { 0 => None, _ => {
let id = self.scene_cursor as usize - 1;
self.scenes.get_mut(id).map(|t|(id, t))
} }
}
pub fn phrase_id (&self) -> Option<usize> {
let (track_id, _) = self.track()?;
let (_, scene) = self.scene()?;
*scene.clips.get(track_id)?
}
}