refactor midi module

This commit is contained in:
🪞👃🪞 2025-01-02 13:32:08 +01:00
parent 1723826cc2
commit 7f55c3bfc8
8 changed files with 333 additions and 330 deletions

91
src/midi/midi_in.rs Normal file
View file

@ -0,0 +1,91 @@
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 has_midi_ins (&self) -> bool {
!self.midi_ins().is_empty()
}
}
pub trait MidiRecordApi: HasClock + HasPlayPhrase + HasMidiIns {
fn notes_in (&self) -> &Arc<RwLock<[bool;128]>>;
fn recording (&self) -> bool;
fn recording_mut (&mut self) -> &mut bool;
fn toggle_record (&mut self) {
*self.recording_mut() = !self.recording();
}
fn monitoring (&self) -> bool;
fn monitoring_mut (&mut self) -> &mut bool;
fn toggle_monitor (&mut self) {
*self.monitoring_mut() = !self.monitoring();
}
fn monitor (&mut self, scope: &ProcessScope, midi_buf: &mut Vec<Vec<Vec<u8>>>) {
// For highlighting keys and note repeat
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)) {
if let LiveEvent::Midi { message, .. } = event {
if monitoring {
midi_buf[sample].push(bytes.to_vec());
}
update_keys(&mut notes_in.write().unwrap(), &message);
}
}
}
}
fn record (&mut self, scope: &ProcessScope, midi_buf: &mut Vec<Vec<Vec<u8>>>) {
if self.monitoring() {
self.monitor(scope, midi_buf);
}
if !self.clock().is_rolling() {
return
}
if let Some((started, ref clip)) = self.play_phrase().clone() {
self.record_clip(scope, started, clip, midi_buf);
}
if let Some((start_at, phrase)) = &self.next_phrase() {
self.record_next();
}
}
fn record_clip (
&mut self,
scope: &ProcessScope,
started: Moment,
phrase: &Option<Arc<RwLock<MidiClip>>>,
midi_buf: &mut Vec<Vec<Vec<u8>>>
) {
if let Some(phrase) = phrase {
let sample0 = scope.last_frame_time() as usize;
let start = started.sample.get() as usize;
let recording = self.recording();
let timebase = self.clock().timebase().clone();
let quant = self.clock().quant.get();
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)) {
if let LiveEvent::Midi { message, .. } = event {
phrase.record_event({
let sample = (sample0 + sample - start) as f64;
let pulse = timebase.samples_to_pulse(sample);
let quantized = (pulse / quant).round() * quant;
quantized as usize % length
}, message);
}
}
}
}
}
fn record_next (&mut self) {
// TODO switch to next clip and record into it
}
fn overdub (&self) -> bool;
fn overdub_mut (&mut self) -> &mut bool;
fn toggle_overdub (&mut self) {
*self.overdub_mut() = !self.overdub();
}
}