wip: general overhaul of core and ports
Some checks are pending
/ build (push) Waiting to run

This commit is contained in:
🪞👃🪞 2025-05-20 22:05:09 +03:00
parent 573534a9a6
commit 447638ee71
30 changed files with 824 additions and 548 deletions

View file

@ -1,29 +1,119 @@
use crate::*;
impl JackMidiIn {
//impl_port!(MidiInput: MidiOut -> MidiIn |j, n|j.register_port::<MidiOut>(n));
#[derive(Debug)] pub struct MidiInput<'j> {
/// Handle to JACK client, for receiving reconnect events.
jack: Jack<'j>,
/// Port name
name: Arc<str>,
/// Port handle.
port: Port<MidiOut>,
/// List of ports to connect to.
connections: Vec<Connect>
}
impl<'j> AsRef<Port<MidiOut>> for MidiInput<'j> {
fn as_ref (&self) -> &Port<MidiOut> { &self.port }
}
impl<'j> MidiInput<'j> {
pub fn new (jack: &Jack, name: impl AsRef<str>, connect: &[Connect])
-> Usually<Self>
{
let port = Self {
port: jack.register_port::<MidiIn>(name.as_ref())?,
jack,
name: name.into(),
connections: connect.to_vec()
};
port.connect_to_matching()?;
Ok(port)
}
pub fn name (&self) -> &Arc<str> {
&self.name
}
pub fn port (&self) -> &Port<MidiOut> {
&self.port
}
pub fn port_mut (&mut self) -> &mut Port<MidiOut> {
&mut self.port
}
pub fn into_port (self) -> Port<MidiOut> {
self.port
}
pub fn close (self) -> Usually<()> {
let Self { jack, port, .. } = self;
Ok(jack.with_client(|client|client.unregister_port(port))?)
}
pub fn parsed <'a> (&'a self, scope: &'a ProcessScope) -> impl Iterator<Item=(usize, LiveEvent<'a>, &'a [u8])> {
parse_midi_input(self.port().iter(scope))
}
}
#[tengri_proc::command(JackMidiIn)]
impl MidiInputCommand {
fn _todo_ (_port: &mut JackMidiIn) -> Perhaps<Self> { Ok(None) }
impl<'j> HasJack<'j> for MidiInput<'j> {
fn jack (&self) -> &'j Jack<'j> { &self.jack }
}
impl<'j> JackPort<'j> for MidiInput<'j> {
type Port = MidiIn;
type Pair = MidiOut;
fn port (&self) -> &Port<MidiOut> { &self.port }
}
//impl<'j, T: AsRef<str>> ConnectTo<'j, T> for MidiInput<'j> {
//fn connect_to (&self, to: &T) -> Usually<ConnectStatus> {
//self.with_client(|c|if let Some(ref port) = c.port_by_name(to.as_ref()) {
//self.connect_to(port)
//} else {
//Ok(Missing)
//})
//}
//}
connect_to!(<'j>|self: MidiInput<'j>, port: &str|{
self.with_client(|c|if let Some(ref port) = c.port_by_name(port.as_ref()) {
self.connect_to(port)
} else {
Ok(Missing)
})
});
connect_to!(<'j>|self: MidiInput<'j>, port: Port<MidiOut>|{
self.with_client(|c|Ok(if let Ok(_) = c.connect_ports(&self.port, port) {
Connected
} else if let Ok(_) = c.connect_ports(port, &self.port) {
Connected
} else {
Mismatch
}))
});
connect_to!(<'j>|self: MidiInput<'j>, port: Port<Unowned>|{
self.with_client(|c|Ok(if let Ok(_) = c.connect_ports(&self.port, port) {
Connected
} else if let Ok(_) = c.connect_ports(port, &self.port) {
Connected
} else {
Mismatch
}))
});
impl<'j> ConnectAuto<'j> for MidiInput<'j> {
fn connections (&self) -> &[Connect] {
&self.connections
}
}
impl<T: Has<Vec<JackMidiIn>>> HasMidiIns for T {
fn midi_ins (&self) -> &Vec<JackMidiIn> {
#[tengri_proc::command(MidiInput)]
impl MidiInputCommand {
//fn _todo_ (_port: &mut MidiInput) -> Perhaps<Self> { Ok(None) }
}
impl<T: Has<Vec<MidiInput>>> HasMidiIns for T {
fn midi_ins (&self) -> &Vec<MidiInput> {
self.get()
}
fn midi_ins_mut (&mut self) -> &mut Vec<JackMidiIn> {
fn midi_ins_mut (&mut self) -> &mut Vec<MidiInput> {
self.get_mut()
}
}
/// Trait for thing that may receive MIDI.
pub trait HasMidiIns {
fn midi_ins (&self) -> &Vec<JackMidiIn>;
fn midi_ins_mut (&mut self) -> &mut Vec<JackMidiIn>;
fn midi_ins (&self) -> &Vec<MidiInput>;
fn midi_ins_mut (&mut self) -> &mut Vec<MidiInput>;
/// 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()
@ -33,7 +123,7 @@ pub trait HasMidiIns {
.collect::<Vec<_>>()
}
fn midi_ins_with_sizes <'a> (&'a self) ->
impl Iterator<Item=(usize, &Arc<str>, &[PortConnect], usize, usize)> + Send + Sync + 'a
impl Iterator<Item=(usize, &Arc<str>, &[Connect], usize, usize)> + Send + Sync + 'a
{
let mut y = 0;
self.midi_ins().iter().enumerate().map(move|(i, input)|{
@ -47,10 +137,10 @@ pub trait HasMidiIns {
pub type CollectedMidiInput<'a> = Vec<Vec<(u32, Result<LiveEvent<'a>, MidiError>)>>;
impl<T: HasMidiIns + HasJack> AddMidiIn for T {
impl<'j, T: HasMidiIns + HasJack<'j>> AddMidiIn for T {
fn midi_in_add (&mut self) -> Usually<()> {
let index = self.midi_ins().len();
let port = JackMidiIn::new(self.jack(), &format!("M/{index}"), &[])?;
let port = MidiInput::new(self.jack(), &format!("M/{index}"), &[])?;
self.midi_ins_mut().push(port);
Ok(())
}