diff --git a/crates/tek_sequencer/src/arranger.rs b/crates/tek_sequencer/src/arranger.rs index ccd022ed..778f6a35 100644 --- a/crates/tek_sequencer/src/arranger.rs +++ b/crates/tek_sequencer/src/arranger.rs @@ -236,12 +236,20 @@ impl Arrangement { size: Measure::new(), } } + fn is_stopped (&self) -> bool { + *self.clock.playing.read().unwrap() == Some(TransportState::Stopped) + } pub fn activate (&mut self) { match self.selected { ArrangementFocus::Scene(s) => { for (t, track) in self.tracks.iter_mut().enumerate() { track.player.enqueue_next(self.scenes[s].clips[t].as_ref()); } + // TODO make transport available here, so that + // activating a scene when stopped starts playback + //if self.is_stopped() { + //self.transport.toggle_play() + //} }, ArrangementFocus::Clip(t, s) => { self.tracks[t].player.enqueue_next(self.scenes[s].clips[t].as_ref()); diff --git a/crates/tek_sequencer/src/sequencer_snd.rs b/crates/tek_sequencer/src/sequencer_snd.rs index 2fd7e381..b3e6ab4b 100644 --- a/crates/tek_sequencer/src/sequencer_snd.rs +++ b/crates/tek_sequencer/src/sequencer_snd.rs @@ -11,7 +11,7 @@ impl Audio for Sequencer { impl Audio for PhrasePlayer { fn process (&mut self, _: &Client, scope: &ProcessScope) -> Control { let has_midi_outputs = self.has_midi_outputs(); - let has_midi_inputs = self.has_midi_inputs(); + let has_midi_inputs = self.has_midi_inputs(); if has_midi_outputs { // Clear output buffer(s) self.clear(scope, false); @@ -45,11 +45,12 @@ impl PhrasePlayer { all_notes_off(&mut self.midi_out_buf); self.reset = false; } } + fn is_rolling (&self) -> bool { + *self.clock.playing.read().unwrap() == Some(TransportState::Rolling) + } /// Return playing phrase with starting point fn playing (&self) -> Option<(usize, Arc>)> { - if let ( - Some(TransportState::Rolling), Some((started, Some(ref phrase))) - ) = (*self.clock.playing.read().unwrap(), &self.phrase) { + if let (true, Some((started, Some(ref phrase)))) = (self.is_rolling(), &self.phrase) { Some((started.sample().get() as usize, phrase.clone())) } else { None @@ -57,9 +58,7 @@ impl PhrasePlayer { } /// Return next phrase with starting point fn enqueued (&self) -> Option<(usize, Arc>)> { - if let ( - Some(TransportState::Rolling), Some((start_at, Some(ref phrase))) - ) = (*self.clock.playing.read().unwrap(), &self.next_phrase) { + if let (true, Some((start_at, Some(ref phrase)))) = (self.is_rolling(), &self.next_phrase) { Some((start_at.sample().get() as usize, phrase.clone())) } else { None @@ -76,6 +75,10 @@ impl PhrasePlayer { let notes_on = &mut self.notes_out.write().unwrap(); let mut buf = Vec::with_capacity(8); for (sample, tick) in ticks { + // If a next phrase is enqueued, and we're past the end of the current one, + // break the loop here (FIXME count tick correctly) + if self.next_phrase.is_some() && tick >= phrase.length { break } + // Output events from phrase at appropriate frames of output buffer let tick = tick % phrase.length; for message in phrase.notes[tick].iter() { buf.clear(); @@ -88,6 +91,9 @@ impl PhrasePlayer { } }).unwrap() } + if let Some((start, ref phrase)) = self.enqueued() { + // TODO switch to next phrase and fill in remaining ticks from it + } } fn record (&mut self, scope: &ProcessScope) { let sample0 = scope.last_frame_time() as usize; @@ -101,7 +107,9 @@ 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 { - if self.monitoring { self.midi_out_buf[sample].push(bytes.to_vec()) } + if self.monitoring { + self.midi_out_buf[sample].push(bytes.to_vec()) + } if self.recording { phrase.record_event({ let pulse = self.clock.timebase().samples_to_pulse( @@ -117,6 +125,9 @@ impl PhrasePlayer { } } } + if let Some((start, ref phrase)) = self.enqueued() { + // TODO switch to next phrase and record into it + } } fn monitor (&mut self, scope: &ProcessScope) { let mut notes_in = self.notes_in.write().unwrap(); diff --git a/crates/tek_sequencer/src/transport.rs b/crates/tek_sequencer/src/transport.rs index c873d50c..0d70667b 100644 --- a/crates/tek_sequencer/src/transport.rs +++ b/crates/tek_sequencer/src/transport.rs @@ -2,13 +2,13 @@ use crate::*; #[derive(Debug, Default)] pub struct TransportTime { /// Current moment in time - pub instant: Instant, + pub instant: Instant, /// Note quantization factor - pub quant: TimeUnit, + pub quant: TimeUnit, /// Launch quantization factor - pub sync: TimeUnit, + pub sync: TimeUnit, /// Playback state - pub playing: RwLock>, + pub playing: RwLock>, } impl TransportTime { pub fn timebase (&self) -> &Arc { &self.instant.timebase }