tek/src/main.rs

196 lines
8.9 KiB
Rust

#![allow(macro_expanded_macro_exports_accessed_by_absolute_paths)]
extern crate clap;
extern crate jack;
extern crate crossterm;
use clap::{Parser};
use std::error::Error;
pub mod core;
pub mod cli;
pub mod config;
pub mod device;
pub mod layout;
use crate::core::*;
use crate::device::*;
macro_rules! sample {
($note:expr, $name:expr, $src:expr) => {
{
let mut channels: Vec<wavers::Samples<f32>> = vec![];
for channel in wavers::Wav::from_path($src)?.channels() {
channels.push(channel);
}
let mut end = 0;
let mut data: Vec<Vec<f32>> = vec![];
for samples in channels.iter() {
let channel = Vec::from(samples.as_ref());
end = end.max(channel.len());
data.push(channel);
}
(u7::from_int_lossy($note).into(), Sample::new($name, 0, end, data).into())
}
};
}
fn main () -> Result<(), Box<dyn Error>> {
let _cli = cli::Cli::parse();
let xdg = microxdg::XdgApp::new("tek")?;
crate::config::create_dirs(&xdg)?;
//run(Sampler::new("Sampler#000")?)
let input = ".*nanoKEY.*";
let output = ["Komplete.*:playback_FL", "Komplete.*:playback_FR"];
let (client, _) = Client::new("init", ClientOptions::NO_START_SERVER)?;
let timebase = Arc::new(Timebase::new(client.sample_rate() as f64, 125000.0, 96.0));
let ppq = timebase.ppq() as usize;
macro_rules! play {
($t1:expr => [ $($msg:expr),* $(,)? ]) => {
( $t1 * ppq / 4, vec![ $($msg),* ] )
}
}
macro_rules! phrase {
($($t:expr => $msg:expr),* $(,)?) => {{
let mut phrase = BTreeMap::new();
$(phrase.insert($t, vec![]);)*
$(phrase.get_mut(&$t).unwrap().push($msg);)*
phrase
}}
}
let app = Launcher::new("Launcher#0", &timebase,
Some(vec![
Track::new("Drums", &timebase, 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"),
])))?.boxed(),
Plugin::lv2("Panagement", "file:///home/user/.lv2/Auburn Sounds Panagement 2.lv2")?.boxed(),
]), Some(vec![
Phrase::new("KSH", ppq * 4, Some(phrase! {
00 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() },
00 * ppq/4 => MidiMessage::NoteOn { key: 44.into(), vel: 100.into() },
01 * ppq/4 => MidiMessage::NoteOn { key: 44.into(), vel: 100.into() },
02 * ppq/4 => MidiMessage::NoteOn { key: 44.into(), vel: 100.into() },
04 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() },
04 * ppq/4 => MidiMessage::NoteOn { key: 44.into(), vel: 100.into() },
06 * ppq/4 => MidiMessage::NoteOn { key: 44.into(), vel: 100.into() },
08 * ppq/4 => MidiMessage::NoteOn { key: 44.into(), vel: 100.into() },
10 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() },
10 * ppq/4 => MidiMessage::NoteOn { key: 44.into(), vel: 100.into() },
11 * ppq/4 => MidiMessage::NoteOn { key: 44.into(), vel: 100.into() },
12 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() },
12 * ppq/4 => MidiMessage::NoteOn { key: 44.into(), vel: 100.into() },
14 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() },
14 * ppq/4 => MidiMessage::NoteOn { key: 44.into(), vel: 100.into() }
})),
Phrase::new("4K", 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() },
})),
Phrase::new("KS", 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() },
10 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() },
12 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() },
})),
]))?,
Track::new("Odin2", &timebase, Some(vec![
Plugin::lv2("Odin2", "file:///home/user/.lv2/Odin2.lv2")?.boxed(),
]), Some(vec![
Phrase::new("E G A Bb", ppq * 4, Some(BTreeMap::from([
play!(2 => [
MidiMessage::NoteOff { key: 42.into(), vel: 100.into() },
MidiMessage::NoteOn { key: 36.into(), vel: 100.into() },
]),
play!(6 => [
MidiMessage::NoteOff { key: 36.into(), vel: 100.into() },
MidiMessage::NoteOn { key: 39.into(), vel: 100.into() },
]),
play!(10 => [
MidiMessage::NoteOff { key: 39.into(), vel: 100.into() },
MidiMessage::NoteOn { key: 41.into(), vel: 100.into() },
]),
play!(14 => [
MidiMessage::NoteOff { key: 41.into(), vel: 100.into() },
MidiMessage::NoteOn { key: 42.into(), vel: 100.into() },
]),
]))),
Phrase::new("E E G Bb", ppq * 4, Some(BTreeMap::from([
play!(2 => [
MidiMessage::NoteOff { key: 42.into(), vel: 100.into() },
MidiMessage::NoteOn { key: 36.into(), vel: 100.into() },
]),
play!(6 => [
MidiMessage::NoteOff { key: 36.into(), vel: 100.into() },
MidiMessage::NoteOn { key: 36.into(), vel: 100.into() },
]),
play!(10 => [
MidiMessage::NoteOff { key: 36.into(), vel: 100.into() },
MidiMessage::NoteOn { key: 39.into(), vel: 100.into() },
]),
play!(14 => [
MidiMessage::NoteOff { key: 39.into(), vel: 100.into() },
MidiMessage::NoteOn { key: 42.into(), vel: 100.into() },
]),
]))),
Phrase::new("E E E E", ppq * 4, Some(BTreeMap::from([
play!(0 => [
MidiMessage::NoteOff { key: 36.into(), vel: 100.into() },
]),
play!(2 => [
MidiMessage::NoteOn { key: 36.into(), vel: 100.into() },
]),
play!(4 => [
MidiMessage::NoteOff { key: 36.into(), vel: 100.into() },
]),
play!(6 => [
MidiMessage::NoteOn { key: 36.into(), vel: 100.into() },
]),
play!(8 => [
MidiMessage::NoteOff { key: 36.into(), vel: 100.into() },
]),
play!(10 => [
MidiMessage::NoteOn { key: 36.into(), vel: 100.into() },
]),
play!(12 => [
MidiMessage::NoteOff { key: 36.into(), vel: 100.into() },
]),
play!(14 => [
MidiMessage::NoteOn { key: 36.into(), vel: 100.into() },
]),
])))
]))?,
//Plugin::lv2("Helm", "file:///home/user/.lv2/Helm.lv2", &[1, 0, 0, 2])?.boxed(),
//Plugin::lv2("Kick/ChowKick", "file:///home/user/.lv2/ChowKick.lv2", &[1, 1, 0, 2])?.boxed(),
//Plugin::lv2("Bass/Helm", "file:///home/user/.lv2/Helm.lv2", &[1, 0, 0, 2])?.boxed(),
//Plugin::lv2("Pads/Odin2", "file:///home/user/.lv2/Odin2.lv2", &[1, 0, 0, 2])?.boxed(),
]),
Some(vec![
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(1), None, None]),
Scene::new(&"Scene 4", &[Some(2), Some(2), 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]),
])
)?.connect(input, &output)?;
run(app)
}