remove unused fields from arranger

This commit is contained in:
🪞👃🪞 2024-12-18 19:22:51 +01:00
parent e2492a1326
commit 326507f400
8 changed files with 172 additions and 46 deletions

View file

@ -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 {

View file

@ -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());

View file

@ -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
}

View file

@ -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
})
}
}

View file

@ -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()?
})
}

View file

@ -0,0 +1,2 @@
//! TODO

View file

@ -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

View file

@ -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;