From bb8ab496c0faed7f61ba17283edda78205f8834b Mon Sep 17 00:00:00 2001 From: unspeaker Date: Sun, 3 Nov 2024 08:38:03 +0200 Subject: [PATCH] don't reallocate note buffer each callback --- crates/tek_sequencer/src/arranger.rs | 6 +++--- crates/tek_sequencer/src/sequencer.rs | 22 ++++++++++++++-------- crates/tek_sequencer/src/sequencer_snd.rs | 23 ++++++++++++----------- 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/crates/tek_sequencer/src/arranger.rs b/crates/tek_sequencer/src/arranger.rs index c522dabe..ffb7fb1a 100644 --- a/crates/tek_sequencer/src/arranger.rs +++ b/crates/tek_sequencer/src/arranger.rs @@ -155,9 +155,9 @@ impl Arranger { } pub fn next_color (&self) -> ItemColor { if let ArrangementFocus::Clip(track, scene) = self.arrangement.selected { - let track_color = self.arrangement.tracks[track].color; - let scene_color = self.arrangement.scenes[scene].color; - track_color.mix(scene_color, 0.5).mix(ItemColor::random(), 0.25) + let track_color = self.arrangement.tracks[track].color; + let scene_color = self.arrangement.scenes[scene].color; + track_color.mix(scene_color, 0.5).mix(ItemColor::random(), 0.5) } else { panic!("could not compute next color") } diff --git a/crates/tek_sequencer/src/sequencer.rs b/crates/tek_sequencer/src/sequencer.rs index ce270725..ce1debbf 100644 --- a/crates/tek_sequencer/src/sequencer.rs +++ b/crates/tek_sequencer/src/sequencer.rs @@ -134,7 +134,9 @@ pub struct PhrasePlayer { /// Play from current sequence to MIDI ports pub midi_outputs: Vec>, /// MIDI output buffer - pub midi_out_buf: Vec>>, + pub midi_note: Vec, + /// MIDI output buffer + pub midi_chunk: Vec>>, /// Notes currently held at input pub notes_in: Arc>, /// Notes currently held at output @@ -236,12 +238,15 @@ impl PhrasePool { } pub fn begin_rename (&mut self) { self.mode = Some(PhrasePoolMode::Rename( - self.phrase, self.phrases[self.phrase].read().unwrap().name.clone() + self.phrase, + self.phrases[self.phrase].read().unwrap().name.clone() )); } pub fn begin_length (&mut self) { self.mode = Some(PhrasePoolMode::Length( - self.phrase, self.phrases[self.phrase].read().unwrap().length, PhraseLengthFocus::Bar + self.phrase, + self.phrases[self.phrase].read().unwrap().length, + PhraseLengthFocus::Bar )); } pub fn move_up (&mut self) { @@ -406,14 +411,15 @@ impl PhrasePlayer { monitoring: false, recording: false, overdub: true, - midi_inputs: vec![ - jack.client().register_port(format!("{name}_in0").as_str(), MidiIn::default())? - ], + reset: true, + midi_note: Vec::with_capacity(8), + midi_chunk: vec![Vec::with_capacity(16);16384], midi_outputs: vec![ jack.client().register_port(format!("{name}_out0").as_str(), MidiOut::default())? ], - midi_out_buf: vec![Vec::with_capacity(16);16384], - reset: true, + midi_inputs: vec![ + jack.client().register_port(format!("{name}_in0").as_str(), MidiIn::default())? + ], }) } pub fn toggle_monitor (&mut self) { self.monitoring = !self.monitoring; } diff --git a/crates/tek_sequencer/src/sequencer_snd.rs b/crates/tek_sequencer/src/sequencer_snd.rs index d566a885..ff0150cd 100644 --- a/crates/tek_sequencer/src/sequencer_snd.rs +++ b/crates/tek_sequencer/src/sequencer_snd.rs @@ -48,11 +48,11 @@ impl PhrasePlayer { /// 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_out_buf[0..scope.n_frames() as usize] { + for frame in &mut self.midi_chunk[0..scope.n_frames() as usize] { frame.clear(); } if self.reset || force_reset { - all_notes_off(&mut self.midi_out_buf); self.reset = false; + all_notes_off(&mut self.midi_chunk); self.reset = false; } } fn play (&mut self, scope: &ProcessScope) -> bool { @@ -74,9 +74,7 @@ impl PhrasePlayer { // sample of the output buffer that corresponds to a MIDI pulse. let pulses = self.clock.timebase().pulses_between_samples(sample, sample + samples); // MIDI output buffer that will be copied to the JACK MIDI output ports. - let output = &mut self.midi_out_buf; - // Buffer for bytes of a MIDI event. - let mut mm = Vec::with_capacity(8); + let output = &mut self.midi_chunk; // Notes active during current chunk. let notes = &mut self.notes_out.write().unwrap(); for (sample, pulse) in pulses { @@ -99,13 +97,13 @@ impl PhrasePlayer { // 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. - mm.clear(); + self.midi_note.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 mm).unwrap(); + LiveEvent::Midi { channel, message: *message }.write(&mut self.midi_note).unwrap(); // Append serialized message to output buffer. - output[sample].push(mm.clone()); + output[sample].push(self.midi_note.clone()); // Update the list of currently held notes. update_keys(notes, &message); } @@ -135,6 +133,9 @@ impl PhrasePlayer { } // TODO fill in remaining ticks of chunk from next phrase. // ?? just call self.play(scope) again, since enqueuement is off ??? + self.play(scope); + // ?? or must it be with modified scope ?? + // likely not because start time etc } } } @@ -150,7 +151,7 @@ impl PhrasePlayer { for (sample, event, bytes) in parse_midi_input(input.iter(scope)) { if let LiveEvent::Midi { message, .. } = event { if self.monitoring { - self.midi_out_buf[sample].push(bytes.to_vec()) + self.midi_chunk[sample].push(bytes.to_vec()) } if self.recording { if let Some(phrase) = phrase { @@ -179,7 +180,7 @@ impl PhrasePlayer { for input in self.midi_inputs.iter() { for (sample, event, bytes) in parse_midi_input(input.iter(scope)) { if let LiveEvent::Midi { message, .. } = event { - self.midi_out_buf[sample].push(bytes.to_vec()); + self.midi_chunk[sample].push(bytes.to_vec()); update_keys(&mut notes_in, &message); } } @@ -189,7 +190,7 @@ impl PhrasePlayer { let samples = scope.n_frames() as usize; for port in self.midi_outputs.iter_mut() { let writer = &mut port.writer(scope); - let output = &self.midi_out_buf; + let output = &self.midi_chunk; for time in 0..samples { for event in output[time].iter() { writer.write(&RawMidi { time: time as u32, bytes: &event })