mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
refactor: merge plugin, sampler -> mixer; transport -> sequencer; time -> core
This commit is contained in:
parent
6206a43b4a
commit
a659062dbc
46 changed files with 128 additions and 198 deletions
36
Cargo.lock
generated
36
Cargo.lock
generated
|
|
@ -2514,16 +2514,14 @@ dependencies = [
|
||||||
"tek_core",
|
"tek_core",
|
||||||
"tek_jack",
|
"tek_jack",
|
||||||
"tek_mixer",
|
"tek_mixer",
|
||||||
"tek_plugin",
|
|
||||||
"tek_sampler",
|
|
||||||
"tek_sequencer",
|
"tek_sequencer",
|
||||||
"tek_timer",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tek_core"
|
name = "tek_core"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"atomic_float",
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"better-panic",
|
"better-panic",
|
||||||
"clap",
|
"clap",
|
||||||
|
|
@ -2546,33 +2544,15 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tek_mixer"
|
name = "tek_mixer"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
|
||||||
"tek_core",
|
|
||||||
"tek_jack",
|
|
||||||
"tek_plugin",
|
|
||||||
"tek_sampler",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tek_plugin"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"livi",
|
"livi",
|
||||||
"suil-rs",
|
"suil-rs",
|
||||||
"tek_core",
|
|
||||||
"tek_jack",
|
|
||||||
"vst",
|
|
||||||
"winit",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tek_sampler"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"symphonia",
|
"symphonia",
|
||||||
"tek_core",
|
"tek_core",
|
||||||
"tek_jack",
|
"tek_jack",
|
||||||
|
"vst",
|
||||||
"wavers",
|
"wavers",
|
||||||
|
"winit",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2581,16 +2561,6 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"tek_core",
|
"tek_core",
|
||||||
"tek_jack",
|
"tek_jack",
|
||||||
"tek_timer",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tek_timer"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"atomic_float",
|
|
||||||
"tek_core",
|
|
||||||
"tek_jack",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,8 @@ microxdg = "0.1.2"
|
||||||
|
|
||||||
tek_core = { path = "../tek_core" }
|
tek_core = { path = "../tek_core" }
|
||||||
tek_jack = { path = "../tek_jack" }
|
tek_jack = { path = "../tek_jack" }
|
||||||
tek_plugin = { path = "../tek_plugin" }
|
|
||||||
tek_sampler = { path = "../tek_sampler" }
|
|
||||||
tek_sequencer = { path = "../tek_sequencer" }
|
tek_sequencer = { path = "../tek_sequencer" }
|
||||||
tek_timer = { path = "../tek_timer" }
|
tek_mixer = { path = "../tek_mixer" }
|
||||||
tek_mixer = { path = "../tek_mixer", features = ["standalone_devices"] }
|
|
||||||
#jack = "0.10"
|
#jack = "0.10"
|
||||||
#crossterm = "0.27"
|
#crossterm = "0.27"
|
||||||
#ratatui = { version = "0.26.3", features = [ "unstable-widget-ref", "underline-color" ] }
|
#ratatui = { version = "0.26.3", features = [ "unstable-widget-ref", "underline-color" ] }
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use tek_core::Direction;
|
use tek_core::Direction;
|
||||||
use tek_timer::TransportToolbar;
|
use tek_sequencer::{TransportToolbar, Arranger};
|
||||||
use tek_sequencer::Arranger;
|
|
||||||
use tek_mixer::Mixer;
|
use tek_mixer::Mixer;
|
||||||
|
|
||||||
/// Root of application state.
|
/// Root of application state.
|
||||||
|
|
@ -108,7 +107,7 @@ render!(App |self, buf, area| {
|
||||||
focused: self.section == AppFocus::Chain,
|
focused: self.section == AppFocus::Chain,
|
||||||
chain: self.mixer.track()
|
chain: self.mixer.track()
|
||||||
},
|
},
|
||||||
&self.arranger.sequencer,
|
&self.arranger.sequencer(),
|
||||||
]))
|
]))
|
||||||
]).render(buf, area)?;
|
]).render(buf, area)?;
|
||||||
if let Some(ref modal) = *MODAL.lock().unwrap() {
|
if let Some(ref modal) = *MODAL.lock().unwrap() {
|
||||||
|
|
|
||||||
|
|
@ -39,8 +39,8 @@ fn handle_modal (e: &AppEvent) -> Usually<bool> {
|
||||||
fn handle_focused (state: &mut App, e: &AppEvent) -> Usually<bool> {
|
fn handle_focused (state: &mut App, e: &AppEvent) -> Usually<bool> {
|
||||||
match state.section {
|
match state.section {
|
||||||
AppFocus::Transport => state.transport.handle(e),
|
AppFocus::Transport => state.transport.handle(e),
|
||||||
AppFocus::Arranger => state.arranger.sequencer.handle(e),
|
AppFocus::Arranger => state.arranger.sequencer_mut().map(|s|s.handle(e)),
|
||||||
AppFocus::Sequencer => state.arranger.sequencer.handle(e),
|
AppFocus::Sequencer => state.arranger.sequencer_mut().map(|s|s.handle(e)),
|
||||||
AppFocus::Chain => Ok(false)/*if state.entered {
|
AppFocus::Chain => Ok(false)/*if state.entered {
|
||||||
handle_device(state, e)? ||
|
handle_device(state, e)? ||
|
||||||
handle_keymap(state, e, crate::control::KEYMAP_CHAIN)?
|
handle_keymap(state, e, crate::control::KEYMAP_CHAIN)?
|
||||||
|
|
@ -85,11 +85,11 @@ pub const KEYMAP_GLOBAL: &'static [KeyBinding<App>] = keymap!(App {
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}],
|
}],
|
||||||
[Char('='), NONE, "zoom_in", "show fewer ticks per block", |app: &mut App| {
|
[Char('='), NONE, "zoom_in", "show fewer ticks per block", |app: &mut App| {
|
||||||
app.arranger.sequencer.time_axis.scale_mut(&prev_note_length);
|
app.arranger.sequencer_mut().map(|s|s.time_axis.scale_mut(&prev_note_length));
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}],
|
}],
|
||||||
[Char('-'), NONE, "zoom_out", "show more ticks per block", |app: &mut App| {
|
[Char('-'), NONE, "zoom_out", "show more ticks per block", |app: &mut App| {
|
||||||
app.arranger.sequencer.time_axis.scale_mut(&next_note_length);
|
app.arranger.sequencer_mut().map(|s|s.time_axis.scale_mut(&next_note_length));
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}],
|
}],
|
||||||
[Char('x'), NONE, "extend", "double the current clip", |app: &mut App| {
|
[Char('x'), NONE, "extend", "double the current clip", |app: &mut App| {
|
||||||
|
|
@ -144,14 +144,14 @@ pub const KEYMAP_FOCUS: &'static [KeyBinding<App>] = keymap!(App {
|
||||||
app.entered = false;
|
app.entered = false;
|
||||||
app.transport.entered = app.entered;
|
app.transport.entered = app.entered;
|
||||||
app.arranger.entered = app.entered;
|
app.arranger.entered = app.entered;
|
||||||
app.arranger.sequencer.entered = app.entered;
|
app.arranger.sequencer_mut().map(|s|s.entered = app.entered);
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}],
|
}],
|
||||||
[Enter, NONE, "focus_enter", "activate item at cursor", |app: &mut App|{
|
[Enter, NONE, "focus_enter", "activate item at cursor", |app: &mut App|{
|
||||||
app.entered = true;
|
app.entered = true;
|
||||||
app.transport.entered = app.entered;
|
app.transport.entered = app.entered;
|
||||||
app.arranger.entered = app.entered;
|
app.arranger.entered = app.entered;
|
||||||
app.arranger.sequencer.entered = app.entered;
|
app.arranger.sequencer_mut().map(|s|s.entered = app.entered);
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}],
|
}],
|
||||||
});
|
});
|
||||||
|
|
@ -162,8 +162,10 @@ pub fn focus_next (app: &mut App) -> Usually<bool> {
|
||||||
app.transport.entered = app.entered;
|
app.transport.entered = app.entered;
|
||||||
app.arranger.focused = app.section == AppFocus::Arranger;
|
app.arranger.focused = app.section == AppFocus::Arranger;
|
||||||
app.arranger.entered = app.entered;
|
app.arranger.entered = app.entered;
|
||||||
app.arranger.sequencer.focused = app.section == AppFocus::Sequencer;
|
app.arranger.sequencer_mut().map(|s|{
|
||||||
app.arranger.sequencer.entered = app.entered;
|
s.focused = app.section == AppFocus::Sequencer;
|
||||||
|
s.entered = app.entered;
|
||||||
|
});
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -173,7 +175,9 @@ pub fn focus_prev (app: &mut App) -> Usually<bool> {
|
||||||
app.transport.entered = app.entered;
|
app.transport.entered = app.entered;
|
||||||
app.arranger.focused = app.section == AppFocus::Arranger;
|
app.arranger.focused = app.section == AppFocus::Arranger;
|
||||||
app.arranger.entered = app.entered;
|
app.arranger.entered = app.entered;
|
||||||
app.arranger.sequencer.focused = app.section == AppFocus::Sequencer;
|
app.arranger.sequencer_mut().map(|s|{
|
||||||
app.arranger.sequencer.entered = app.entered;
|
s.focused = app.section == AppFocus::Sequencer;
|
||||||
|
s.entered = app.entered;
|
||||||
|
});
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
pub(crate) use tek_core::*;
|
pub(crate) use tek_core::*;
|
||||||
pub(crate) use tek_jack::{*, jack::*};
|
pub(crate) use tek_jack::{*, jack::*};
|
||||||
pub(crate) use tek_timer::*;
|
pub(crate) use tek_sequencer::*;
|
||||||
pub(crate) use microxdg::XdgApp;
|
pub(crate) use microxdg::XdgApp;
|
||||||
|
|
||||||
submod! {
|
submod! {
|
||||||
|
|
|
||||||
|
|
@ -13,3 +13,4 @@ midly = "0.5"
|
||||||
clap = { version = "4.5.4", features = [ "derive" ] }
|
clap = { version = "4.5.4", features = [ "derive" ] }
|
||||||
clojure-reader = "0.1.0"
|
clojure-reader = "0.1.0"
|
||||||
once_cell = "1.19.0"
|
once_cell = "1.19.0"
|
||||||
|
atomic_float = "1.0.0"
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,13 @@ pub use ratatui::prelude::{Rect, Style, Color, Buffer};
|
||||||
pub use ratatui::style::Stylize;
|
pub use ratatui::style::Stylize;
|
||||||
pub use clojure_reader::{edn::{read, Edn}, error::Error as EdnError};
|
pub use clojure_reader::{edn::{read, Edn}, error::Error as EdnError};
|
||||||
pub use once_cell::sync::Lazy;
|
pub use once_cell::sync::Lazy;
|
||||||
|
pub use std::sync::atomic::{Ordering, AtomicBool};
|
||||||
|
|
||||||
pub(crate) use std::error::Error;
|
pub(crate) use std::error::Error;
|
||||||
pub(crate) use std::io::{stdout};
|
pub(crate) use std::io::{stdout};
|
||||||
pub(crate) use std::thread::{spawn, JoinHandle};
|
pub(crate) use std::thread::{spawn, JoinHandle};
|
||||||
pub(crate) use std::time::Duration;
|
pub(crate) use std::time::Duration;
|
||||||
pub(crate) use std::sync::atomic::{Ordering, AtomicBool};
|
pub(crate) use atomic_float::*;
|
||||||
//, LockResult, RwLockReadGuard, RwLockWriteGuard};
|
//, LockResult, RwLockReadGuard, RwLockWriteGuard};
|
||||||
//pub(crate) use std::path::PathBuf;
|
//pub(crate) use std::path::PathBuf;
|
||||||
//pub(crate) use std::fs::read_dir;
|
//pub(crate) use std::fs::read_dir;
|
||||||
|
|
@ -41,7 +42,12 @@ use crossterm::terminal::{
|
||||||
}
|
}
|
||||||
|
|
||||||
submod! {
|
submod! {
|
||||||
exit render handle
|
exit
|
||||||
|
render
|
||||||
|
handle
|
||||||
|
time_base
|
||||||
|
time_note
|
||||||
|
time_tick
|
||||||
}
|
}
|
||||||
|
|
||||||
/// EDN parsing helper.
|
/// EDN parsing helper.
|
||||||
|
|
|
||||||
|
|
@ -145,6 +145,15 @@ impl Render for () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: Render> Render for Option<T> {
|
||||||
|
fn render (&self, b: &mut Buffer, a: Rect) -> Usually<Rect> {
|
||||||
|
match self {
|
||||||
|
Some(widget) => widget.render(b, a),
|
||||||
|
None => ().render(b, a),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: Fn(&mut Buffer, Rect) -> Usually<Rect> + Send> Render for T {
|
impl<T: Fn(&mut Buffer, Rect) -> Usually<Rect> + Send> Render for T {
|
||||||
fn render (&self, b: &mut Buffer, a: Rect) -> Usually<Rect> {
|
fn render (&self, b: &mut Buffer, a: Rect) -> Usually<Rect> {
|
||||||
(*self)(b, a)
|
(*self)(b, a)
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,3 @@
|
||||||
pub(crate) use tek_core::*;
|
|
||||||
pub(crate) use tek_core::crossterm::event::{KeyCode, KeyModifiers};
|
|
||||||
pub(crate) use tek_jack::{*, jack::*};
|
|
||||||
pub(crate) use std::sync::{Arc, atomic::Ordering};
|
|
||||||
pub(crate) use atomic_float::AtomicF64;
|
|
||||||
submod! {
|
|
||||||
timebase
|
|
||||||
ticks
|
|
||||||
transport
|
|
||||||
transport_focus
|
|
||||||
transport_handle
|
|
||||||
transport_render
|
|
||||||
}
|
|
||||||
|
|
||||||
/// (pulses, name)
|
/// (pulses, name)
|
||||||
pub const NOTE_DURATIONS: [(usize, &str);26] = [
|
pub const NOTE_DURATIONS: [(usize, &str);26] = [
|
||||||
(1, "1/384"),
|
(1, "1/384"),
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
use crate::*;
|
|
||||||
|
|
||||||
/// Defines frames per tick.
|
/// Defines frames per tick.
|
||||||
pub struct Ticks(pub f64);
|
pub struct Ticks(pub f64);
|
||||||
|
|
||||||
|
|
@ -6,13 +6,14 @@ version = "0.1.0"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tek_core = { path = "../tek_core" }
|
tek_core = { path = "../tek_core" }
|
||||||
tek_jack = { path = "../tek_jack" }
|
tek_jack = { path = "../tek_jack" }
|
||||||
tek_sampler = { path = "../tek_sampler", optional = true }
|
|
||||||
tek_plugin = { path = "../tek_plugin", optional = true }
|
|
||||||
|
|
||||||
[features]
|
livi = "0.7.4"
|
||||||
standalone_devices = [ "sampler", "plugin" ]
|
suil-rs = { path = "../suil" }
|
||||||
sampler = [ "tek_sampler" ]
|
symphonia = { version = "0.5.4", features = [ "all" ] }
|
||||||
plugin = [ "tek_plugin" ]
|
vst = "0.4.0"
|
||||||
|
#vst3 = "0.1.0"
|
||||||
|
wavers = "1.4.3"
|
||||||
|
winit = { version = "0.30.4", features = [ "x11" ] }
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
@ -24,3 +25,11 @@ path = "src/mixer_main.rs"
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "tek_track"
|
name = "tek_track"
|
||||||
path = "src/track_main.rs"
|
path = "src/track_main.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "tek_sampler"
|
||||||
|
path = "src/sampler_main.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "tek_plugin"
|
||||||
|
path = "src/sampler_main.rs"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,15 @@
|
||||||
# `tek_mixer` and `tek_track`
|
# `tek_mixer`
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// - Meters: propagate clipping:
|
// - Meters: propagate clipping:
|
||||||
// - If one stage clips, all stages after it are marked red
|
// - If one stage clips, all stages after it are marked red
|
||||||
// - If one track clips, all tracks that feed from it are marked red?
|
// - If one track clips, all tracks that feed from it are marked red?
|
||||||
|
|
||||||
|
# `tek_track`
|
||||||
|
|
||||||
|
# `tek_sampler`
|
||||||
|
|
||||||
|
This crate implements a sampler device which plays audio files
|
||||||
|
in response to MIDI notes.
|
||||||
|
|
||||||
|
# `tek_plugin`
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,15 @@
|
||||||
pub(crate) use tek_core::*;
|
pub(crate) use tek_core::*;
|
||||||
pub(crate) use tek_core::ratatui::prelude::*;
|
pub(crate) use tek_core::ratatui::prelude::*;
|
||||||
pub(crate) use tek_core::crossterm::event::{KeyCode, KeyModifiers};
|
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_jack::{*, jack::*};
|
||||||
|
|
||||||
|
pub(crate) use std::collections::BTreeMap;
|
||||||
|
pub(crate) use std::sync::{Arc, Mutex, RwLock};
|
||||||
|
pub(crate) use std::path::PathBuf;
|
||||||
|
pub(crate) use std::ffi::OsString;
|
||||||
|
pub(crate) use std::fs::read_dir;
|
||||||
|
|
||||||
submod! {
|
submod! {
|
||||||
mixer
|
mixer
|
||||||
mixer_cli
|
mixer_cli
|
||||||
|
|
@ -10,4 +18,14 @@ submod! {
|
||||||
track
|
track
|
||||||
track_view
|
track_view
|
||||||
track_handle
|
track_handle
|
||||||
|
plugin
|
||||||
|
plugin_lv2
|
||||||
|
plugin_lv2_gui
|
||||||
|
plugin_vst2
|
||||||
|
plugin_vst3
|
||||||
|
sample
|
||||||
|
sample_add
|
||||||
|
sampler
|
||||||
|
sampler_edn
|
||||||
|
voice
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1
crates/tek_mixer/src/plugin_vst3.rs
Normal file
1
crates/tek_mixer/src/plugin_vst3.rs
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
//! TODO
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "tek_plugin"
|
|
||||||
edition = "2021"
|
|
||||||
version = "0.1.0"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
tek_core = { path = "../tek_core" }
|
|
||||||
tek_jack = { path = "../tek_jack" }
|
|
||||||
livi = "0.7.4"
|
|
||||||
winit = { version = "0.30.4", features = [ "x11" ] }
|
|
||||||
suil-rs = { path = "../suil" }
|
|
||||||
vst = "0.4.0"
|
|
||||||
#vst3 = "0.1.0"
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
path = "src/lib.rs"
|
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "tek_plugin"
|
|
||||||
path = "src/main.rs"
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
# `tek_plugin`
|
|
||||||
|
|
||||||
This crate allows plugins to be loaded.
|
|
||||||
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
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_jack::*;
|
|
||||||
pub(crate) use tek_jack::jack::*;
|
|
||||||
|
|
||||||
use std::sync::Arc;
|
|
||||||
use std::sync::Mutex;
|
|
||||||
|
|
||||||
submod! {
|
|
||||||
plugin
|
|
||||||
lv2
|
|
||||||
lv2_gui
|
|
||||||
vst2
|
|
||||||
vst3
|
|
||||||
}
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
use crate::*;
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "tek_sampler"
|
|
||||||
edition = "2021"
|
|
||||||
version = "0.1.0"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
tek_core = { path = "../tek_core" }
|
|
||||||
tek_jack = { path = "../tek_jack" }
|
|
||||||
symphonia = { version = "0.5.4", features = [ "all" ] }
|
|
||||||
wavers = "1.4.3"
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
path = "src/lib.rs"
|
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "tek_sampler"
|
|
||||||
path = "src/main.rs"
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
# `tek_sampler`
|
|
||||||
|
|
||||||
This crate implements a sampler device which plays audio files
|
|
||||||
in response to MIDI notes.
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
// Sampler (currently 16bit WAVs at system rate; TODO convert/resample)
|
|
||||||
|
|
||||||
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 std::collections::BTreeMap;
|
|
||||||
pub(crate) use std::sync::{Arc, Mutex, RwLock};
|
|
||||||
pub(crate) use std::path::PathBuf;
|
|
||||||
pub(crate) use std::ffi::OsString;
|
|
||||||
pub(crate) use std::fs::read_dir;
|
|
||||||
|
|
||||||
submod! {
|
|
||||||
sampler
|
|
||||||
sample
|
|
||||||
sample_add
|
|
||||||
voice
|
|
||||||
}
|
|
||||||
|
|
@ -6,7 +6,6 @@ version = "0.1.0"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tek_core = { path = "../tek_core" }
|
tek_core = { path = "../tek_core" }
|
||||||
tek_jack = { path = "../tek_jack" }
|
tek_jack = { path = "../tek_jack" }
|
||||||
tek_timer = { path = "../tek_timer" }
|
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
@ -18,3 +17,7 @@ path = "src/sequencer_main.rs"
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "tek_arranger"
|
name = "tek_arranger"
|
||||||
path = "src/arranger_main.rs"
|
path = "src/arranger_main.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "tek_transport"
|
||||||
|
path = "src/transport_main.rs"
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,23 @@
|
||||||
# `tek_sequencer`
|
# `tek_sequencer`
|
||||||
|
|
||||||
This crate implements a MIDI sequencer and arranger with clip launching.
|
This crate implements a MIDI sequencer and arranger with clip launching.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# `tek_arranger`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# `tek_timer`
|
||||||
|
|
||||||
|
This crate implements time sync and JACK transport control.
|
||||||
|
|
||||||
|
* Warning: If transport is set rolling by qjackctl, this program can't pause it
|
||||||
|
* Todo: bpm: shift +/- 0.001
|
||||||
|
* Todo: quant/sync: shift = next/prev value of same type (normal, triplet, dotted)
|
||||||
|
* Or: use shift to switch between inc/dec top/bottom value?
|
||||||
|
* Todo: focus play button
|
||||||
|
* Todo: focus time position
|
||||||
|
* Todo: edit numeric values
|
||||||
|
* Todo: jump to time/bbt markers
|
||||||
|
* Todo: count xruns
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,16 @@ impl Arranger {
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn sequencer (&self) -> Option<&Sequencer> {
|
||||||
|
self.selected.track()
|
||||||
|
.map(|track|self.tracks.get(track))
|
||||||
|
.flatten()
|
||||||
|
}
|
||||||
|
pub fn sequencer_mut (&mut self) -> Option<&mut Sequencer> {
|
||||||
|
self.selected.track()
|
||||||
|
.map(|track|self.tracks.get_mut(track))
|
||||||
|
.flatten()
|
||||||
|
}
|
||||||
pub fn show_phrase (&mut self) -> Usually<()> {
|
pub fn show_phrase (&mut self) -> Usually<()> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
//let phrase = self.phrase();
|
//let phrase = self.phrase();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
use tek_core::clap::{self, Parser};
|
use tek_core::clap::{self, Parser};
|
||||||
use tek_timer::TransportToolbar;
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
#[derive(Debug, Parser)]
|
#[derive(Debug, Parser)]
|
||||||
|
|
|
||||||
|
|
@ -4,24 +4,27 @@ pub(crate) use tek_core::*;
|
||||||
pub(crate) use tek_core::ratatui::prelude::*;
|
pub(crate) use tek_core::ratatui::prelude::*;
|
||||||
pub(crate) use tek_core::crossterm::event::{KeyCode, KeyModifiers};
|
pub(crate) use tek_core::crossterm::event::{KeyCode, KeyModifiers};
|
||||||
pub(crate) use tek_core::midly::{num::u7, live::LiveEvent, MidiMessage};
|
pub(crate) use tek_core::midly::{num::u7, live::LiveEvent, MidiMessage};
|
||||||
pub(crate) use tek_jack::jack::*;
|
pub(crate) use tek_jack::{*, jack::*};
|
||||||
pub(crate) use tek_timer::*;
|
|
||||||
pub(crate) use std::sync::{Arc, RwLock};
|
pub(crate) use std::sync::{Arc, RwLock};
|
||||||
|
|
||||||
submod! {
|
submod! {
|
||||||
midi
|
|
||||||
phrase
|
|
||||||
sequencer
|
|
||||||
sequencer_cli
|
|
||||||
sequencer_handle
|
|
||||||
sequencer_render
|
|
||||||
arranger
|
arranger
|
||||||
arranger_cli
|
arranger_cli
|
||||||
arranger_focus
|
arranger_focus
|
||||||
arranger_handle
|
arranger_handle
|
||||||
arranger_track
|
arranger_track
|
||||||
arranger_view
|
arranger_view
|
||||||
|
midi
|
||||||
|
phrase
|
||||||
scene
|
scene
|
||||||
|
sequencer
|
||||||
|
sequencer_cli
|
||||||
|
sequencer_handle
|
||||||
|
sequencer_render
|
||||||
|
transport
|
||||||
|
transport_focus
|
||||||
|
transport_handle
|
||||||
|
transport_render
|
||||||
}
|
}
|
||||||
|
|
||||||
pubmod! {
|
pubmod! {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
use tek_core::clap::{self, Parser};
|
use tek_core::clap::{self, Parser};
|
||||||
use tek_timer::TransportToolbar;
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
#[derive(Debug, Parser)]
|
#[derive(Debug, Parser)]
|
||||||
|
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "tek_timer"
|
|
||||||
edition = "2021"
|
|
||||||
version = "0.1.0"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
tek_core = { path = "../tek_core" }
|
|
||||||
tek_jack = { path = "../tek_jack" }
|
|
||||||
atomic_float = "1.0.0"
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
path = "src/lib.rs"
|
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "tek_timer"
|
|
||||||
path = "src/transport_main.rs"
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
# `tek_timer`
|
|
||||||
|
|
||||||
This crate implements time sync and JACK transport control.
|
|
||||||
|
|
||||||
* Warning: If transport is set rolling by qjackctl, this program can't pause it
|
|
||||||
* Todo: bpm: shift +/- 0.001
|
|
||||||
* Todo: quant/sync: shift = next/prev value of same type (normal, triplet, dotted)
|
|
||||||
* Or: use shift to switch between inc/dec top/bottom value?
|
|
||||||
* Todo: focus play button
|
|
||||||
* Todo: focus time position
|
|
||||||
* Todo: edit numeric values
|
|
||||||
* Todo: jump to time/bbt markers
|
|
||||||
* Todo: count xruns
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue