diff --git a/crates/tek_sequencer/src/arranger.rs b/crates/tek_sequencer/src/arranger.rs index ffb7fb1a..108bf9a0 100644 --- a/crates/tek_sequencer/src/arranger.rs +++ b/crates/tek_sequencer/src/arranger.rs @@ -76,13 +76,13 @@ pub struct Arrangement { /// Represents a track in the arrangement pub struct ArrangementTrack { /// Name of track - pub name: Arc>, + pub name: Arc>, /// Preferred width of track column - pub width: usize, + pub width: usize, /// Identifying color of track - pub color: ItemColor, + pub color: ItemColor, /// MIDI player/recorder - pub player: PhrasePlayer, + pub player: PhrasePlayer, } #[derive(Default, Debug)] pub struct Scene { diff --git a/crates/tek_sequencer/src/arranger_tui.rs b/crates/tek_sequencer/src/arranger_tui.rs index 7560bd03..3fb803a2 100644 --- a/crates/tek_sequencer/src/arranger_tui.rs +++ b/crates/tek_sequencer/src/arranger_tui.rs @@ -100,7 +100,7 @@ impl Content for ArrangerStatusBar { _ => command(&[]) }; //let commands = commands.iter().reduce(String::new(), |s, (a, b, c)| format!("{s} {a}{b}{c}")); - row!(mode, commands) + row!(mode, commands).fill_x().bg(Color::Rgb(28, 35, 25)) } } fn command (commands: &[[impl Widget;3]]) -> impl Widget + '_ { diff --git a/crates/tek_sequencer/src/sequencer_snd.rs b/crates/tek_sequencer/src/sequencer_snd.rs index ff0150cd..8a7fbbf5 100644 --- a/crates/tek_sequencer/src/sequencer_snd.rs +++ b/crates/tek_sequencer/src/sequencer_snd.rs @@ -56,25 +56,23 @@ impl PhrasePlayer { } } fn play (&mut self, scope: &ProcessScope) -> bool { - let sample0 = scope.last_frame_time() as usize; - let samples = scope.n_frames() as usize; let mut next = false; // Write MIDI events from currently playing phrase (if any) to MIDI output buffer if self.is_rolling() { + let sample0 = scope.last_frame_time() as usize; + let samples = scope.n_frames() as usize; // If no phrase is playing, prepare for switchover immediately next = self.phrase.is_none(); if let Some((started, phrase)) = &self.phrase { // First sample to populate. Greater than 0 means that the first // pulse of the phrase falls somewhere in the middle of the chunk. - let sample = sample0.saturating_sub( - started.sample.get() as usize + self.clock.started.read().unwrap().unwrap().0 - ); + let sample = started.sample.get() as usize; + let sample = sample + self.clock.started.read().unwrap().unwrap().0; + let sample = sample0.saturating_sub(sample); // Iterator that emits sample (index into output buffer at which to write MIDI event) // paired with pulse (index into phrase from which to take the MIDI event) for each // 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_chunk; // Notes active during current chunk. let notes = &mut self.notes_out.write().unwrap(); for (sample, pulse) in pulses { @@ -93,7 +91,7 @@ impl PhrasePlayer { // Source phrase from which the MIDI events will be taken. let phrase = phrase.read().unwrap(); // Current pulse index in source phrase - let pulse = pulse % phrase.length; + let pulse = pulse % phrase.length; // 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. @@ -101,9 +99,11 @@ impl PhrasePlayer { // TODO: support MIDI channels other than CH1. let channel = 0.into(); // Serialize MIDI event into message buffer. - LiveEvent::Midi { channel, message: *message }.write(&mut self.midi_note).unwrap(); + LiveEvent::Midi { channel, message: *message } + .write(&mut self.midi_note) + .unwrap(); // Append serialized message to output buffer. - output[sample].push(self.midi_note.clone()); + self.midi_chunk[sample].push(self.midi_note.clone()); // Update the list of currently held notes. update_keys(notes, &message); } @@ -114,15 +114,14 @@ impl PhrasePlayer { next } fn switchover (&mut self, scope: &ProcessScope) { - let sample0 = scope.last_frame_time() as usize; - let samples = scope.n_frames() as usize; if self.is_rolling() { + let sample0 = scope.last_frame_time() as usize; + //let samples = scope.n_frames() as usize; if let Some((start_at, phrase)) = &self.next_phrase { - let start = start_at.sample.get() as usize; + let start = start_at.sample.get() as usize; + let sample = self.clock.started.read().unwrap().unwrap().0; // If it's time to switch to the next phrase: - if start <= sample0.saturating_sub( - self.clock.started.read().unwrap().unwrap().0 - ) { + if start <= sample0.saturating_sub(sample) { // Samples elapsed since phrase was supposed to start let skipped = sample0 - start; // Switch over to enqueued phrase