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, pub port_list: Vec, pub input_buffer: Vec, pub ui_thread: Option>, } impl LV2Plugin { pub fn from_edn <'e, T, U> (args: &[Edn<'e>]) -> Usually> { 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 { // 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 }) } }