wip: long awaited fixes to main sequencer

This commit is contained in:
🪞👃🪞 2024-07-01 04:20:41 +03:00
parent 2837ffff4a
commit 78e5469b32
17 changed files with 391 additions and 563 deletions

View file

@ -14,32 +14,44 @@ impl Phrase {
pub fn new (name: &str, length: u32, notes: Option<PhraseData>) -> Self {
Self { name: name.to_string(), length, notes: notes.unwrap_or(BTreeMap::new()) }
}
pub fn frames (&self, timebase: &Arc<Timebase>) -> usize {
timebase.pulse_to_frame(self.length as usize)
}
pub fn frame_to_pulse (&self, timebase: &Arc<Timebase>, frame: usize) -> usize {
timebase.frame_to_pulse(frame) % self.length as usize
}
/** Write a chunk of MIDI events to an output port. */
pub fn chunk_out (
&self,
output: &mut MIDIChunk,
start: usize,
length: usize,
timebase: &Arc<Timebase>,
steps: usize,
resolution: usize,
output: &mut MIDIChunk,
notes_on: &mut Vec<bool>,
timebase: &Arc<Timebase>,
frame0: usize,
frames: usize,
) {
let quant = timebase.frames_per_beat() as usize * steps / resolution;
let ticks = timebase.frames_to_ticks(start, start + length, quant);
let quant = self.frames(timebase);
let ticks = timebase.frames_to_ticks(frame0, frame0 + frames, quant);
for (time, tick) in ticks.iter() {
if let Some(events) = self.notes.get(&(*tick as u32)) {
for message in events.iter() {
let mut buf = vec![];
let channel = 0.into();
let message = *message;
LiveEvent::Midi { channel, message }.write(&mut buf).unwrap();
let t = *time as usize;
if output[t].is_none() {
output[t] = Some(vec![]);
}
if let Some(Some(frame)) = output.get_mut(t) {
frame.push(buf);
}
let events = self.notes.get(&(*tick as u32));
if events.is_none() {
continue
}
for message in events.unwrap().iter() {
let mut buf = vec![];
let channel = 0.into();
let message = *message;
match message {
MidiMessage::NoteOn { key, .. } => notes_on[key.as_int() as usize] = true,
MidiMessage::NoteOff { key, .. } => notes_on[key.as_int() as usize] = false,
_ => {}
}
LiveEvent::Midi { channel, message }.write(&mut buf).unwrap();
let t = *time as usize;
if output[t].is_none() {
output[t] = Some(vec![]);
}
if let Some(Some(frame)) = output.get_mut(t) {
frame.push(buf);
}
}
}
@ -47,60 +59,54 @@ impl Phrase {
/** React a chunk of MIDI events from an input port. */
pub fn chunk_in (
&mut self,
port: &Port<MidiIn>,
scope: &ProcessScope,
input: ::jack::MidiIter,
notes_on: &mut Vec<bool>,
mut monitor: Option<&mut MIDIChunk>,
record: bool,
notes_on: &mut Vec<bool>,
tick: u32,
timebase: &Arc<Timebase>,
frame0: usize,
) {
for event in port.iter(scope) {
let msg = LiveEvent::parse(event.bytes).unwrap();
match msg {
LiveEvent::Midi { message, .. } => match message {
MidiMessage::NoteOn { key, vel: _ } => {
notes_on[key.as_int() as usize] = true;
if let Some(ref mut monitor) = monitor {
let t = event.time as usize;
if monitor[t].is_none() {
monitor[t] = Some(vec![]);
}
if let Some(Some(frame)) = monitor.get_mut(t) {
frame.push(event.bytes.into())
}
for RawMidi { time, bytes } in input {
let time = time as usize;
let pulse = timebase.frame_to_pulse(frame0 + time) as u32;
if let LiveEvent::Midi { message, .. } = LiveEvent::parse(bytes).unwrap() {
if let MidiMessage::NoteOn { key, vel: _ } = message {
notes_on[key.as_int() as usize] = true;
if let Some(ref mut monitor) = monitor {
if monitor[time].is_none() {
monitor[time] = Some(vec![]);
}
if record {
let contains = self.notes.contains_key(&tick);
if contains {
self.notes.get_mut(&tick).unwrap().push(message.clone());
} else {
self.notes.insert(tick, vec![message.clone()]);
}
if let Some(Some(frame)) = monitor.get_mut(time) {
frame.push(bytes.into())
}
},
midly::MidiMessage::NoteOff { key, vel: _ } => {
notes_on[key.as_int() as usize] = false;
if let Some(ref mut monitor) = monitor {
let t = event.time as usize;
if monitor[t].is_none() {
monitor[t] = Some(vec![]);
}
if let Some(Some(frame)) = monitor.get_mut(t) {
frame.push(event.bytes.into())
}
}
if record {
let contains = self.notes.contains_key(&pulse);
if contains {
self.notes.get_mut(&pulse).unwrap().push(message.clone());
} else {
self.notes.insert(pulse, vec![message.clone()]);
}
if record {
let contains = self.notes.contains_key(&tick);
if contains {
self.notes.get_mut(&tick).unwrap().push(message.clone());
} else {
self.notes.insert(tick, vec![message.clone()]);
}
}
} else if let midly::MidiMessage::NoteOff { key, vel: _ } = message {
notes_on[key.as_int() as usize] = false;
if let Some(ref mut monitor) = monitor {
if monitor[time].is_none() {
monitor[time] = Some(vec![]);
}
},
_ => {}
},
_ => {}
if let Some(Some(frame)) = monitor.get_mut(time) {
frame.push(bytes.into())
}
}
if record {
let contains = self.notes.contains_key(&pulse);
if contains {
self.notes.get_mut(&pulse).unwrap().push(message.clone());
} else {
self.notes.insert(pulse, vec![message.clone()]);
}
}
}
}
}
}