use crate::*; //impl_port!(MidiInput: MidiOut -> MidiIn |j, n|j.register_port::(n)); #[derive(Debug)] pub struct MidiInput { /// Handle to JACK client, for receiving reconnect events. jack: Jack<'static>, /// Port name name: Arc, /// Port handle. port: Port, /// List of currently held notes. held: Arc>, /// List of ports to connect to. pub connections: Vec, } has!(Jack<'static>: |self: MidiInput|self.jack); impl JackPort for MidiInput { type Port = MidiIn; type Pair = MidiOut; fn name (&self) -> &Arc { &self.name } fn port (&self) -> &Port { &self.port } fn port_mut (&mut self) -> &mut Port { &mut self.port } fn into_port (self) -> Port { self.port } fn connections (&self) -> &[Connect] { self.connections.as_slice() } fn new (jack: &Jack<'static>, name: &impl AsRef, connect: &[Connect]) -> Usually where Self: Sized { let port = Self { port: Self::register(jack, name)?, jack: jack.clone(), name: name.as_ref().into(), connections: connect.to_vec(), held: Arc::new(RwLock::new([false;128])) }; port.connect_to_matching()?; Ok(port) } } impl MidiInput { pub fn parsed <'a> (&'a self, scope: &'a ProcessScope) -> impl Iterator, &'a [u8])> { parse_midi_input(self.port().iter(scope)) } } #[tengri_proc::command(MidiInput)] impl MidiInputCommand { //fn _todo_ (_port: &mut MidiInput) -> Perhaps { Ok(None) } } impl>> HasMidiIns for T { fn midi_ins (&self) -> &Vec { self.get() } fn midi_ins_mut (&mut self) -> &mut Vec { self.get_mut() } } /// Trait for thing that may receive MIDI. pub trait HasMidiIns { fn midi_ins (&self) -> &Vec; fn midi_ins_mut (&mut self) -> &mut Vec; /// Collect MIDI input from app ports (TODO preallocate large buffers) fn midi_input_collect <'a> (&'a self, scope: &'a ProcessScope) -> CollectedMidiInput<'a> { self.midi_ins().iter() .map(|port|port.port().iter(scope) .map(|RawMidi { time, bytes }|(time, LiveEvent::parse(bytes))) .collect::>()) .collect::>() } fn midi_ins_with_sizes <'a> (&'a self) -> impl Iterator, &[Connect], usize, usize)> + Send + Sync + 'a { let mut y = 0; self.midi_ins().iter().enumerate().map(move|(i, input)|{ let height = 1 + input.connections().len(); let data = (i, input.name(), input.connections(), y, y + height); y += height; data }) } } pub type CollectedMidiInput<'a> = Vec, MidiError>)>>; impl> AddMidiIn for T { fn midi_in_add (&mut self) -> Usually<()> { let index = self.midi_ins().len(); let port = MidiInput::new(self.jack(), &format!("M/{index}"), &[])?; self.midi_ins_mut().push(port); Ok(()) } } /// May create new MIDI input ports. pub trait AddMidiIn { fn midi_in_add (&mut self) -> Usually<()>; }