merge tek_jack into tek_core

This commit is contained in:
🪞👃🪞 2024-08-11 09:48:45 +03:00
parent a659062dbc
commit 278b3caad3
23 changed files with 285 additions and 456 deletions

12
Cargo.lock generated
View file

@ -2512,7 +2512,6 @@ dependencies = [
"clojure-reader",
"microxdg",
"tek_core",
"tek_jack",
"tek_mixer",
"tek_sequencer",
]
@ -2527,20 +2526,13 @@ dependencies = [
"clap",
"clojure-reader",
"crossterm",
"jack",
"midly",
"once_cell",
"ratatui",
"toml",
]
[[package]]
name = "tek_jack"
version = "0.1.0"
dependencies = [
"jack",
"tek_core",
]
[[package]]
name = "tek_mixer"
version = "0.1.0"
@ -2549,7 +2541,6 @@ dependencies = [
"suil-rs",
"symphonia",
"tek_core",
"tek_jack",
"vst",
"wavers",
"winit",
@ -2560,7 +2551,6 @@ name = "tek_sequencer"
version = "0.1.0"
dependencies = [
"tek_core",
"tek_jack",
]
[[package]]

View file

@ -8,7 +8,6 @@ clojure-reader = "0.1.0"
microxdg = "0.1.2"
tek_core = { path = "../tek_core" }
tek_jack = { path = "../tek_jack" }
tek_sequencer = { path = "../tek_sequencer" }
tek_mixer = { path = "../tek_mixer" }
#jack = "0.10"

139
crates/tek/example.edn Normal file
View file

@ -0,0 +1,139 @@
;(bpm 150)
;(midi-in "nanoKEY Studio.*capture.*")
;(midi-in "nanoKEY Studio.*capture.*")
;(audio-out "Built-.+:playback_FL", "Built-.+:playback_FR")
;(scene { :name "Intro" } 0 0 _ _)
;(scene { :name "Hook" } 1 1 0 _)
;(scene { :name "Verse" } 2 2 1 _)
;(scene { :name "Chorus" } 3 3 2 _)
;(scene { :name "Bridge" } _ 4 3 _)
;(scene { :name "Outro" } 4 1 4 _)
;(track { :name "Drums" :gain +0.0 }
;(phrase { :name "4 kicks" :beats 4 :steps 16 }
;(:00 (36 128))
;(:04 (36 100))
;(:08 (36 100))
;(:12 (36 100)))
;(phrase { :name "5 kicks" :beats 4 :steps 16 }
;(:00 (36 128))
;(:04 (36 100))
;(:08 (36 128))
;(:12 (36 100))
;(:14 (36 110)))
;(phrase { :name "D Beat" :beats 8 :steps 32 }
;(:00 (44 70) (36 128) (49 110))
;(:02 (44 30))
;(:04 (44 80) (40 100))
;(:06 (44 50))
;(:08 (44 30) (36 100))
;(:10 (44 50) (36 100))
;(:12 (44 80) (40 100))
;(:14 (44 50))
;(:15 (36 50))
;(:16 (44 60) (36 80))
;(:18 (44 60) (36 80))
;(:20 (44 60) (40 80))
;(:22 (44 60))
;(:24 (44 60))
;(:26 (44 30) (36 80))
;(:27 (44 60))
;(:28 (44 60) (40 80))
;(:30 (44 60)))
;(phrase { :name "Garage" :beats 4 :steps 16 }
;(:00 (44 100) (36 100) (35 100))
;(:01 (44 100))
;(:02 (44 100) (35 100))
;(:03 (44 100))
;(:04 (44 100) (40 100))
;(:06 (44 100))
;(:07 (44 100) (34 100))
;(:09 (44 100))
;(:10 (44 100))
;(:11 (35 100) (36 100))
;(:12 (44 100) (40 100))
;(:14 (44 100)))
;(phrase { :name "Trap Pinging" :beats 8 :steps 96 }
;(:00 (42 100) (36 100) (34 120) (49 100))
;(:01 (42 100))
;(:02 (42 100))
;(:06 (42 100) (35 80) (36 80) (49 100))
;(:07 (42 100))
;(:08 (42 100))
;(:12 (42 100))
;(:15 (39 100) (34 100))
;(:18 (42 100))
;(:24 (42 100) (38 50) (40 50))
;(:27 (42 100) (36 50))
;(:30 (42 100))
;(:33 (42 100) (36 50) (34 100))
;(:36 (42 90))
;(:39 (42 80))
;(:42 (42 70))
;(:45 (42 60))
;(:48 (42 100) (36 100) (34 100))
;(:50 (42 100))
;(:52 (42 110))
;(:54 (46 50) (42 120))
;(:56 (42 90))
;(:58 (42 100))
;(:60 (42 100) (35 100))
;(:64 (39 100))
;(:66 (42 100) (34 100))
;(:70 (42 100))
;(:71 (42 100))
;(:72 (42 100) (38 50) (40 50))
;(:75 (42 100) (36 50) (34 80))
;(:78 (42 100))
;(:81 (42 100) (36 50))
;(:84 (38 40) (40 50) (34 90))
;(:87 (42 90) (35 40))
;(:90 (42 70)))
;(sampler { :name "DrumKit1" :dir "/home/user/Lab/Music/pak" }
;(sample { :midi 34 :name "808 D" :file "808.wav" })
;(sample { :midi 35 :name "Kick 1" :file "kik.wav" })
;(sample { :midi 36 :name "Kick 2" :file "kik2.wav" })
;(sample { :midi 37 :name "Rim" :file "rim.wav" })
;(sample { :midi 38 :name "Snare 1" :file "sna.wav" })
;(sample { :midi 39 :name "Shaker" :file "shk.wav" })
;(sample { :midi 40 :name "Snare 2" :file "sna2.wav" })
;(sample { :midi 42 :name "Closed HH 1" :file "chh.wav" })
;(sample { :midi 44 :name "Closed HH 2" :file "chh2.wav" })
;(sample { :midi 45 :name "Open HH 0" :file "ohh.wav" })
;(sample { :midi 46 :name "Open HH 1" :file "ohh1.wav" })
;(sample { :midi 47 :name "Open HH 2" :file "ohh2.wav" })
;(sample { :midi 49 :name "Crash" :file "crs.wav" })))
;(track { :name "Bass" :gain +0.0 }
;(phrase { :name "Bass 1" :beats 4 })
;(phrase { :name "Bass 2" :beats 4 })
;(phrase { :name "Bass 3" :beats 4 })
;(phrase { :name "Bass 4" :beats 4 })
;(phrase { :name "Bass 5" :beats 4 })
;(phrase { :name "Bass 6" :beats 4 })
;(phrase { :name "Bass 7" :beats 4 })
;(phrase { :name "Bass 8" :beats 4 })
;(lv2 {
;:name "Odin2"
;:path "file:///home/user/.lv2/Odin2.lv2"
;}))
;(track { :name "Lead" :gain +0.0 }
;(phrase { :name "Lead 1" :beats 4 })
;(phrase { :name "Lead 2" :beats 4 })
;(phrase { :name "Lead 3" :beats 4 })
;(phrase { :name "Lead 4" :beats 4 })
;(phrase { :name "Lead 5" :beats 4 })
;(phrase { :name "Lead 6" :beats 4 })
;(phrase { :name "Lead 7" :beats 4 })
;(phrase { :name "Lead 8" :beats 4 })
;(lv2 {
;:name "Odin2"
;:path "file:///home/user/.lv2/Odin2.lv2"
;}))

View file

@ -37,17 +37,18 @@ fn handle_modal (e: &AppEvent) -> Usually<bool> {
}
fn handle_focused (state: &mut App, e: &AppEvent) -> Usually<bool> {
match state.section {
AppFocus::Transport => state.transport.handle(e),
AppFocus::Arranger => state.arranger.sequencer_mut().map(|s|s.handle(e)),
AppFocus::Sequencer => state.arranger.sequencer_mut().map(|s|s.handle(e)),
AppFocus::Chain => Ok(false)/*if state.entered {
handle_device(state, e)? ||
handle_keymap(state, e, crate::control::KEYMAP_CHAIN)?
} else {
handle_keymap(state, e, crate::control::KEYMAP_CHAIN)? || handle_device(state, e)?
})*/
}
unimplemented!()
//match state.section {
//AppFocus::Transport => state.transport.handle(e),
//AppFocus::Arranger => state.arranger.sequencer_mut().map(|s|s.handle(e)),
//AppFocus::Sequencer => state.arranger.sequencer_mut().map(|s|s.handle(e)),
//AppFocus::Chain => Ok(false)[>if state.entered {
//handle_device(state, e)? ||
//handle_keymap(state, e, crate::control::KEYMAP_CHAIN)?
//} else {
//handle_keymap(state, e, crate::control::KEYMAP_CHAIN)? || handle_device(state, e)?
//})*/
//}
}
fn handle_device (state: &mut App, e: &AppEvent) -> Usually<bool> {

View file

@ -7,9 +7,9 @@
#![allow(macro_expanded_macro_exports_accessed_by_absolute_paths)]
#![allow(ambiguous_glob_reexports)]
pub(crate) use tek_core::*;
pub(crate) use tek_jack::{*, jack::*};
pub(crate) use tek_core::{*, jack::*};
pub(crate) use tek_sequencer::*;
pub(crate) use tek_mixer::*;
pub(crate) use microxdg::XdgApp;
submod! {
@ -29,7 +29,7 @@ pub static MODAL: Lazy<Arc<Mutex<Option<Box<dyn ExitableComponent>>>>> =
/// Application entrypoint.
pub fn main () -> Usually<()> {
run(App::from_edn(include_str!("../../../demos/project.edn"))?
run(App::from_edn(include_str!("../example.edn"))?
.activate(Some(|app: &Arc<RwLock<App>>|Ok({
let (midi_in, mut midi_outs) = {
let app = app.read().unwrap();

View file

@ -4,13 +4,14 @@ edition = "2021"
version = "0.1.0"
[dependencies]
crossterm = "0.27"
ratatui = { version = "0.26.3", features = [ "unstable-widget-ref", "underline-color" ] }
atomic_float = "1.0.0"
backtrace = "0.3.72"
toml = "0.8.12"
better-panic = "0.3.0"
midly = "0.5"
clap = { version = "4.5.4", features = [ "derive" ] }
clojure-reader = "0.1.0"
crossterm = "0.27"
jack = "0.10"
midly = "0.5"
once_cell = "1.19.0"
atomic_float = "1.0.0"
ratatui = { version = "0.26.3", features = [ "unstable-widget-ref", "underline-color" ] }
toml = "0.8.12"

View file

@ -1,39 +1,4 @@
//! Audio engine.
pub use jack;
use std::sync::{Arc, RwLock, LockResult, RwLockReadGuard, RwLockWriteGuard};
use std::collections::BTreeMap;
submod!( device event factory ports );
pub(crate) use tek_core::*;
pub(crate) use tek_core::ratatui::prelude::{Buffer, Rect};
pub(crate) use ::jack::{
AsyncClient,
AudioIn,
AudioOut,
Client,
ClientOptions,
ClientStatus,
ClosureProcessHandler,
Control,
//CycleTimes,
Frames,
MidiIn,
//MidiIter,
MidiOut,
NotificationHandler,
Port,
//PortFlags,
PortId,
PortSpec,
ProcessScope,
//RawMidi,
Transport,
//TransportState,
Unowned
};
use crate::{*, jack::*};
/// A UI component that may be associated with a JACK client by the `Jack` factory.
pub trait Device: Render + Handle + Process + Send + Sync {
@ -156,3 +121,109 @@ pub fn jack_run <T: Sync> (name: &str, app: &Arc<RwLock<T>>) -> Usually<DynamicA
)?)
}
/// `JackDevice` factory. Creates JACK `Client`s, performs port registration
/// and activation, and encapsulates a `Device` into a `JackDevice`.
pub struct Jack {
pub client: Client,
pub midi_ins: Vec<String>,
pub audio_ins: Vec<String>,
pub midi_outs: Vec<String>,
pub audio_outs: Vec<String>,
}
impl Jack {
pub fn new (name: &str) -> Usually<Self> {
Ok(Self {
midi_ins: vec![],
audio_ins: vec![],
midi_outs: vec![],
audio_outs: vec![],
client: Client::new(
name,
ClientOptions::NO_START_SERVER
)?.0,
})
}
pub fn run <T: Device + Process + Sized + 'static> (
self, state: impl FnOnce(JackPorts)->Box<T>
)
-> Usually<JackDevice>
{
let owned_ports = JackPorts {
audio_ins: register_ports(&self.client, self.audio_ins, AudioIn)?,
audio_outs: register_ports(&self.client, self.audio_outs, AudioOut)?,
midi_ins: register_ports(&self.client, self.midi_ins, MidiIn)?,
midi_outs: register_ports(&self.client, self.midi_outs, MidiOut)?,
};
let midi_outs = owned_ports.midi_outs.values()
.map(|p|Ok(p.name()?)).collect::<Usually<Vec<_>>>()?;
let midi_ins = owned_ports.midi_ins.values()
.map(|p|Ok(p.name()?)).collect::<Usually<Vec<_>>>()?;
let audio_outs = owned_ports.audio_outs.values()
.map(|p|Ok(p.name()?)).collect::<Usually<Vec<_>>>()?;
let audio_ins = owned_ports.audio_ins.values()
.map(|p|Ok(p.name()?)).collect::<Usually<Vec<_>>>()?;
let state = Arc::new(RwLock::new(state(owned_ports) as Box<dyn Device>));
let client = self.client.activate_async(
Notifications(Box::new({
let _state = state.clone();
move|_event|{
// FIXME: this deadlocks
//state.lock().unwrap().handle(&event).unwrap();
}
}) as Box<dyn Fn(JackEvent) + Send + Sync>),
ClosureProcessHandler::new(Box::new({
let state = state.clone();
move|c: &Client, s: &ProcessScope|{
state.write().unwrap().process(c, s)
}
}) as BoxedProcessHandler)
)?;
Ok(JackDevice {
ports: UnownedJackPorts {
audio_ins: query_ports(&client.as_client(), audio_ins),
audio_outs: query_ports(&client.as_client(), audio_outs),
midi_ins: query_ports(&client.as_client(), midi_ins),
midi_outs: query_ports(&client.as_client(), midi_outs),
},
client,
state,
})
}
pub fn audio_in (mut self, name: &str) -> Self {
self.audio_ins.push(name.to_string());
self
}
pub fn audio_out (mut self, name: &str) -> Self {
self.audio_outs.push(name.to_string());
self
}
pub fn midi_in (mut self, name: &str) -> Self {
self.midi_ins.push(name.to_string());
self
}
pub fn midi_out (mut self, name: &str) -> Self {
self.midi_outs.push(name.to_string());
self
}
}
fn register_ports <T: PortSpec + Copy> (
client: &Client, names: Vec<String>, spec: T
) -> Usually<BTreeMap<String, Port<T>>> {
names.into_iter().try_fold(BTreeMap::new(), |mut ports, name|{
let port = client.register_port(&name, spec)?;
ports.insert(name, port);
Ok(ports)
})
}
fn query_ports (
client: &Client, names: Vec<String>
) -> BTreeMap<String, Port<Unowned>> {
names.into_iter().fold(BTreeMap::new(), |mut ports, name|{
let port = client.port_by_name(&name).unwrap();
ports.insert(name, port);
ports
})
}

View file

@ -1,7 +1,4 @@
//! Wrap JACK-enabled [Device]s.
use super::*;
use tek_core::ratatui::prelude::{Buffer, Rect};
use crate::{*, jack::*};
/// A [Device] bound to a JACK client and a set of ports.
pub struct JackDevice {
@ -52,3 +49,4 @@ impl JackDevice {
Ok(self.client.as_client().connect_ports(self.audio_outs()?[index], port)?)
}
}

View file

@ -1,6 +1,4 @@
//! JACK event handling.
use super::*;
use crate::{*, jack::*};
/// Notification handler used by the [Jack] factory
/// when constructing [JackDevice]s.

View file

@ -1,5 +1,4 @@
//! Handling JACK ports.
use super::*;
use crate::{*, jack::*};
/// Collection of JACK ports as [AudioIn]/[AudioOut]/[MidiIn]/[MidiOut].
#[derive(Default, Debug)]
@ -92,3 +91,4 @@ pub trait Ports {
)?}
};
}

View file

@ -1,8 +1,9 @@
pub use ratatui;
pub use crossterm;
pub use jack;
pub use midly;
pub use clap;
pub use std::sync::{Arc, Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard};
pub use std::sync::{Arc, Mutex, LockResult, RwLock, RwLockReadGuard, RwLockWriteGuard};
pub use std::collections::BTreeMap;
pub use crossterm::event::{Event, KeyEvent, KeyCode, KeyModifiers};
pub use ratatui::prelude::{Rect, Style, Color, Buffer};
@ -16,7 +17,6 @@ pub(crate) use std::io::{stdout};
pub(crate) use std::thread::{spawn, JoinHandle};
pub(crate) use std::time::Duration;
pub(crate) use atomic_float::*;
//, LockResult, RwLockReadGuard, RwLockWriteGuard};
//pub(crate) use std::path::PathBuf;
//pub(crate) use std::fs::read_dir;
//pub(crate) use std::ffi::OsString;
@ -48,6 +48,10 @@ submod! {
time_base
time_note
time_tick
jack_core
jack_device
jack_event
jack_ports
}
/// EDN parsing helper.

View file

@ -145,7 +145,7 @@ impl Render for () {
}
}
impl<T: Render> Render for Option<T> {
impl<T: Render + Send + Sync> Render for Option<&T> {
fn render (&self, b: &mut Buffer, a: Rect) -> Usually<Rect> {
match self {
Some(widget) => widget.render(b, a),

View file

@ -46,63 +46,3 @@ mod test {
}
}
/// (pulses, name)
pub const NOTE_DURATIONS: [(usize, &str);26] = [
(1, "1/384"),
(2, "1/192"),
(3, "1/128"),
(4, "1/96"),
(6, "1/64"),
(8, "1/48"),
(12, "1/32"),
(16, "1/24"),
(24, "1/16"),
(32, "1/12"),
(48, "1/8"),
(64, "1/6"),
(96, "1/4"),
(128, "1/3"),
(192, "1/2"),
(256, "2/3"),
(384, "1/1"),
(512, "4/3"),
(576, "3/2"),
(768, "2/1"),
(1152, "3/1"),
(1536, "4/1"),
(2304, "6/1"),
(3072, "8/1"),
(3456, "9/1"),
(6144, "16/1"),
];
/// Returns the next shorter length
pub fn prev_note_length (ppq: usize) -> usize {
for i in 1..=16 {
let length = NOTE_DURATIONS[16-i].0;
if length < ppq {
return length
}
}
ppq
}
/// Returns the next longer length
pub fn next_note_length (ppq: usize) -> usize {
for (length, _) in &NOTE_DURATIONS {
if *length > ppq {
return *length
}
}
ppq
}
pub fn ppq_to_name (ppq: usize) -> &'static str {
for (length, name) in &NOTE_DURATIONS {
if *length == ppq {
return name
}
}
""
}

View file

@ -1,8 +0,0 @@
[package]
name = "tek_jack"
edition = "2021"
version = "0.1.0"
[dependencies]
tek_core = { path = "../tek_core" }
jack = "0.10"

View file

@ -1,3 +0,0 @@
# `tek_jack`
This crate interfaces with the JACK Audio Connection Kit API.

View file

@ -1,108 +0,0 @@
//! Encapsulate and run [Device]s as [JackDevice]s.
use super::*;
/// `JackDevice` factory. Creates JACK `Client`s, performs port registration
/// and activation, and encapsulates a `Device` into a `JackDevice`.
pub struct Jack {
pub client: Client,
pub midi_ins: Vec<String>,
pub audio_ins: Vec<String>,
pub midi_outs: Vec<String>,
pub audio_outs: Vec<String>,
}
impl Jack {
pub fn new (name: &str) -> Usually<Self> {
Ok(Self {
midi_ins: vec![],
audio_ins: vec![],
midi_outs: vec![],
audio_outs: vec![],
client: Client::new(
name,
ClientOptions::NO_START_SERVER
)?.0,
})
}
pub fn run <T: Device + Process + Sized + 'static> (
self, state: impl FnOnce(JackPorts)->Box<T>
)
-> Usually<JackDevice>
{
let owned_ports = JackPorts {
audio_ins: register_ports(&self.client, self.audio_ins, AudioIn)?,
audio_outs: register_ports(&self.client, self.audio_outs, AudioOut)?,
midi_ins: register_ports(&self.client, self.midi_ins, MidiIn)?,
midi_outs: register_ports(&self.client, self.midi_outs, MidiOut)?,
};
let midi_outs = owned_ports.midi_outs.values()
.map(|p|Ok(p.name()?)).collect::<Usually<Vec<_>>>()?;
let midi_ins = owned_ports.midi_ins.values()
.map(|p|Ok(p.name()?)).collect::<Usually<Vec<_>>>()?;
let audio_outs = owned_ports.audio_outs.values()
.map(|p|Ok(p.name()?)).collect::<Usually<Vec<_>>>()?;
let audio_ins = owned_ports.audio_ins.values()
.map(|p|Ok(p.name()?)).collect::<Usually<Vec<_>>>()?;
let state = Arc::new(RwLock::new(state(owned_ports) as Box<dyn Device>));
let client = self.client.activate_async(
Notifications(Box::new({
let _state = state.clone();
move|_event|{
// FIXME: this deadlocks
//state.lock().unwrap().handle(&event).unwrap();
}
}) as Box<dyn Fn(JackEvent) + Send + Sync>),
ClosureProcessHandler::new(Box::new({
let state = state.clone();
move|c: &Client, s: &ProcessScope|{
state.write().unwrap().process(c, s)
}
}) as BoxedProcessHandler)
)?;
Ok(JackDevice {
ports: UnownedJackPorts {
audio_ins: query_ports(&client.as_client(), audio_ins),
audio_outs: query_ports(&client.as_client(), audio_outs),
midi_ins: query_ports(&client.as_client(), midi_ins),
midi_outs: query_ports(&client.as_client(), midi_outs),
},
client,
state,
})
}
pub fn audio_in (mut self, name: &str) -> Self {
self.audio_ins.push(name.to_string());
self
}
pub fn audio_out (mut self, name: &str) -> Self {
self.audio_outs.push(name.to_string());
self
}
pub fn midi_in (mut self, name: &str) -> Self {
self.midi_ins.push(name.to_string());
self
}
pub fn midi_out (mut self, name: &str) -> Self {
self.midi_outs.push(name.to_string());
self
}
}
fn register_ports <T: PortSpec + Copy> (
client: &Client, names: Vec<String>, spec: T
) -> Usually<BTreeMap<String, Port<T>>> {
names.into_iter().try_fold(BTreeMap::new(), |mut ports, name|{
let port = client.register_port(&name, spec)?;
ports.insert(name, port);
Ok(ports)
})
}
fn query_ports (
client: &Client, names: Vec<String>
) -> BTreeMap<String, Port<Unowned>> {
names.into_iter().fold(BTreeMap::new(), |mut ports, name|{
let port = client.port_by_name(&name).unwrap();
ports.insert(name, port);
ports
})
}

View file

@ -5,7 +5,6 @@ version = "0.1.0"
[dependencies]
tek_core = { path = "../tek_core" }
tek_jack = { path = "../tek_jack" }
livi = "0.7.4"
suil-rs = { path = "../suil" }
@ -32,4 +31,4 @@ path = "src/sampler_main.rs"
[[bin]]
name = "tek_plugin"
path = "src/sampler_main.rs"
path = "src/plugin_main.rs"

View file

@ -2,7 +2,7 @@ pub(crate) use tek_core::*;
pub(crate) use tek_core::ratatui::prelude::*;
pub(crate) use tek_core::crossterm::event::{KeyCode, KeyModifiers};
pub(crate) use tek_core::midly::{num::u7, live::LiveEvent, MidiMessage};
pub(crate) use tek_jack::{*, jack::*};
pub(crate) use tek_core::jack::*;
pub(crate) use std::collections::BTreeMap;
pub(crate) use std::sync::{Arc, Mutex, RwLock};

View file

@ -5,7 +5,6 @@ version = "0.1.0"
[dependencies]
tek_core = { path = "../tek_core" }
tek_jack = { path = "../tek_jack" }
[lib]
path = "src/lib.rs"

View file

@ -27,12 +27,12 @@ impl Arranger {
arr.transport = Some(Arc::new(RwLock::new(TransportToolbar::new(None))));
}
if let Some(tracks) = args.tracks {
for track in 0..tracks {
for _ in 0..tracks {
arr.track_add(None)?;
}
}
if let Some(scenes) = args.scenes {
for scene in 0..scenes {
for _ in 0..scenes {
arr.scene_add(None)?;
}
}

View file

@ -4,7 +4,7 @@ pub(crate) use tek_core::*;
pub(crate) use tek_core::ratatui::prelude::*;
pub(crate) use tek_core::crossterm::event::{KeyCode, KeyModifiers};
pub(crate) use tek_core::midly::{num::u7, live::LiveEvent, MidiMessage};
pub(crate) use tek_jack::{*, jack::*};
pub(crate) use tek_core::jack::*;
pub(crate) use std::sync::{Arc, RwLock};
submod! {

View file

@ -1,139 +0,0 @@
(bpm 150)
(midi-in "nanoKEY Studio.*capture.*")
(midi-in "nanoKEY Studio.*capture.*")
(audio-out "Built-.+:playback_FL", "Built-.+:playback_FR")
(scene { :name "Intro" } 0 0 _ _)
(scene { :name "Hook" } 1 1 0 _)
(scene { :name "Verse" } 2 2 1 _)
(scene { :name "Chorus" } 3 3 2 _)
(scene { :name "Bridge" } _ 4 3 _)
(scene { :name "Outro" } 4 1 4 _)
(track { :name "Drums" :gain +0.0 }
(phrase { :name "4 kicks" :beats 4 :steps 16 }
(:00 (36 128))
(:04 (36 100))
(:08 (36 100))
(:12 (36 100)))
(phrase { :name "5 kicks" :beats 4 :steps 16 }
(:00 (36 128))
(:04 (36 100))
(:08 (36 128))
(:12 (36 100))
(:14 (36 110)))
(phrase { :name "D Beat" :beats 8 :steps 32 }
(:00 (44 70) (36 128) (49 110))
(:02 (44 30))
(:04 (44 80) (40 100))
(:06 (44 50))
(:08 (44 30) (36 100))
(:10 (44 50) (36 100))
(:12 (44 80) (40 100))
(:14 (44 50))
(:15 (36 50))
(:16 (44 60) (36 80))
(:18 (44 60) (36 80))
(:20 (44 60) (40 80))
(:22 (44 60))
(:24 (44 60))
(:26 (44 30) (36 80))
(:27 (44 60))
(:28 (44 60) (40 80))
(:30 (44 60)))
(phrase { :name "Garage" :beats 4 :steps 16 }
(:00 (44 100) (36 100) (35 100))
(:01 (44 100))
(:02 (44 100) (35 100))
(:03 (44 100))
(:04 (44 100) (40 100))
(:06 (44 100))
(:07 (44 100) (34 100))
(:09 (44 100))
(:10 (44 100))
(:11 (35 100) (36 100))
(:12 (44 100) (40 100))
(:14 (44 100)))
(phrase { :name "Trap Pinging" :beats 8 :steps 96 }
(:00 (42 100) (36 100) (34 120) (49 100))
(:01 (42 100))
(:02 (42 100))
(:06 (42 100) (35 80) (36 80) (49 100))
(:07 (42 100))
(:08 (42 100))
(:12 (42 100))
(:15 (39 100) (34 100))
(:18 (42 100))
(:24 (42 100) (38 50) (40 50))
(:27 (42 100) (36 50))
(:30 (42 100))
(:33 (42 100) (36 50) (34 100))
(:36 (42 90))
(:39 (42 80))
(:42 (42 70))
(:45 (42 60))
(:48 (42 100) (36 100) (34 100))
(:50 (42 100))
(:52 (42 110))
(:54 (46 50) (42 120))
(:56 (42 90))
(:58 (42 100))
(:60 (42 100) (35 100))
(:64 (39 100))
(:66 (42 100) (34 100))
(:70 (42 100))
(:71 (42 100))
(:72 (42 100) (38 50) (40 50))
(:75 (42 100) (36 50) (34 80))
(:78 (42 100))
(:81 (42 100) (36 50))
(:84 (38 40) (40 50) (34 90))
(:87 (42 90) (35 40))
(:90 (42 70)))
(sampler { :name "DrumKit1" :dir "/home/user/Lab/Music/pak" }
(sample { :midi 34 :name "808 D" :file "808.wav" })
(sample { :midi 35 :name "Kick 1" :file "kik.wav" })
(sample { :midi 36 :name "Kick 2" :file "kik2.wav" })
(sample { :midi 37 :name "Rim" :file "rim.wav" })
(sample { :midi 38 :name "Snare 1" :file "sna.wav" })
(sample { :midi 39 :name "Shaker" :file "shk.wav" })
(sample { :midi 40 :name "Snare 2" :file "sna2.wav" })
(sample { :midi 42 :name "Closed HH 1" :file "chh.wav" })
(sample { :midi 44 :name "Closed HH 2" :file "chh2.wav" })
(sample { :midi 45 :name "Open HH 0" :file "ohh.wav" })
(sample { :midi 46 :name "Open HH 1" :file "ohh1.wav" })
(sample { :midi 47 :name "Open HH 2" :file "ohh2.wav" })
(sample { :midi 49 :name "Crash" :file "crs.wav" })))
(track { :name "Bass" :gain +0.0 }
(phrase { :name "Bass 1" :beats 4 })
(phrase { :name "Bass 2" :beats 4 })
(phrase { :name "Bass 3" :beats 4 })
(phrase { :name "Bass 4" :beats 4 })
(phrase { :name "Bass 5" :beats 4 })
(phrase { :name "Bass 6" :beats 4 })
(phrase { :name "Bass 7" :beats 4 })
(phrase { :name "Bass 8" :beats 4 })
(lv2 {
:name "Odin2"
:path "file:///home/user/.lv2/Odin2.lv2"
}))
(track { :name "Lead" :gain +0.0 }
(phrase { :name "Lead 1" :beats 4 })
(phrase { :name "Lead 2" :beats 4 })
(phrase { :name "Lead 3" :beats 4 })
(phrase { :name "Lead 4" :beats 4 })
(phrase { :name "Lead 5" :beats 4 })
(phrase { :name "Lead 6" :beats 4 })
(phrase { :name "Lead 7" :beats 4 })
(phrase { :name "Lead 8" :beats 4 })
(lv2 {
:name "Odin2"
:path "file:///home/user/.lv2/Odin2.lv2"
}))

View file

@ -1,52 +0,0 @@
;(:bpm 150)
;(:track#01 "Drums")
;(:track#02 "Bass")
;(:track#03 "Lead")
;(:scene#01 "Intro" (:01 --) (:02 :01) (:03 :01) )
;(:scene#02 "Hook" )
;(:scene#03 "Verse" )
;(:scene#04 "Chorus")
;(:scene#05 "Bridge")
;(midi-in "nanoKEY Studio.*capture.*")
;(audio-out ["Komplete.+:playback_FL", "Komplete.+:playback_FR"])
;(sampler { :name "DrumKit1" :dir "/home/user/Lab/Music/pak" }
;(sample { :midi 34 :name "808" :file "808.wav" })
;(sample { :midi 35 :name "KC1" :file "kik.wav" })
;(sample { :midi 36 :name "KC2" :file "kik2.wav" })
;(sample { :midi 38 :name "SN1" :file "sna.wav" })
;(sample { :midi 40 :name "SN2" :file "sna2.wav" })
;(sample { :midi 42 :name "HH1" :file "chh.wav" })
;(sample { :midi 44 :name "HH2" :file "chh2.wav" }))
;(phrase { :name "4 kicks" :beats 4 :steps 16 }
;(:00 (36 128))
;(:04 (36 128))
;(:08 (36 128))
;(:12 (36 128))))
;(phrase {
;:name "5 kicks"
;:beats 4
;} (:00 (36 128))
;(:04 (36 128))
;(:08 (36 128))
;(:12 (36 128))
;(:14 (36 128)))
;(track "Bass"
;(lv2-plugin "Odin2")
;(phrase { :name "Empty" :beats 4 })
;(phrase { :name "Empty" :beats 4 }))
;(track "Lead"
;(lv2-plugin "Odin2")
;(phrase { :name "Empty" :beats 4 })
;(phrase { :name "Empty" :beats 4 }))