From 8d8fe64be35f8824cd3e1cd71731f6a2974b28ad Mon Sep 17 00:00:00 2001 From: unspeaker Date: Sat, 22 Jun 2024 20:51:01 +0300 Subject: [PATCH] fix: write jack events in order (many allocations) --- src/device/sequencer.rs | 93 +++++++++++++++++++++++++++++++++++------ 1 file changed, 80 insertions(+), 13 deletions(-) diff --git a/src/device/sequencer.rs b/src/device/sequencer.rs index 1f44fa18..0b4f2345 100644 --- a/src/device/sequencer.rs +++ b/src/device/sequencer.rs @@ -97,6 +97,9 @@ impl Sequencer { } fn process (&mut self, _: &Client, scope: &ProcessScope) -> Control { + + // Update time + let mut sequence = &mut self.sequences[self.sequence]; let transport = self.transport.query().unwrap(); self.playing = transport.state; let pos = &transport.pos; @@ -104,15 +107,61 @@ impl Sequencer { let steps = usecs / self.timebase.usec_per_step(self.resolution as usize); let step = steps % self.steps; let tick = step * self.timebase.ppq() / self.resolution; - let mut sequence = &mut self.sequences[self.sequence]; - let mut writer = self.output_port.writer(scope); + + // Prepare output buffer + let frames = scope.n_frames() as usize; + let mut output: Vec>>> = vec![None;frames]; + + // Read from input + for event in self.input_port.iter(scope) { + + // Write to output + if self.monitoring { + let t = event.time as usize; + if output[t].is_none() { + output[t] = Some(vec![]); + } + if let Some(Some(frame)) = output.get_mut(t) { + frame.push(event.bytes.into()) + } + } + + // Write to sequence + if self.recording { + let tick = tick as u32; + match midly::live::LiveEvent::parse(event.bytes).unwrap() { + midly::live::LiveEvent::Midi { channel: _, message } => match message { + midly::MidiMessage::NoteOn { key, vel: _ } => { + self.notes_on[key.as_int() as usize] = true; + let contains = sequence.contains_key(&tick); + if contains { + sequence.get_mut(&tick).unwrap().push(message.clone()); + } else { + sequence.insert(tick, vec![message.clone()]); + } + }, + midly::MidiMessage::NoteOff { key, vel: _ } => { + self.notes_on[key.as_int() as usize] = false; + let contains = sequence.contains_key(&tick); + if contains { + sequence.get_mut(&tick).unwrap().push(message.clone()); + } else { + sequence.insert(tick, vec![message.clone()]); + } + }, + _ => {} + }, + _ => {} + } + } + + } + + // Play from sequence if self.playing == TransportState::Rolling { let frame = transport.pos.frame() as usize; - let ticks = self.timebase.frames_to_ticks( - frame, - frame + scope.n_frames() as usize, - self.timebase.fpb() as usize * self.steps / self.resolution - ); + let quant = self.timebase.fpb() as usize * self.steps / self.resolution; + let ticks = self.timebase.frames_to_ticks(frame, frame + frames, quant); for (time, tick) in ticks.iter() { if let Some(events) = sequence.get(&(*tick as u32)) { for message in events.iter() { @@ -121,16 +170,34 @@ impl Sequencer { channel: 0.into(), message: *message, }.write(&mut buf).unwrap(); - let midi = ::jack::RawMidi { - time: *time as u32, - bytes: &buf - }; - writer.write(&midi).expect(&format!("{midi:?}")); - //panic!("{midi:?}"); + 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 mut writer = self.output_port.writer(scope); + for t in 0..scope.n_frames() { + if let Some(Some(frame)) = output.get_mut(t as usize) { + for event in frame.iter() { + writer.write(&::jack::RawMidi { + time: t, + bytes: &event + }).expect(&format!("{event:?}")); + } + } + } + + //// + + if self.playing == TransportState::Rolling { + } for event in self.input_port.iter(scope) { if self.monitoring { writer.write(&event).expect(&format!("{event:?}"))