wip: enabling autoconnecting ports

This commit is contained in:
🪞👃🪞 2025-01-09 20:40:26 +01:00
parent c23f52c87b
commit fe70b57dc1
10 changed files with 375 additions and 424 deletions

View file

@ -2,8 +2,8 @@ use crate::*;
/// Trait for thing that may receive MIDI.
pub trait HasMidiIns {
fn midi_ins (&self) -> &Vec<Port<MidiIn>>;
fn midi_ins_mut (&mut self) -> &mut Vec<Port<MidiIn>>;
fn midi_ins (&self) -> &Vec<JackPort<MidiIn>>;
fn midi_ins_mut (&mut self) -> &mut Vec<JackPort<MidiIn>>;
fn has_midi_ins (&self) -> bool {
!self.midi_ins().is_empty()
}
@ -27,7 +27,7 @@ pub trait MidiRecordApi: HasClock + HasPlayPhrase + HasMidiIns {
let notes_in = self.notes_in().clone();
let monitoring = self.monitoring();
for input in self.midi_ins_mut().iter() {
for (sample, event, bytes) in parse_midi_input(input.iter(scope)) {
for (sample, event, bytes) in parse_midi_input(input.port.iter(scope)) {
if let LiveEvent::Midi { message, .. } = event {
if monitoring {
midi_buf[sample].push(bytes.to_vec());
@ -67,7 +67,7 @@ pub trait MidiRecordApi: HasClock + HasPlayPhrase + HasMidiIns {
let mut phrase = phrase.write().unwrap();
let length = phrase.length;
for input in self.midi_ins_mut().iter() {
for (sample, event, bytes) in parse_midi_input(input.iter(scope)) {
for (sample, event, bytes) in parse_midi_input(input.port.iter(scope)) {
if let LiveEvent::Midi { message, .. } = event {
phrase.record_event({
let sample = (sample0 + sample - start) as f64;

View file

@ -2,8 +2,8 @@ use crate::*;
/// Trait for thing that may output MIDI.
pub trait HasMidiOuts {
fn midi_outs (&self) -> &Vec<Port<MidiOut>>;
fn midi_outs_mut (&mut self) -> &mut Vec<Port<MidiOut>>;
fn midi_outs (&self) -> &Vec<JackPort<MidiOut>>;
fn midi_outs_mut (&mut self) -> &mut Vec<JackPort<MidiOut>>;
fn has_midi_outs (&self) -> bool {
!self.midi_outs().is_empty()
}
@ -143,7 +143,7 @@ pub trait MidiPlaybackApi: HasPlayPhrase + HasClock + HasMidiOuts {
fn write (&mut self, scope: &ProcessScope, out: &[Vec<Vec<u8>>]) {
let samples = scope.n_frames() as usize;
for port in self.midi_outs_mut().iter_mut() {
Self::write_port(&mut port.writer(scope), samples, out)
Self::write_port(&mut port.port.writer(scope), samples, out)
}
}

View file

@ -35,9 +35,9 @@ pub struct MidiPlayer {
/// Send all notes off
pub reset: bool, // TODO?: after Some(nframes)
/// Record from MIDI ports to current sequence.
pub midi_ins: Vec<Port<MidiIn>>,
pub midi_ins: Vec<JackPort<MidiIn>>,
/// Play from current sequence to MIDI ports
pub midi_outs: Vec<Port<MidiOut>>,
pub midi_outs: Vec<JackPort<MidiOut>>,
/// Notes currently held at input
pub notes_in: Arc<RwLock<[bool; 128]>>,
/// Notes currently held at output
@ -47,33 +47,28 @@ pub struct MidiPlayer {
}
impl MidiPlayer {
pub fn new (
jack: &Arc<RwLock<JackConnection>>,
name: impl AsRef<str>,
clip: Option<&Arc<RwLock<MidiClip>>>,
midi_from: &[impl AsRef<str>],
midi_to: &[impl AsRef<str>],
jack: &Arc<RwLock<JackConnection>>,
name: impl AsRef<str>,
clip: Option<&Arc<RwLock<MidiClip>>>,
midi_from: &[PortConnection],
midi_to: &[PortConnection],
) -> Usually<Self> {
let name = name.as_ref();
let midi_in = jack.midi_in(&format!("M/{name}"), midi_from)?;
jack.connect_midi_from(&midi_in, midi_from)?;
let midi_out = jack.midi_out(&format!("{name}/M"), midi_to)?;
jack.connect_midi_to(&midi_out, midi_to)?;
let clock = Clock::from(jack);
let name = name.as_ref();
let clock = Clock::from(jack);
Ok(Self {
play_phrase: Some((Moment::zero(&clock.timebase), clip.cloned())),
next_phrase: None,
recording: false,
monitoring: false,
overdub: false,
notes_in: RwLock::new([false;128]).into(),
midi_ins: vec![midi_in],
midi_outs: vec![midi_out],
notes_out: RwLock::new([false;128]).into(),
note_buf: vec![0;8],
reset: true,
notes_in: RwLock::new([false;128]).into(),
notes_out: RwLock::new([false;128]).into(),
note_buf: vec![0;8],
reset: true,
midi_ins: vec![JackPort::<MidiIn>::new(jack, format!("M/{name}"), midi_from)?,],
midi_outs: vec![JackPort::<MidiOut>::new(jack, format!("{name}/M"), midi_to)?, ],
clock,
})
}
@ -114,26 +109,14 @@ from!(|state: (&Clock, &Arc<RwLock<MidiClip>>)|MidiPlayer = {
model
});
has_clock!(|self: MidiPlayer|&self.clock);
impl HasMidiIns for MidiPlayer {
fn midi_ins (&self) -> &Vec<Port<MidiIn>> {
&self.midi_ins
}
fn midi_ins_mut (&mut self) -> &mut Vec<Port<MidiIn>> {
&mut self.midi_ins
}
fn midi_ins (&self) -> &Vec<JackPort<MidiIn>> { &self.midi_ins }
fn midi_ins_mut (&mut self) -> &mut Vec<JackPort<MidiIn>> { &mut self.midi_ins }
}
impl HasMidiOuts for MidiPlayer {
fn midi_outs (&self) -> &Vec<Port<MidiOut>> {
&self.midi_outs
}
fn midi_outs_mut (&mut self) -> &mut Vec<Port<MidiOut>> {
&mut self.midi_outs
}
fn midi_note (&mut self) -> &mut Vec<u8> {
&mut self.note_buf
}
fn midi_outs (&self) -> &Vec<JackPort<MidiOut>> { &self.midi_outs }
fn midi_outs_mut (&mut self) -> &mut Vec<JackPort<MidiOut>> { &mut self.midi_outs }
fn midi_note (&mut self) -> &mut Vec<u8> { &mut self.note_buf }
}
/// Hosts the JACK callback for a single MIDI player