From 3ee9a670da55b6f63aef77a32ebd0f4e2dfa9e6b Mon Sep 17 00:00:00 2001 From: unspeaker Date: Sat, 2 Nov 2024 01:17:02 +0200 Subject: [PATCH] move started field onto TransportTime --- crates/tek_core/src/time.rs | 38 +++++++---------------- crates/tek_sequencer/src/sequencer.rs | 4 +-- crates/tek_sequencer/src/transport.rs | 22 ++++++------- crates/tek_sequencer/src/transport_snd.rs | 24 ++++++++------ 4 files changed, 40 insertions(+), 48 deletions(-) diff --git a/crates/tek_core/src/time.rs b/crates/tek_core/src/time.rs index d5e74607..35a63ace 100644 --- a/crates/tek_core/src/time.rs +++ b/crates/tek_core/src/time.rs @@ -59,13 +59,21 @@ macro_rules! time_unit { time_unit!(SampleRate); impl SampleRate { /// Return the duration of a sample in microseconds (floating) - #[inline] pub fn usec_per_sample (&self) -> f64 { 1_000_000f64 / self.get() } + #[inline] pub fn usec_per_sample (&self) -> f64 { + 1_000_000f64 / self.get() + } /// Return the duration of a sample in microseconds (floating) - #[inline] pub fn sample_per_usec (&self) -> f64 { self.get() / 1_000_000f64 } + #[inline] pub fn sample_per_usec (&self) -> f64 { + self.get() / 1_000_000f64 + } /// Convert a number of samples to microseconds (floating) - #[inline] pub fn samples_to_usec (&self, samples: f64) -> f64 { samples * self.usec_per_sample() } + #[inline] pub fn samples_to_usec (&self, samples: f64) -> f64 { + self.usec_per_sample() * samples + } /// Convert a number of microseconds to samples (floating) - #[inline] pub fn usecs_to_sample (&self, usecs: f64) -> f64 { usecs * self.sample_per_usec() } + #[inline] pub fn usecs_to_sample (&self, usecs: f64) -> f64 { + self.sample_per_usec() * usecs + } } time_unit!(BeatsPerMinute); @@ -256,28 +264,6 @@ impl Instant { self.timebase.format_beats_1(self.pulse.get()) } } -/// A timer with starting point, current time, and quantization -pub struct Timer { - pub timebase: Arc, - /// Starting point in global time - pub started: Option, - /// Current moment in global time - pub current: Instant, - /// Note quantization factor - pub quant: Quantize, - /// Launch quantization factor - pub sync: LaunchSync, - /// Playback state - pub playing: RwLock>, -} -/// Something that defines launch quantization -impl Timer { - #[inline] pub fn next_launch_pulse (&self) -> usize { - let sync = self.sync.get() as usize; - let pulse = self.current.pulse.get() as usize; - if pulse % sync == 0 { pulse } else { (pulse / sync + 1) * sync } - } -} /// Iterator that emits subsequent ticks within a range. pub struct TicksIterator { spp: f64, diff --git a/crates/tek_sequencer/src/sequencer.rs b/crates/tek_sequencer/src/sequencer.rs index 49fb05a1..614f7d91 100644 --- a/crates/tek_sequencer/src/sequencer.rs +++ b/crates/tek_sequencer/src/sequencer.rs @@ -1,11 +1,11 @@ use crate::*; use std::cmp::PartialEq; /// MIDI message structural -pub type PhraseData = Vec>; +pub type PhraseData = Vec>; /// MIDI message serialized pub type PhraseMessage = Vec; /// Collection of serialized MIDI messages -pub type PhraseChunk = [Vec]; +pub type PhraseChunk = [Vec]; /// Root level object for standalone `tek_sequencer` pub struct Sequencer { /// JACK client handle (needs to not be dropped for standalone mode to work). diff --git a/crates/tek_sequencer/src/transport.rs b/crates/tek_sequencer/src/transport.rs index 9c1afcec..b9d6fd3c 100644 --- a/crates/tek_sequencer/src/transport.rs +++ b/crates/tek_sequencer/src/transport.rs @@ -1,14 +1,16 @@ use crate::*; -#[derive(Debug, Default)] -pub struct TransportTime { +/// A timer with starting point, current time, and quantization +#[derive(Debug, Default)] pub struct TransportTime { + /// Playback state + pub playing: RwLock>, + /// Global sample and usec at which playback started + pub started: RwLock>, /// Current moment in time pub current: Instant, /// Note quantization factor pub quant: Quantize, /// Launch quantization factor pub sync: LaunchSync, - /// Playback state - pub playing: RwLock>, } impl TransportTime { #[inline] pub fn timebase (&self) -> &Arc { &self.current.timebase } @@ -32,8 +34,6 @@ pub struct TransportToolbar { pub jack: Option>, /// JACK transport handle. pub transport: Option, - /// Global sample and usec at which playback started - pub started: Option<(usize, usize)>, /// Whether the toolbar is focused pub focused: bool, /// Which part of the toolbar is focused @@ -52,7 +52,6 @@ impl TransportToolbar { focused: false, focus: TransportToolbarFocus::PlayPause, metronome: false, - started: None, jack: None, transport, clock: match clock { @@ -60,10 +59,11 @@ impl TransportToolbar { None => { let timebase = Arc::new(Timebase::default()); Arc::new(TransportTime { - playing: Some(TransportState::Stopped).into(), - quant: 24.into(), - sync: (timebase.ppq.get() * 4.).into(), - current: Instant::default(), + playing: Some(TransportState::Stopped).into(), + quant: 24.into(), + sync: (timebase.ppq.get() * 4.).into(), + current: Instant::default(), + started: None.into(), }) } } diff --git a/crates/tek_sequencer/src/transport_snd.rs b/crates/tek_sequencer/src/transport_snd.rs index 569e607b..7bf799a7 100644 --- a/crates/tek_sequencer/src/transport_snd.rs +++ b/crates/tek_sequencer/src/transport_snd.rs @@ -6,18 +6,24 @@ impl Audio for TransportToolbar { let _chunk_size = scope.n_frames() as usize; let transport = self.transport.as_ref().unwrap().query().unwrap(); self.clock.current.sample.set(transport.pos.frame() as f64); - if *self.clock.playing.read().unwrap() != Some(transport.state) { - self.started = match transport.state { - TransportState::Rolling => Some((current_frames as usize, current_usecs as usize)), - TransportState::Stopped => None, - _ => self.started + let mut playing = self.clock.playing.write().unwrap(); + let mut started = self.clock.started.write().unwrap(); + if *playing != Some(transport.state) { + match transport.state { + TransportState::Rolling => { + *started = Some((current_frames as usize, current_usecs as usize)) + }, + TransportState::Stopped => { + *started = None + }, + _ => {} } }; - *self.clock.playing.write().unwrap() = Some(transport.state); - if *self.clock.playing.read().unwrap() == Some(TransportState::Stopped) { - self.started = None; + *playing = Some(transport.state); + if *playing == Some(TransportState::Stopped) { + *started = None; } - self.clock.current.update_from_usec(match self.started { + self.clock.current.update_from_usec(match *started { Some((_, usecs)) => current_usecs as f64 - usecs as f64, None => 0. });