From c875d87c3321ee27cf7f8557310252712f381d06 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Fri, 15 Nov 2024 13:36:06 +0100 Subject: [PATCH] wip: refactor pt.38 (27e) pass midi out bufs from outside --- crates/tek_api/src/api_player.rs | 50 ++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/crates/tek_api/src/api_player.rs b/crates/tek_api/src/api_player.rs index 12cbb2e3..55487421 100644 --- a/crates/tek_api/src/api_player.rs +++ b/crates/tek_api/src/api_player.rs @@ -8,7 +8,8 @@ pub trait HasPlayer: HasJack { pub trait PlayerApi: MidiInputApi + MidiOutputApi {} pub trait HasMidiBuffer { - fn midi_buffer (&self) -> &mut Vec>>; + fn midi_buffer (&self) -> &Vec>>; + fn midi_buffer_mut (&self) -> &mut Vec>>; fn reset (&self) -> bool; @@ -17,11 +18,11 @@ pub trait HasMidiBuffer { /// Clear the section of the output buffer that we will be using, /// emitting "all notes off" at start of buffer if requested. fn clear (&mut self, scope: &ProcessScope, force_reset: bool) { - for frame in &mut self.midi_buffer()[0..scope.n_frames() as usize] { + for frame in &mut self.midi_buffer_mut()[0..scope.n_frames() as usize] { frame.clear(); } if self.reset() || force_reset { - all_notes_off(&mut self.midi_buffer()); + all_notes_off(&mut self.midi_buffer_mut()); *self.reset_mut() = false; } } @@ -92,7 +93,7 @@ pub trait MidiInputApi: PlayheadApi + HasMidiBuffer + HasPhrase { for (sample, event, bytes) in parse_midi_input(input.iter(scope)) { if let LiveEvent::Midi { message, .. } = event { if self.monitoring() { - self.midi_buffer()[sample].push(bytes.to_vec()) + self.midi_buffer_mut()[sample].push(bytes.to_vec()) } if self.recording() { if let Some(phrase) = phrase { @@ -122,7 +123,7 @@ pub trait MidiInputApi: PlayheadApi + HasMidiBuffer + HasPhrase { for input in self.midi_ins_mut().iter() { for (sample, event, bytes) in parse_midi_input(input.iter(scope)) { if let LiveEvent::Midi { message, .. } = event { - self.midi_buffer()[sample].push(bytes.to_vec()); + self.midi_buffer_mut()[sample].push(bytes.to_vec()); update_keys(&mut notes_in, &message); } } @@ -144,7 +145,12 @@ pub trait MidiOutputApi: PlayheadApi + HasMidiBuffer + HasPhrase { self.midi_outs().len() > 0 } - fn play (&mut self, scope: &ProcessScope) -> bool { + fn play ( + &mut self, + scope: &ProcessScope, + note_buffer: &mut Vec, + output_buffer: &mut Vec>> + ) -> bool { let mut next = false; // Write MIDI events from currently playing phrase (if any) to MIDI output buffer if self.is_rolling() { @@ -152,13 +158,11 @@ pub trait MidiOutputApi: PlayheadApi + HasMidiBuffer + HasPhrase { let samples = scope.n_frames() as usize; // If no phrase is playing, prepare for switchover immediately next = self.phrase().is_none(); - let mut midi_note = self.midi_note(); - let ref phrase = self.phrase(); - let ref started0 = self.started(); - let ref timebase = self.timebase(); - let ref notes_out = self.notes_out(); - let ref next_phrase = self.next_phrase(); - let ref midi_buffer = self.midi_buffer(); + let phrase = self.phrase(); + let started0 = self.started(); + let timebase = self.timebase(); + let notes_out = self.notes_out(); + let next_phrase = self.next_phrase(); if let Some((started, phrase)) = phrase { // First sample to populate. Greater than 0 means that the first // pulse of the phrase falls somewhere in the middle of the chunk. @@ -191,15 +195,15 @@ pub trait MidiOutputApi: PlayheadApi + HasMidiBuffer + HasPhrase { // Output each MIDI event from phrase at appropriate frames of output buffer: for message in phrase.notes[pulse].iter() { // Clear output buffer for this MIDI event. - midi_note.clear(); + note_buffer.clear(); // TODO: support MIDI channels other than CH1. let channel = 0.into(); // Serialize MIDI event into message buffer. LiveEvent::Midi { channel, message: *message } - .write(&mut midi_note) + .write(note_buffer) .unwrap(); // Append serialized message to output buffer. - midi_buffer[sample].push(midi_note.clone()); + output_buffer[sample].push(note_buffer.clone()); // Update the list of currently held notes. update_keys(&mut*notes, &message); } @@ -210,7 +214,12 @@ pub trait MidiOutputApi: PlayheadApi + HasMidiBuffer + HasPhrase { next } - fn switchover (&mut self, scope: &ProcessScope) { + fn switchover ( + &mut self, + scope: &ProcessScope, + note_buffer: &mut Vec, + output_buffer: &mut Vec>> + ) { if self.is_rolling() { let sample0 = scope.last_frame_time() as usize; //let samples = scope.n_frames() as usize; @@ -229,20 +238,19 @@ pub trait MidiOutputApi: PlayheadApi + HasMidiBuffer + HasPhrase { } // TODO fill in remaining ticks of chunk from next phrase. // ?? just call self.play(scope) again, since enqueuement is off ??? - self.play(scope); + self.play(scope, note_buffer, output_buffer); // ?? or must it be with modified scope ?? // likely not because start time etc } } } - fn write (&mut self, scope: &ProcessScope) { + fn write (&mut self, scope: &ProcessScope, output_buffer: &Vec>>) { let samples = scope.n_frames() as usize; for port in self.midi_outs_mut().iter_mut() { let writer = &mut port.writer(scope); - let output = &self.midi_buffer(); for time in 0..samples { - for event in output[time].iter() { + for event in output_buffer[time].iter() { writer.write(&RawMidi { time: time as u32, bytes: &event }) .expect(&format!("{event:?}")); }