mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
196 lines
8.9 KiB
Rust
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)
|
|
}
|