From d7c47c2561bc9fd473468cffe971e0fb4087d99e Mon Sep 17 00:00:00 2001 From: unspeaker Date: Thu, 26 Dec 2024 00:36:40 +0100 Subject: [PATCH] move play call to innermost block of fn switchover --- crates/tek/src/edn.rs | 6 ++- crates/tek/src/midi/midi_play.rs | 65 +++++++++++++++----------------- 2 files changed, 35 insertions(+), 36 deletions(-) diff --git a/crates/tek/src/edn.rs b/crates/tek/src/edn.rs index f0c4d6ad..eb4992bb 100644 --- a/crates/tek/src/edn.rs +++ b/crates/tek/src/edn.rs @@ -1,3 +1,5 @@ +#![allow(unused)] + use crate::*; pub use clojure_reader::edn::Edn; //pub use clojure_reader::{edn::{read, Edn}, error::Error as EdnError}; @@ -49,9 +51,9 @@ impl crate::Sampler { unmapped: Default::default(), voices: Default::default(), buffer: Default::default(), - midi_in: midi_in, audio_outs: vec![], - output_gain: 0. + output_gain: 0., + midi_in, }) } } diff --git a/crates/tek/src/midi/midi_play.rs b/crates/tek/src/midi/midi_play.rs index 12d414c7..8331d30c 100644 --- a/crates/tek/src/midi/midi_play.rs +++ b/crates/tek/src/midi/midi_play.rs @@ -27,11 +27,40 @@ pub trait MidiPlaybackApi: HasPlayPhrase + HasClock + HasMidiOuts { // If a phrase is playing, write a chunk of MIDI events from it to the output buffer. // If no phrase is playing, prepare for switchover immediately. self.play_phrase().as_ref().map_or(true, |(started, phrase)|{ - self.play_phrase_chunk(scope, note_buf, out, started, phrase) + self.play_chunk(scope, note_buf, out, started, phrase) }) } - fn play_phrase_chunk ( + /// Handle switchover from current to next playing phrase. + fn switchover ( + &mut self, scope: &ProcessScope, note_buf: &mut Vec, out: &mut [Vec>] + ) { + if !self.clock().is_rolling() { + return + } + 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 sample = self.clock().started.read().unwrap() + .as_ref().unwrap().sample.get() as usize; + // If it's time to switch to the next phrase: + if start <= sample0.saturating_sub(sample) { + // Samples elapsed since phrase was supposed to start + let skipped = sample0 - start; + // Switch over to enqueued phrase + let started = Moment::from_sample(&self.clock().timebase(), start as f64); + // Launch enqueued phrase + *self.play_phrase_mut() = Some((started, phrase.clone())); + // Unset enqueuement (TODO: where to implement looping?) + *self.next_phrase_mut() = None; + // Fill in remaining ticks of chunk from next phrase. + self.play(scope, note_buf, out); + } + } + } + + fn play_chunk ( &self, scope: &ProcessScope, note_buf: &mut Vec, @@ -99,38 +128,6 @@ pub trait MidiPlaybackApi: HasPlayPhrase + HasClock + HasMidiOuts { } } - /// Handle switchover from current to next playing phrase. - fn switchover ( - &mut self, scope: &ProcessScope, note_buf: &mut Vec, out: &mut [Vec>] - ) { - if !self.clock().is_rolling() { - return - } - 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 sample = self.clock().started.read().unwrap() - .as_ref().unwrap().sample.get() as usize; - // If it's time to switch to the next phrase: - if start <= sample0.saturating_sub(sample) { - // Samples elapsed since phrase was supposed to start - let skipped = sample0 - start; - // Switch over to enqueued phrase - let started = Moment::from_sample(&self.clock().timebase(), start as f64); - // Launch enqueued phrase - *self.play_phrase_mut() = Some((started, phrase.clone())); - // Unset enqueuement (TODO: where to implement looping?) - *self.next_phrase_mut() = None - } - // TODO fill in remaining ticks of chunk from next phrase. - // ?? just call self.play(scope) again, since enqueuement is off ??? - self.play(scope, note_buf, out); - // ?? or must it be with modified scope ?? - // likely not because start time etc - } - } - /// Write a chunk of MIDI data from the output buffer to all assigned output ports. fn write (&mut self, scope: &ProcessScope, out: &[Vec>]) { let samples = scope.n_frames() as usize;