pub trait HasClock: AsRef + AsMut { fn clock (&self) -> &Clock { self.as_ref() } fn clock_mut (&mut self) -> &mut Clock { self.as_mut() } } /// Temporal resolutions: sample rate, tempo, MIDI pulses per quaver (beat) /// /// ``` /// let _ = tek::Timebase::default(); /// ``` #[derive(Debug, Clone)] pub struct Timebase { /// Audio samples per second pub sr: SampleRate, /// MIDI beats per minute pub bpm: Bpm, /// MIDI ticks per beat pub ppq: Ppq, } /// Iterator that emits subsequent ticks within a range. /// /// ``` /// let iter = tek::Ticker::default(); /// ``` #[derive(Debug, Default)] pub struct Ticker { pub spp: f64, pub sample: usize, pub start: usize, pub end: usize, } /// A point in time in all time scales (microsecond, sample, MIDI pulse) /// /// ``` /// let _ = tek::Moment::default(); /// ``` #[derive(Debug, Default, Clone)] pub struct Moment { pub timebase: Arc, /// Current time in microseconds pub usec: Microsecond, /// Current time in audio samples pub sample: SampleCount, /// Current time in MIDI pulses pub pulse: Pulse, } /// /// ``` /// let _ = tek::Moment2::default(); /// ``` #[derive(Debug, Clone, Default)] pub enum Moment2 { #[default] None, Zero, Usec(Microsecond), Sample(SampleCount), Pulse(Pulse), } /// MIDI resolution in PPQ (pulses per quarter note) /// /// ``` /// /// ``` #[derive(Debug, Default)] pub struct Ppq (pub(crate) AtomicF64); /// Timestamp in MIDI pulses /// /// ``` /// /// ``` #[derive(Debug, Default)] pub struct Pulse (pub(crate) AtomicF64); /// Tempo in beats per minute /// /// ``` /// /// ``` #[derive(Debug, Default)] pub struct Bpm (pub(crate) AtomicF64); /// Quantization setting for launching clips /// /// ``` /// /// ``` #[derive(Debug, Default)] pub struct LaunchSync (pub(crate) AtomicF64); /// Quantization setting for notes /// /// ``` /// /// ``` #[derive(Debug, Default)] pub struct Quantize (pub(crate) AtomicF64); /// Timestamp in audio samples /// /// ``` /// /// ``` #[derive(Debug, Default)] pub struct SampleCount (pub(crate) AtomicF64); /// Audio sample rate in Hz (samples per second) /// /// ``` /// /// ``` #[derive(Debug, Default)] pub struct SampleRate (pub(crate) AtomicF64); /// Timestamp in microseconds /// /// ``` /// /// ``` #[derive(Debug, Default)] pub struct Microsecond (pub(crate) AtomicF64); /// The source of time. /// /// ``` /// let clock = tek::Clock::default(); /// ``` #[derive(Clone, Default)] pub struct Clock { /// JACK transport handle. pub transport: Arc>, /// Global temporal resolution (shared by [Moment] fields) pub timebase: Arc, /// Current global sample and usec (monotonic from JACK clock) pub global: Arc, /// Global sample and usec at which playback started pub started: Arc>>, /// Playback offset (when playing not from start) pub offset: Arc, /// Current playhead position pub playhead: Arc, /// Note quantization factor pub quant: Arc, /// Launch quantization factor pub sync: Arc, /// Size of buffer in samples pub chunk: Arc, // Cache of formatted strings pub view_cache: Arc>, /// For syncing the clock to an external source #[cfg(feature = "port")] pub midi_in: Arc>>, /// For syncing other devices to this clock #[cfg(feature = "port")] pub midi_out: Arc>>, /// For emitting a metronome #[cfg(feature = "port")] pub click_out: Arc>>, } /// A unit of time, represented as an atomic 64-bit float. /// /// According to https://stackoverflow.com/a/873367, as per IEEE754, /// every integer between 1 and 2^53 can be represented exactly. /// This should mean that, even at 192kHz sampling rate, over 1 year of audio /// can be clocked in microseconds with f64 without losing precision. pub trait TimeUnit: InteriorMutable {} /// Contains memoized renders of clock values. /// /// Performance optimization. #[derive(Debug)] pub struct ClockView { pub sr: Memo, String>, pub buf: Memo, String>, pub lat: Memo, String>, pub bpm: Memo, String>, pub beat: Memo, String>, pub time: Memo, String>, }