wip: refactor pt.41 (57e) nice

This commit is contained in:
🪞👃🪞 2024-11-15 20:09:49 +01:00
parent c875d87c33
commit 8856353eab
32 changed files with 911 additions and 1019 deletions

View file

@ -5,14 +5,13 @@ pub trait HasPlayer: HasJack {
fn player_mut (&mut self) -> &mut impl PlayerApi;
}
pub trait PlayerApi: MidiInputApi + MidiOutputApi {}
pub trait PlayerApi: MidiInputApi + MidiOutputApi + Send + Sync {}
pub trait HasMidiBuffer {
fn midi_buffer (&self) -> &Vec<Vec<Vec<u8>>>;
fn midi_buffer_mut (&self) -> &mut Vec<Vec<Vec<u8>>>;
fn reset (&self) -> bool;
fn reset_mut (&mut self) -> &mut bool;
/// Clear the section of the output buffer that we will be using,
@ -285,3 +284,100 @@ pub fn update_keys (keys: &mut[bool;128], message: &MidiMessage) {
_ => {}
}
}
/// Hosts the JACK callback for a single MIDI player
pub struct PlayerAudio<'a, T: PlayerApi>(
/// Player
pub &'a mut T,
/// Note buffer
pub &'a mut Vec<u8>,
/// Note chunk buffer
pub &'a mut Vec<Vec<Vec<u8>>>,
);
/// JACK process callback for a sequencer's phrase player/recorder.
impl<'a, T: PlayerApi> Audio for PlayerAudio<'a, T> {
fn process (&mut self, _: &Client, scope: &ProcessScope) -> Control {
let model = &mut self.0;
let note_buffer = &mut self.1;
let output_buffer = &mut self.2;
// Clear output buffer(s)
model.clear(scope, false);
// Write chunk of phrase to output, handle switchover
if model.play(scope, note_buffer, output_buffer) {
model.switchover(scope, note_buffer, output_buffer);
}
if model.has_midi_ins() {
if model.recording() || model.monitoring() {
// Record and/or monitor input
model.record(scope)
} else if model.has_midi_outs() && model.monitoring() {
// Monitor input to output
model.monitor(scope)
}
}
// Write to output port(s)
model.write(scope, output_buffer);
Control::Continue
}
}
//#[derive(Debug)]
//pub struct MIDIPlayer {
///// Global timebase
//pub clock: Arc<Clock>,
///// Start time and phrase being played
//pub play_phrase: Option<(Instant, Option<Arc<RwLock<Phrase>>>)>,
///// Start time and next phrase
//pub next_phrase: Option<(Instant, Option<Arc<RwLock<Phrase>>>)>,
///// Play input through output.
//pub monitoring: bool,
///// Write input to sequence.
//pub recording: bool,
///// Overdub input to sequence.
//pub overdub: bool,
///// Send all notes off
//pub reset: bool, // TODO?: after Some(nframes)
///// Record from MIDI ports to current sequence.
//pub midi_inputs: Vec<Port<MidiIn>>,
///// Play from current sequence to MIDI ports
//pub midi_outputs: Vec<Port<MidiOut>>,
///// MIDI output buffer
//pub midi_note: Vec<u8>,
///// MIDI output buffer
//pub midi_chunk: Vec<Vec<Vec<u8>>>,
///// Notes currently held at input
//pub notes_in: Arc<RwLock<[bool; 128]>>,
///// Notes currently held at output
//pub notes_out: Arc<RwLock<[bool; 128]>>,
//}
///// Methods used primarily by the process callback
//impl MIDIPlayer {
//pub fn new (
//jack: &Arc<RwLock<JackClient>>,
//clock: &Arc<Clock>,
//name: &str
//) -> Usually<Self> {
//let jack = jack.read().unwrap();
//Ok(Self {
//clock: clock.clone(),
//phrase: None,
//next_phrase: None,
//notes_in: Arc::new(RwLock::new([false;128])),
//notes_out: Arc::new(RwLock::new([false;128])),
//monitoring: false,
//recording: false,
//overdub: true,
//reset: true,
//midi_note: Vec::with_capacity(8),
//midi_chunk: vec![Vec::with_capacity(16);16384],
//midi_outputs: vec![
//jack.client().register_port(format!("{name}_out0").as_str(), MidiOut::default())?
//],
//midi_inputs: vec![
//jack.client().register_port(format!("{name}_in0").as_str(), MidiIn::default())?
//],
//})
//}
//}