mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
time: clock: add next_launch_instant, modularize
This commit is contained in:
parent
13444dc59a
commit
24bc33d3d0
4 changed files with 81 additions and 61 deletions
18
crates/time/src/clock.rs
Normal file
18
crates/time/src/clock.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
use crate::*;
|
||||||
|
|
||||||
|
mod clock_api; pub use self::clock_api::*;
|
||||||
|
mod clock_model; pub use self::clock_model::*;
|
||||||
|
|
||||||
|
pub trait HasClock: Send + Sync {
|
||||||
|
fn clock (&self) -> &Clock;
|
||||||
|
fn clock_mut (&mut self) -> &mut Clock;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export] macro_rules! has_clock {
|
||||||
|
(|$self:ident:$Struct:ident$(<$($L:lifetime),*$($T:ident$(:$U:path)?),*>)?|$cb:expr) => {
|
||||||
|
impl $(<$($L),*$($T $(: $U)?),*>)? HasClock for $Struct $(<$($L),*$($T),*>)? {
|
||||||
|
fn clock (&$self) -> &Clock { &$cb }
|
||||||
|
fn clock_mut (&mut $self) -> &mut Clock { &mut $cb }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
55
crates/time/src/clock/clock_api.rs
Normal file
55
crates/time/src/clock/clock_api.rs
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
use crate::*;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub enum ClockCommand {
|
||||||
|
Play(Option<u32>),
|
||||||
|
Pause(Option<u32>),
|
||||||
|
SeekUsec(f64),
|
||||||
|
SeekSample(f64),
|
||||||
|
SeekPulse(f64),
|
||||||
|
SetBpm(f64),
|
||||||
|
SetQuant(f64),
|
||||||
|
SetSync(f64),
|
||||||
|
}
|
||||||
|
|
||||||
|
provide_num!(u32: |self: Clock| {});
|
||||||
|
|
||||||
|
provide!(f64: |self: Clock| {});
|
||||||
|
|
||||||
|
atom_command!(ClockCommand: |state: Clock| {
|
||||||
|
("play" [] Some(Self::Play(None)))
|
||||||
|
("play" [t: u32] Some(Self::Play(t)))
|
||||||
|
("pause" [] Some(Self::Pause(None)))
|
||||||
|
("pause" [t: u32] Some(Self::Pause(t)))
|
||||||
|
("toggle" [] Some(if state.is_rolling() { Self::Pause(None) } else { Self::Play(None) }))
|
||||||
|
("toggle" [t: u32] Some(if state.is_rolling() { Self::Pause(t) } else { Self::Play(t) }))
|
||||||
|
("seek/usec" [t: f64] Some(Self::SeekUsec(t.expect("no usec"))))
|
||||||
|
("seek/pulse" [t: f64] Some(Self::SeekPulse(t.expect("no pulse"))))
|
||||||
|
("seek/sample" [t: f64] Some(Self::SeekSample(t.expect("no sample"))))
|
||||||
|
("set/bpm" [t: f64] Some(Self::SetBpm(t.expect("no bpm"))))
|
||||||
|
("set/sync" [t: f64] Some(Self::SetSync(t.expect("no sync"))))
|
||||||
|
("set/quant" [t: f64] Some(Self::SetQuant(t.expect("no quant"))))
|
||||||
|
});
|
||||||
|
|
||||||
|
impl<T: HasClock> Command<T> for ClockCommand {
|
||||||
|
fn execute (self, state: &mut T) -> Perhaps<Self> {
|
||||||
|
self.execute(state.clock_mut())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Command<Clock> for ClockCommand {
|
||||||
|
fn execute (self, state: &mut Clock) -> Perhaps<Self> {
|
||||||
|
use ClockCommand::*;
|
||||||
|
match self {
|
||||||
|
Play(start) => state.play_from(start)?,
|
||||||
|
Pause(pause) => state.pause_at(pause)?,
|
||||||
|
SeekUsec(usec) => state.playhead.update_from_usec(usec),
|
||||||
|
SeekSample(sample) => state.playhead.update_from_sample(sample),
|
||||||
|
SeekPulse(pulse) => state.playhead.update_from_pulse(pulse),
|
||||||
|
SetBpm(bpm) => return Ok(Some(SetBpm(state.timebase().bpm.set(bpm)))),
|
||||||
|
SetQuant(quant) => return Ok(Some(SetQuant(state.quant.set(quant)))),
|
||||||
|
SetSync(sync) => return Ok(Some(SetSync(state.sync.set(sync)))),
|
||||||
|
};
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,64 +1,4 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
pub trait HasClock: Send + Sync {
|
|
||||||
fn clock (&self) -> &Clock;
|
|
||||||
fn clock_mut (&mut self) -> &mut Clock;
|
|
||||||
}
|
|
||||||
#[macro_export] macro_rules! has_clock {
|
|
||||||
(|$self:ident:$Struct:ident$(<$($L:lifetime),*$($T:ident$(:$U:path)?),*>)?|$cb:expr) => {
|
|
||||||
impl $(<$($L),*$($T $(: $U)?),*>)? HasClock for $Struct $(<$($L),*$($T),*>)? {
|
|
||||||
fn clock (&$self) -> &Clock { &$cb }
|
|
||||||
fn clock_mut (&mut $self) -> &mut Clock { &mut $cb }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
pub enum ClockCommand {
|
|
||||||
Play(Option<u32>),
|
|
||||||
Pause(Option<u32>),
|
|
||||||
SeekUsec(f64),
|
|
||||||
SeekSample(f64),
|
|
||||||
SeekPulse(f64),
|
|
||||||
SetBpm(f64),
|
|
||||||
SetQuant(f64),
|
|
||||||
SetSync(f64),
|
|
||||||
}
|
|
||||||
provide_num!(u32: |self: Clock| {});
|
|
||||||
provide!(f64: |self: Clock| {});
|
|
||||||
atom_command!(ClockCommand: |state: Clock| {
|
|
||||||
("play" [] Some(Self::Play(None)))
|
|
||||||
("play" [t: u32] Some(Self::Play(t)))
|
|
||||||
("pause" [] Some(Self::Pause(None)))
|
|
||||||
("pause" [t: u32] Some(Self::Pause(t)))
|
|
||||||
("toggle" [] Some(if state.is_rolling() { Self::Pause(None) } else { Self::Play(None) }))
|
|
||||||
("toggle" [t: u32] Some(if state.is_rolling() { Self::Pause(t) } else { Self::Play(t) }))
|
|
||||||
("seek/usec" [t: f64] Some(Self::SeekUsec(t.expect("no usec"))))
|
|
||||||
("seek/pulse" [t: f64] Some(Self::SeekPulse(t.expect("no pulse"))))
|
|
||||||
("seek/sample" [t: f64] Some(Self::SeekSample(t.expect("no sample"))))
|
|
||||||
("set/bpm" [t: f64] Some(Self::SetBpm(t.expect("no bpm"))))
|
|
||||||
("set/sync" [t: f64] Some(Self::SetSync(t.expect("no sync"))))
|
|
||||||
("set/quant" [t: f64] Some(Self::SetQuant(t.expect("no quant"))))
|
|
||||||
});
|
|
||||||
impl<T: HasClock> Command<T> for ClockCommand {
|
|
||||||
fn execute (self, state: &mut T) -> Perhaps<Self> {
|
|
||||||
self.execute(state.clock_mut())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl Command<Clock> for ClockCommand {
|
|
||||||
fn execute (self, state: &mut Clock) -> Perhaps<Self> {
|
|
||||||
use ClockCommand::*;
|
|
||||||
match self {
|
|
||||||
Play(start) => state.play_from(start)?,
|
|
||||||
Pause(pause) => state.pause_at(pause)?,
|
|
||||||
SeekUsec(usec) => state.playhead.update_from_usec(usec),
|
|
||||||
SeekSample(sample) => state.playhead.update_from_sample(sample),
|
|
||||||
SeekPulse(pulse) => state.playhead.update_from_pulse(pulse),
|
|
||||||
SetBpm(bpm) => return Ok(Some(SetBpm(state.timebase().bpm.set(bpm)))),
|
|
||||||
SetQuant(quant) => return Ok(Some(SetQuant(state.quant.set(quant)))),
|
|
||||||
SetSync(sync) => return Ok(Some(SetSync(state.sync.set(sync)))),
|
|
||||||
};
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct Clock {
|
pub struct Clock {
|
||||||
|
|
@ -87,6 +27,7 @@ pub struct Clock {
|
||||||
/// For emitting a metronome
|
/// For emitting a metronome
|
||||||
pub click_out: Arc<RwLock<Option<JackAudioOut>>>,
|
pub click_out: Arc<RwLock<Option<JackAudioOut>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for Clock {
|
impl std::fmt::Debug for Clock {
|
||||||
fn fmt (&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
|
fn fmt (&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
|
||||||
f.debug_struct("Clock")
|
f.debug_struct("Clock")
|
||||||
|
|
@ -100,6 +41,7 @@ impl std::fmt::Debug for Clock {
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clock {
|
impl Clock {
|
||||||
pub fn new (jack: &Jack, bpm: Option<f64>) -> Usually<Self> {
|
pub fn new (jack: &Jack, bpm: Option<f64>) -> Usually<Self> {
|
||||||
let (chunk, transport) = jack.with_client(|c|(c.buffer_size(), c.transport()));
|
let (chunk, transport) = jack.with_client(|c|(c.buffer_size(), c.transport()));
|
||||||
|
|
@ -231,4 +173,8 @@ impl Clock {
|
||||||
ticks_per_beat: ppq as f64
|
ticks_per_beat: ppq as f64
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn next_launch_instant (&self) -> Moment {
|
||||||
|
Moment::from_pulse(self.timebase(), self.next_launch_pulse() as f64)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
mod time_clock; pub use self::time_clock::*;
|
mod clock; pub use self::clock::*;
|
||||||
|
|
||||||
mod time_moment; pub use self::time_moment::*;
|
mod time_moment; pub use self::time_moment::*;
|
||||||
mod time_note; pub use self::time_note::*;
|
mod time_note; pub use self::time_note::*;
|
||||||
mod time_perf; pub use self::time_perf::*;
|
mod time_perf; pub use self::time_perf::*;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue