wip: reenable mixer components

This commit is contained in:
🪞👃🪞 2024-11-04 17:57:47 +02:00
parent 2f189c6d7e
commit 1dbc5d1bb7
6 changed files with 87 additions and 16 deletions

View file

@ -1,15 +1,17 @@
use crate::*;
pub struct Mixer<E: Engine> {
/// JACK client handle (needs to not be dropped for standalone mode to work).
pub jack: Arc<RwLock<JackClient>>,
pub name: String,
pub tracks: Vec<Track<E>>,
pub selected_track: usize,
pub selected_column: usize,
}
impl<E: Engine> Mixer<E> {
pub fn new (name: &str) -> Usually<Self> {
let (client, _status) = Client::new(name, ClientOptions::NO_START_SERVER)?;
pub fn new (jack: &Arc<RwLock<JackClient>>, name: &str) -> Usually<Self> {
Ok(Self {
jack: jack.clone(),
name: name.into(),
selected_column: 0,
selected_track: 1,

View file

@ -0,0 +1,22 @@
//! Multi-track mixer
include!("lib.rs");
use tek_core::clap::{self, Parser};
pub fn main () -> Usually<()> { MixerCli::parse().run() }
#[derive(Debug, Parser)] #[command(version, about, long_about = None)] pub struct MixerCli {
/// Name of JACK client
#[arg(short, long)] name: Option<String>,
/// Number of tracks
#[arg(short, long)] channels: Option<usize>,
}
impl MixerCli {
fn run (&self) -> Usually<()> {
Tui::run(JackClient::new("tek_mixer")?.activate_with(|jack|{
let mut mixer = Mixer::new(jack, self.name.as_ref().map(|x|x.as_str()).unwrap_or("mixer"))?;
for channel in 0..self.channels.unwrap_or(8) {
mixer.track_add(&format!("Track {}", channel + 1), 1)?;
}
Ok(mixer)
})?)?;
Ok(())
}
}

View file

@ -3,6 +3,8 @@ use crate::*;
/// A plugin device.
pub struct Plugin<E> {
_engine: PhantomData<E>,
/// JACK client handle (needs to not be dropped for standalone mode to work).
pub jack: Arc<RwLock<JackClient>>,
pub name: String,
pub path: Option<String>,
pub plugin: Option<PluginKind>,
@ -13,9 +15,13 @@ pub struct Plugin<E> {
impl<E> Plugin<E> {
/// Create a plugin host device.
pub fn new (name: &str) -> Usually<Self> {
pub fn new (
jack: &Arc<RwLock<JackClient>>,
name: &str,
) -> Usually<Self> {
Ok(Self {
_engine: Default::default(),
jack: jack.clone(),
name: name.into(),
path: None,
plugin: None,
@ -27,11 +33,16 @@ impl<E> Plugin<E> {
}
impl Plugin<Tui> {
pub fn new_lv2 (name: &str, path: &str) -> Usually<JackDevice<Tui>> {
pub fn new_lv2 (
jack: &Arc<RwLock<JackClient>>,
name: &str,
path: &str,
) -> Usually<JackDevice<Tui>> {
let plugin = LV2Plugin::new(path)?;
jack_from_lv2(name, &plugin.plugin)?
.run(|ports|Box::new(Self {
_engine: Default::default(),
jack: jack.clone(),
name: name.into(),
path: Some(String::from(path)),
plugin: Some(PluginKind::LV2(plugin)),

View file

@ -1,6 +1,23 @@
//! Plugin host
include!("lib.rs");
pub fn main () -> Usually<()> {
Tui::run(Arc::new(RwLock::new(crate::Plugin::new("")?)))?;
Ok(())
use tek_core::clap::{self, Parser};
pub fn main () -> Usually<()> { PluginCli::parse().run() }
#[derive(Debug, Parser)] #[command(version, about, long_about = None)] pub struct PluginCli {
/// Name of JACK client
#[arg(short, long)] name: Option<String>,
/// Path to plugin
#[arg(short, long)] path: Option<String>,
}
impl PluginCli {
fn run (&self) -> Usually<()> {
Tui::run(JackClient::new("tek_plugin")?.activate_with(|jack|{
let mut plugin = Plugin::new_lv2(
jack,
self.name.as_ref().map(|x|x.as_str()).unwrap_or("mixer"),
self.path.as_ref().expect("pass --path /to/lv2/plugin.so")
)?;
Ok(plugin)
})?)?;
Ok(())
}
}

View file

@ -1,7 +1,9 @@
use crate::*;
/// The sampler plugin plays sounds.
pub struct Sampler {
pub struct Sampler<E: Engine> {
_engine: PhantomData<E>,
pub jack: Arc<RwLock<JackClient>>,
pub name: String,
pub cursor: (usize, usize),
pub editing: Option<Arc<RwLock<Sample>>>,
@ -14,7 +16,7 @@ pub struct Sampler {
pub output_gain: f32
}
impl Sampler {
impl<E: Engine> Sampler<E> {
pub fn from_edn <'e> (args: &[Edn<'e>]) -> Usually<JackDevice<Tui>> {
let mut name = String::new();
let mut dir = String::new();
@ -54,6 +56,7 @@ impl Sampler {
.audio_out("outL")
.audio_out("outR")
.run(|ports|Box::new(Self {
_engine: Default::default(),
name: name.into(),
cursor: (0, 0),
editing: None,
@ -135,7 +138,7 @@ impl Sampler {
}
}
impl Audio for Sampler {
impl<E: Engine> Audio for Sampler<E> {
fn process (&mut self, _: &Client, scope: &ProcessScope) -> Control {
self.process_midi_in(scope);
self.clear_output_buffer();
@ -144,7 +147,7 @@ impl Audio for Sampler {
Control::Continue
}
}
impl Handle<Tui> for Sampler {
impl Handle<Tui> for Sampler<Tui> {
fn handle (&mut self, from: &TuiInput) -> Perhaps<bool> {
match from.event() {
key!(KeyCode::Up) => {
@ -188,7 +191,7 @@ impl Handle<Tui> for Sampler {
}
}
impl Widget for Sampler {
impl Widget for Sampler<Tui> {
type Engine = Tui;
fn layout (&self, to: [u16;2]) -> Perhaps<[u16;2]> {
todo!()
@ -198,7 +201,7 @@ impl Widget for Sampler {
}
}
pub fn tui_render_sampler (sampler: &Sampler, to: &mut TuiOutput) -> Usually<()> {
pub fn tui_render_sampler (sampler: &Sampler<Tui>, to: &mut TuiOutput) -> Usually<()> {
let [x, y, _, height] = to.area();
let style = Style::default().gray();
let title = format!(" {} ({})", sampler.name, sampler.voices.read().unwrap().len());

View file

@ -1,6 +1,22 @@
//! Sample player
include!("lib.rs");
pub fn main () -> Usually<()> {
Tui::run(Arc::new(RwLock::new(crate::Sampler::new("", None)?)))?;
Ok(())
use tek_core::clap::{self, Parser};
pub fn main () -> Usually<()> { SamplerCli::parse().run() }
#[derive(Debug, Parser)] #[command(version, about, long_about = None)] pub struct SamplerCli {
/// Name of JACK client
#[arg(short, long)] name: Option<String>,
/// Path to plugin
#[arg(short, long)] path: Option<String>,
}
impl SamplerCli {
fn run (&self) -> Usually<()> {
Tui::run(JackClient::new("tek_sampler")?.activate_with(|jack|{
let mut plugin = Sampler::new(
jack,
self.name.as_ref().map(|x|x.as_str()).unwrap_or("mixer"),
)?;
Ok(plugin)
})?)?;
Ok(())
}
}