tek/crates/tek_mixer/src/plugin_lv2.rs

74 lines
2.1 KiB
Rust

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 {
pub fn from_edn <'e> (args: &[Edn<'e>]) -> Usually<JackDevice<Tui>> {
let mut name = String::new();
let mut path = String::new();
edn!(edn in args {
Edn::Map(map) => {
if let Some(Edn::Str(n)) = map.get(&Edn::Key(":name")) {
name = String::from(*n);
}
if let Some(Edn::Str(p)) = map.get(&Edn::Key(":path")) {
path = String::from(*p);
}
},
_ => panic!("unexpected in lv2 '{name}'"),
});
Plugin::new_lv2(&name, &path)
}
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.unwrap();
let err = &format!("init {uri}");
// Instantiate
Ok(Self {
world,
instance: unsafe {
plugin
.instantiate(features.clone(), 48000.0)
.expect(&err)
},
port_list: {
let mut port_list = vec![];
for port in plugin.ports() {
port_list.push(port);
}
port_list
},
plugin,
features,
input_buffer: Vec::with_capacity(1024),
ui_thread: None
})
}
}