diff --git a/Cargo.lock b/Cargo.lock index 73e94d91..b95dd46d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -525,6 +525,15 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "music-math" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7475e279ecd71671f462a096fcc33ab1840d0fb7e2e984df8b096831960050" +dependencies = [ + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -892,6 +901,7 @@ dependencies = [ "livi", "microxdg", "midly", + "music-math", "ratatui", "toml", "vst", diff --git a/Cargo.toml b/Cargo.toml index 44bbbb1f..40f0cac4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,3 +18,4 @@ vst = "0.4.0" livi = "0.7.4" #atomic_enum = "0.3.0" wavers = "1.4.3" +music-math = "0.1.1" diff --git a/src/main.rs b/src/main.rs index 80122f36..dedd65d5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -48,28 +48,87 @@ fn main () -> Result<(), Box> { ppq: AtomicUsize::new(96), }); let ppq = timebase.ppq() as u32; + macro_rules! play { + ($t1:expr => [ $($msg:expr),* $(,)? ]) => { + ( $t1 * ppq / 4, vec![ $($msg),* ] ) + } + } let app = Launcher::new("Launcher#0", &timebase, Some(vec![ - Track::new("Kick", &timebase, Some(vec![ + Track::new("Drums", &timebase, Some(vec![ //Plugin::lv2("Kick/ChowKick", "file:///home/user/.lv2/ChowKick.lv2", &[1, 1, 0, 2])?.boxed(), 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"), ])))?.boxed(), ]), Some(vec![ - Phrase::new("HelloKick", ppq * 4, Some(BTreeMap::from([ - ( ppq * 0, vec![MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }] ), - ( ppq * 1, vec![MidiMessage::NoteOn { key: 40.into(), vel: 100.into() }] ), - ( ppq * 5 / 2, vec![MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }] ), - ( ppq * 3, vec![MidiMessage::NoteOn { key: 40.into(), vel: 100.into() }] ), - ]))) + Phrase::new("4K", ppq * 4, Some(BTreeMap::from([ + play!(0 => [ + MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }, + ] ), + play!(4 => [ + MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }, + ]), + play!(8 => [ + MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }, + ]), + play!(12 => [ + MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }, + ]), + ]))), + Phrase::new("KS", ppq * 4, Some(BTreeMap::from([ + play!(0 => [ + MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }, + ] ), + play!(4 => [ + MidiMessage::NoteOn { key: 40.into(), vel: 100.into() }, + ]), + play!(10 => [ + MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }, + ]), + play!(12 => [ + MidiMessage::NoteOn { key: 40.into(), vel: 100.into() }, + ]), + ]))), + Phrase::new("KSH", ppq * 4, Some(BTreeMap::from([ + play!(0 => [ + MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }, + MidiMessage::NoteOn { key: 44.into(), vel: 100.into() }, + ] ), + play!(2 => [ + MidiMessage::NoteOn { key: 44.into(), vel: 100.into() }, + ]), + play!(4 => [ + MidiMessage::NoteOn { key: 40.into(), vel: 100.into() }, + MidiMessage::NoteOn { key: 44.into(), vel: 100.into() }, + ]), + play!(6 => [ + MidiMessage::NoteOn { key: 44.into(), vel: 100.into() }, + ]), + play!(8 => [ + MidiMessage::NoteOn { key: 44.into(), vel: 100.into() }, + ]), + play!(10 => [ + MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }, + MidiMessage::NoteOn { key: 44.into(), vel: 100.into() }, + ]), + play!(12 => [ + MidiMessage::NoteOn { key: 40.into(), vel: 100.into() }, + MidiMessage::NoteOn { key: 44.into(), vel: 100.into() }, + ]), + play!(14 => [ + MidiMessage::NoteOn { key: 40.into(), vel: 100.into() }, + MidiMessage::NoteOn { key: 44.into(), vel: 100.into() }, + ]), + ]))), ]))?, Track::new("Helm", &timebase, Some(vec![ Plugin::lv2("Helm", "file:///home/user/.lv2/Helm.lv2", &[1, 0, 0, 2])?.boxed(), ]), Some(vec![ - Phrase::new("HelloBass", ppq * 4, Some(BTreeMap::from([ + Phrase::new("E G A Bb", ppq * 4, Some(BTreeMap::from([ ( ppq / 2 + ppq * 0, vec![MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }] ), ( ppq / 2 + ppq * 1 / 2, vec![MidiMessage::NoteOff { key: 36.into(), vel: 100.into() }] ), ( ppq / 2 + ppq * 1, vec![MidiMessage::NoteOn { key: 39.into(), vel: 100.into() }] ), @@ -86,8 +145,10 @@ fn main () -> Result<(), Box> { //Plugin::lv2("Pads/Odin2", "file:///home/user/.lv2/Odin2.lv2", &[1, 0, 0, 2])?.boxed(), ]), Some(vec![ - Scene::new(&"Scene#01", &[Some(0), None, None, None]), - Scene::new(&"Scene#02", &[Some(0), Some(0), None, None]), + Scene::new(&"Scene 1", &[Some(0), None, None, None]), + Scene::new(&"Scene 2", &[Some(0), Some(0), None, None]), + Scene::new(&"Scene 3", &[Some(1), Some(0), None, None]), + Scene::new(&"Scene 4", &[Some(2), Some(0), None, None]), //Scene::new(&"Scene#03", &[None, Some(0), None, None]), //Scene::new(&"Scene#04", &[None, None, None, None]), //Scene::new(&"Scene#05", &[None, None, None, None]),