mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
remove unused fields from arranger
This commit is contained in:
parent
e2492a1326
commit
326507f400
8 changed files with 172 additions and 46 deletions
|
|
@ -9,24 +9,32 @@ pub fn main () -> Usually<()> {
|
|||
#[command(version, about, long_about = None)]
|
||||
pub struct ArrangerCli {
|
||||
/// Name of JACK client
|
||||
#[arg(short, long)] name: Option<String>,
|
||||
#[arg(short, long)]
|
||||
name: Option<String>,
|
||||
|
||||
/// Whether to include a transport toolbar (default: true)
|
||||
#[arg(short, long, default_value_t = true)] transport: bool,
|
||||
#[arg(short, long, default_value_t = true)]
|
||||
transport: bool,
|
||||
|
||||
/// Number of tracks
|
||||
#[arg(short = 'x', long, default_value_t = 8)] tracks: usize,
|
||||
#[arg(short = 'x', long, default_value_t = 8)]
|
||||
tracks: usize,
|
||||
|
||||
/// Number of scenes
|
||||
#[arg(short, long, default_value_t = 8)] scenes: usize,
|
||||
#[arg(short, long, default_value_t = 8)]
|
||||
scenes: usize,
|
||||
}
|
||||
|
||||
impl ArrangerCli {
|
||||
/// Run the arranger TUI from CLI arguments.
|
||||
fn run (&self) -> Usually<()> {
|
||||
Tui::run(JackClient::new("tek_arranger")?.activate_with(|jack|{
|
||||
let mut client_name = String::from("tek_arranger");
|
||||
if let Some(name) = self.name.as_ref() {
|
||||
client_name = name.clone();
|
||||
}
|
||||
Tui::run(JackClient::new(client_name.as_str())?.activate_with(|jack|{
|
||||
let mut app = ArrangerTui::try_from(jack)?;
|
||||
app.color = ItemPalette::random();
|
||||
if let Some(name) = self.name.as_ref() {
|
||||
*app.name.write().unwrap() = name.clone();
|
||||
}
|
||||
let track_color_1 = ItemColor::random();
|
||||
let track_color_2 = ItemColor::random();
|
||||
for i in 0..self.tracks {
|
||||
|
|
|
|||
|
|
@ -61,11 +61,11 @@ impl From<Color> for ItemPalette {
|
|||
impl From<ItemColor> for ItemPalette {
|
||||
fn from (base: ItemColor) -> Self {
|
||||
let mut light = base.okhsl.clone();
|
||||
light.lightness = (light.lightness * 4. / 3.).min(Okhsl::<f32>::max_lightness());
|
||||
light.lightness = (light.lightness * 1.3).min(Okhsl::<f32>::max_lightness());
|
||||
let mut lighter = light.clone();
|
||||
lighter.lightness = (lighter.lightness * 5. / 3.).min(Okhsl::<f32>::max_lightness());
|
||||
lighter.lightness = (lighter.lightness * 1.3).min(Okhsl::<f32>::max_lightness());
|
||||
let mut lightest = lighter.clone();
|
||||
lightest.lightness = (lightest.lightness * 4. / 3.).min(Okhsl::<f32>::max_lightness());
|
||||
lightest.lightness = (lightest.lightness * 1.3).min(Okhsl::<f32>::max_lightness());
|
||||
|
||||
let mut dark = base.okhsl.clone();
|
||||
dark.lightness = (dark.lightness * 0.75).max(Okhsl::<f32>::min_lightness());
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
use crate::*;
|
||||
use std::thread::{spawn, JoinHandle};
|
||||
use ::winit::{
|
||||
application::ApplicationHandler,
|
||||
event::WindowEvent,
|
||||
event_loop::{ActiveEventLoop, ControlFlow, EventLoop},
|
||||
window::{Window, WindowId},
|
||||
platform::x11::EventLoopBuilderExtX11
|
||||
};
|
||||
|
||||
//pub struct LV2PluginUI {
|
||||
//write: (),
|
||||
//controller: (),
|
||||
//widget: (),
|
||||
//features: (),
|
||||
//transfer: (),
|
||||
//}
|
||||
|
||||
pub fn run_lv2_ui (mut ui: LV2PluginUI) -> Usually<JoinHandle<()>> {
|
||||
Ok(spawn(move||{
|
||||
let event_loop = EventLoop::builder().with_x11().with_any_thread(true).build().unwrap();
|
||||
event_loop.set_control_flow(ControlFlow::Wait);
|
||||
event_loop.run_app(&mut ui).unwrap()
|
||||
}))
|
||||
}
|
||||
|
||||
/// A LV2 plugin's X11 UI.
|
||||
pub struct LV2PluginUI {
|
||||
pub window: Option<Window>
|
||||
}
|
||||
|
||||
impl LV2PluginUI {
|
||||
pub fn new () -> Usually<Self> {
|
||||
Ok(Self { window: None })
|
||||
}
|
||||
}
|
||||
|
||||
impl ApplicationHandler for LV2PluginUI {
|
||||
fn resumed (&mut self, event_loop: &ActiveEventLoop) {
|
||||
self.window = Some(event_loop.create_window(Window::default_attributes()).unwrap());
|
||||
}
|
||||
fn window_event (&mut self, event_loop: &ActiveEventLoop, id: WindowId, event: WindowEvent) {
|
||||
match event {
|
||||
WindowEvent::CloseRequested => {
|
||||
self.window.as_ref().unwrap().set_visible(false);
|
||||
event_loop.exit();
|
||||
},
|
||||
WindowEvent::RedrawRequested => {
|
||||
self.window.as_ref().unwrap().request_redraw();
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn lv2_ui_instantiate (kind: &str) {
|
||||
//let host = Suil
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
|
||||
use super::*;
|
||||
use ::livi::{
|
||||
World,
|
||||
Instance,
|
||||
Plugin as LiviPlugin,
|
||||
Features,
|
||||
FeaturesBuilder,
|
||||
Port,
|
||||
event::LV2AtomSequence,
|
||||
};
|
||||
use std::thread::JoinHandle;
|
||||
|
||||
/// A LV2 plugin.
|
||||
pub struct LV2Plugin {
|
||||
pub world: World,
|
||||
pub instance: Instance,
|
||||
pub plugin: LiviPlugin,
|
||||
pub features: Arc<Features>,
|
||||
pub port_list: Vec<Port>,
|
||||
pub input_buffer: Vec<LV2AtomSequence>,
|
||||
pub ui_thread: Option<JoinHandle<()>>,
|
||||
}
|
||||
|
||||
impl LV2Plugin {
|
||||
const INPUT_BUFFER: usize = 1024;
|
||||
pub fn new (uri: &str) -> Usually<Self> {
|
||||
// Get 1st plugin at URI
|
||||
let world = World::with_load_bundle(&uri);
|
||||
let features = FeaturesBuilder { min_block_length: 1, max_block_length: 65536 };
|
||||
let features = world.build_features(features);
|
||||
let mut plugin = None;
|
||||
if let Some(p) = world.iter_plugins().next() { plugin = Some(p); }
|
||||
let plugin = plugin.expect("plugin not found");
|
||||
let err = &format!("init {uri}");
|
||||
let instance = unsafe { plugin.instantiate(features.clone(), 48000.0).expect(&err) };
|
||||
let mut port_list = vec![];
|
||||
for port in plugin.ports() {
|
||||
port_list.push(port);
|
||||
}
|
||||
let input_buffer = Vec::with_capacity(Self::INPUT_BUFFER);
|
||||
// Instantiate
|
||||
Ok(Self {
|
||||
world, instance, port_list, plugin, features, input_buffer, ui_thread: None
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
use crate::*;
|
||||
|
||||
impl<E: Engine> ::vst::host::Host for Plugin<E> {}
|
||||
|
||||
fn set_vst_plugin <E: Engine> (host: &Arc<Mutex<Plugin<E>>>, _path: &str) -> Usually<PluginKind> {
|
||||
let mut loader = ::vst::host::PluginLoader::load(
|
||||
&std::path::Path::new("/nix/store/ij3sz7nqg5l7v2dygdvzy3w6cj62bd6r-helm-0.9.0/lib/lxvst/helm.so"),
|
||||
host.clone()
|
||||
)?;
|
||||
Ok(PluginKind::VST2 {
|
||||
instance: loader.instance()?
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
//! TODO
|
||||
|
||||
|
|
@ -1,48 +1,45 @@
|
|||
use crate::*;
|
||||
use ClockCommand::{Play, Pause};
|
||||
use KeyCode::{Char, Down, Right, Delete};
|
||||
use KeyCode::{Char, Delete};
|
||||
/// Root view for standalone `tek_arranger`
|
||||
pub struct ArrangerTui {
|
||||
pub jack: Arc<RwLock<JackClient>>,
|
||||
jack: Arc<RwLock<JackClient>>,
|
||||
pub clock: ClockModel,
|
||||
pub phrases: PhraseListModel,
|
||||
pub tracks: Vec<ArrangerTrack>,
|
||||
pub scenes: Vec<ArrangerScene>,
|
||||
pub name: Arc<RwLock<String>>,
|
||||
pub splits: [u16;2],
|
||||
pub selected: ArrangerSelection,
|
||||
pub mode: ArrangerMode,
|
||||
pub color: ItemPalette,
|
||||
pub size: Measure<Tui>,
|
||||
pub cursor: (usize, usize),
|
||||
pub menu_bar: Option<MenuBar<Tui, Self, ArrangerCommand>>,
|
||||
pub status_bar: Option<ArrangerStatus>,
|
||||
pub history: Vec<ArrangerCommand>,
|
||||
pub note_buf: Vec<u8>,
|
||||
pub midi_buf: Vec<Vec<Vec<u8>>>,
|
||||
pub editor: PhraseEditorModel,
|
||||
pub perf: PerfModel,
|
||||
}
|
||||
from_jack!(|jack| ArrangerTui Self {
|
||||
jack: jack.clone(),
|
||||
clock: ClockModel::from(jack),
|
||||
phrases: PhraseListModel::default(),
|
||||
editor: PhraseEditorModel::default(),
|
||||
from_jack!(|jack| ArrangerTui {
|
||||
let clock = ClockModel::from(jack);
|
||||
let phrase = Arc::new(RwLock::new(Phrase::new(
|
||||
"New", true, 4 * clock.timebase.ppq.get() as usize,
|
||||
None, Some(ItemColor::random().into())
|
||||
)));
|
||||
Self {
|
||||
clock,
|
||||
phrases: PhraseListModel::from(&phrase),
|
||||
editor: PhraseEditorModel::from(&phrase),
|
||||
selected: ArrangerSelection::Clip(0, 0),
|
||||
scenes: vec![],
|
||||
tracks: vec![],
|
||||
color: TuiTheme::bg().into(),
|
||||
history: vec![],
|
||||
mode: ArrangerMode::V(1),
|
||||
name: Arc::new(RwLock::new(String::new())),
|
||||
size: Measure::new(),
|
||||
cursor: (0, 0),
|
||||
splits: [16, 20],
|
||||
menu_bar: None,
|
||||
status_bar: None,
|
||||
midi_buf: vec![vec![];65536],
|
||||
note_buf: vec![],
|
||||
perf: PerfModel::default(),
|
||||
jack: jack.clone(),
|
||||
}
|
||||
});
|
||||
render!(<Tui>|self: ArrangerTui|{
|
||||
let arranger = ||lay!(|add|{
|
||||
|
|
@ -67,11 +64,11 @@ render!(<Tui>|self: ArrangerTui|{
|
|||
])),
|
||||
}
|
||||
});
|
||||
let with_pool = |x|Split::right(false, self.splits[1], PhraseListView(&self.phrases), x);
|
||||
let with_pool = |x|Split::left(false, self.splits[1], PhraseListView(&self.phrases), x);
|
||||
let play = Fixed::wh(5, 2, PlayPause(self.clock.is_rolling()));
|
||||
let transport = TransportView::from((self, None, true));
|
||||
let with_transport = |x|col!([row!(![&play, &transport]), &x]);
|
||||
with_transport(col!([Fixed::h(self.splits[0], arranger()), with_pool(&self.editor),]))
|
||||
with_transport(with_pool(col!([Fixed::h(self.splits[0], arranger()), &self.editor])))
|
||||
});
|
||||
audio!(|self: ArrangerTui, client, scope|{
|
||||
// Start profiling cycle
|
||||
|
|
|
|||
|
|
@ -162,8 +162,7 @@ render!(<Tui>|self: ArrangerVHeader<'a>|row!(
|
|||
// name and width of track
|
||||
let name = track.name().read().unwrap();
|
||||
let max_w = w.saturating_sub(1).min(name.len()).max(2);
|
||||
let name = format!("▎{}", &name[0..max_w]);
|
||||
let name = Tui::bold(true, Tui::fg(track.color.lightest.rgb, name));
|
||||
let name = Tui::bold(true, Tui::fg(track.color.lightest.rgb, format!("▎{}", &name[0..max_w])));
|
||||
// beats elapsed
|
||||
let elapsed = if let Some((_, Some(phrase))) = track.player.play_phrase().as_ref() {
|
||||
let length = phrase.read().unwrap().length;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue