wip: p.42, e=22, more intermediary trait layers

This commit is contained in:
🪞👃🪞 2024-11-16 21:31:04 +01:00
parent 638298ad32
commit dbf6e353b7
15 changed files with 937 additions and 688 deletions

View file

@ -7,27 +7,10 @@ pub trait HasPlayer: HasJack {
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>>>;
pub trait HasPhrase: PlayheadApi {
fn reset (&self) -> bool;
fn reset_mut (&mut self) -> &mut bool;
/// 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_mut()[0..scope.n_frames() as usize] {
frame.clear();
}
if self.reset() || force_reset {
all_notes_off(&mut self.midi_buffer_mut());
*self.reset_mut() = false;
}
}
}
pub trait HasPhrase: PlayheadApi + HasMidiBuffer {
fn phrase (&self)
-> &Option<(Instant, Option<Arc<RwLock<Phrase>>>)>;
fn phrase_mut (&self)
@ -54,7 +37,7 @@ pub trait HasPhrase: PlayheadApi + HasMidiBuffer {
}
}
pub trait MidiInputApi: PlayheadApi + HasMidiBuffer + HasPhrase {
pub trait MidiInputApi: PlayheadApi + HasPhrase {
fn midi_ins (&self) -> &Vec<Port<MidiIn>>;
fn midi_ins_mut (&self) -> &mut Vec<Port<MidiIn>>;
fn has_midi_ins (&self) -> bool {
@ -80,7 +63,11 @@ pub trait MidiInputApi: PlayheadApi + HasMidiBuffer + HasPhrase {
fn notes_in (&self) -> &Arc<RwLock<[bool;128]>>;
fn record (&mut self, scope: &ProcessScope) {
fn record (
&mut self,
scope: &ProcessScope,
midi_buf: &mut Vec<Vec<Vec<u8>>>,
) {
let sample0 = scope.last_frame_time() as usize;
if let (true, Some((started, phrase))) = (self.is_rolling(), self.phrase()) {
let start = started.sample.get() as usize;
@ -92,7 +79,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_mut()[sample].push(bytes.to_vec())
midi_buf[sample].push(bytes.to_vec())
}
if self.recording() {
if let Some(phrase) = phrase {
@ -117,12 +104,16 @@ pub trait MidiInputApi: PlayheadApi + HasMidiBuffer + HasPhrase {
}
}
fn monitor (&mut self, scope: &ProcessScope) {
fn monitor (
&mut self,
scope: &ProcessScope,
midi_buf: &mut Vec<Vec<Vec<u8>>>,
) {
let mut notes_in = self.notes_in().write().unwrap();
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_mut()[sample].push(bytes.to_vec());
midi_buf[sample].push(bytes.to_vec());
update_keys(&mut notes_in, &message);
}
}
@ -131,7 +122,7 @@ pub trait MidiInputApi: PlayheadApi + HasMidiBuffer + HasPhrase {
}
pub trait MidiOutputApi: PlayheadApi + HasMidiBuffer + HasPhrase {
pub trait MidiOutputApi: PlayheadApi + HasPhrase {
fn midi_outs (&self) -> &Vec<Port<MidiOut>>;
fn midi_outs_mut (&mut self) -> &mut Vec<Port<MidiOut>>;
@ -144,6 +135,22 @@ pub trait MidiOutputApi: PlayheadApi + HasMidiBuffer + HasPhrase {
self.midi_outs().len() > 0
}
/// 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,
midi_buf: &mut Vec<Vec<Vec<u8>>>,
reset: bool
) {
for frame in &mut midi_buf[0..scope.n_frames() as usize] {
frame.clear();
}
if reset {
all_notes_off(midi_buf);
}
}
fn play (
&mut self,
scope: &ProcessScope,
@ -298,26 +305,26 @@ pub struct PlayerAudio<'a, T: PlayerApi>(
/// 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;
let model = &mut self.0;
let note_buf = &mut self.1;
let midi_buf = &mut self.2;
// Clear output buffer(s)
model.clear(scope, false);
model.clear(scope, midi_buf, 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.play(scope, note_buf, midi_buf) {
model.switchover(scope, note_buf, midi_buf);
}
if model.has_midi_ins() {
if model.recording() || model.monitoring() {
// Record and/or monitor input
model.record(scope)
model.record(scope, midi_buf)
} else if model.has_midi_outs() && model.monitoring() {
// Monitor input to output
model.monitor(scope)
model.monitor(scope, midi_buf)
}
}
// Write to output port(s)
model.write(scope, output_buffer);
model.write(scope, midi_buf);
Control::Continue
}
}