use crate::*; /// A plugin device. #[derive(Debug)] pub struct Plugin { /// JACK client handle (needs to not be dropped for standalone mode to work). pub jack: Arc>, pub name: String, pub path: Option, pub plugin: Option, pub selected: usize, pub mapping: bool, pub midi_ins: Vec>, pub midi_outs: Vec>, pub audio_ins: Vec>, pub audio_outs: Vec>, } impl Plugin { pub fn new_lv2 ( jack: &Arc>, name: &str, path: &str, ) -> Usually { Ok(Self { jack: jack.clone(), name: name.into(), path: Some(String::from(path)), plugin: Some(PluginKind::LV2(LV2Plugin::new(path)?)), selected: 0, mapping: false, midi_ins: vec![], midi_outs: vec![], audio_ins: vec![], audio_outs: vec![], }) } //fn jack_from_lv2 (name: &str, plugin: &::livi::Plugin) -> Usually { //let counts = plugin.port_counts(); //let mut jack = Jack::new(name)?; //for i in 0..counts.atom_sequence_inputs { //jack = jack.midi_in(&format!("midi-in-{i}")) //} //for i in 0..counts.atom_sequence_outputs { //jack = jack.midi_out(&format!("midi-out-{i}")); //} //for i in 0..counts.audio_inputs { //jack = jack.audio_in(&format!("audio-in-{i}")); //} //for i in 0..counts.audio_outputs { //jack = jack.audio_out(&format!("audio-out-{i}")); //} //Ok(jack) //} } pub struct PluginAudio(Arc>); impl From<&Arc>> for PluginAudio { fn from (model: &Arc>) -> Self { Self(model.clone()) } } impl Audio for PluginAudio { fn process (&mut self, _: &Client, scope: &ProcessScope) -> Control { let state = &mut*self.0.write().unwrap(); match state.plugin.as_mut() { Some(PluginKind::LV2(LV2Plugin { features, ref mut instance, ref mut input_buffer, .. })) => { let urid = features.midi_urid(); input_buffer.clear(); for port in state.midi_ins.iter() { let mut atom = ::livi::event::LV2AtomSequence::new( &features, scope.n_frames() as usize ); for event in port.iter(scope) { match event.bytes.len() { 3 => atom.push_midi_event::<3>( event.time as i64, urid, &event.bytes[0..3] ).unwrap(), _ => {} } } input_buffer.push(atom); } let mut outputs = vec![]; for _ in state.midi_outs.iter() { outputs.push(::livi::event::LV2AtomSequence::new( &features, scope.n_frames() as usize )); } let ports = ::livi::EmptyPortConnections::new() .with_atom_sequence_inputs(input_buffer.iter()) .with_atom_sequence_outputs(outputs.iter_mut()) .with_audio_inputs(state.audio_ins.iter().map(|o|o.as_slice(scope))) .with_audio_outputs(state.audio_outs.iter_mut().map(|o|o.as_mut_slice(scope))); unsafe { instance.run(scope.n_frames() as usize, ports).unwrap() }; }, _ => {} } Control::Continue } }