mirror of
https://codeberg.org/unspeaker/tek.git
synced 2026-08-28 21:06:56 +02:00
This commit is contained in:
parent
7fcab73b04
commit
62f30daac6
6 changed files with 295 additions and 195 deletions
|
|
@ -20,36 +20,61 @@ impl App {
|
|||
}
|
||||
}
|
||||
|
||||
def_command!(ClockCommand: |clock: Clock| {
|
||||
SeekUsec { usec: f64 } => {
|
||||
clock.playhead.update_from_usec(*usec); Ok(None) },
|
||||
SeekSample { sample: f64 } => {
|
||||
clock.playhead.update_from_sample(*sample); Ok(None) },
|
||||
SeekPulse { pulse: f64 } => {
|
||||
clock.playhead.update_from_pulse(*pulse); Ok(None) },
|
||||
SetBpm { bpm: f64 } => Ok(Some(
|
||||
Self::SetBpm { bpm: clock.timebase().bpm.set(*bpm) })),
|
||||
SetQuant { quant: f64 } => Ok(Some(
|
||||
Self::SetQuant { quant: clock.quant.set(*quant) })),
|
||||
SetSync { sync: f64 } => Ok(Some(
|
||||
Self::SetSync { sync: clock.sync.set(*sync) })),
|
||||
#[tek_proc::commands(ClockCommand = "clock")]
|
||||
impl Clock {
|
||||
#[command(SeekUsec = "usec")]
|
||||
fn seek_usec (&mut self, usec: f64) -> Perhaps<ClockCommand> {
|
||||
self.playhead.update_from_usec(usec);
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
Play { position: Option<u32> } => {
|
||||
clock.play_from(*position)?; Ok(None) /* TODO Some(Pause(previousPosition)) */ },
|
||||
Pause { position: Option<u32> } => {
|
||||
clock.pause_at(*position)?; Ok(None) },
|
||||
#[command(SeekSample = "sample")]
|
||||
fn seek_sample (&mut self, sample: f64) -> Perhaps<ClockCommand> {
|
||||
self.playhead.update_from_sample(sample);
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
TogglePlayback { position: u32 } => Ok(if clock.is_rolling() {
|
||||
clock.pause_at(Some(*position))?; None
|
||||
} else {
|
||||
clock.play_from(Some(*position))?; None
|
||||
}),
|
||||
});
|
||||
#[command(SeekPulse = "pulse")]
|
||||
fn seek_pulse (&mut self, pulse: f64) -> Perhaps<ClockCommand> {
|
||||
self.playhead.update_from_pulse(pulse);
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
impl <T: AsRef<Clock>+AsMut<Clock>> HasClock for T {}
|
||||
pub trait HasClock: AsRef<Clock> + AsMut<Clock> {
|
||||
fn clock (&self) -> &Clock { self.as_ref() }
|
||||
fn clock_mut (&mut self) -> &mut Clock { self.as_mut() }
|
||||
#[command(SetBpm = "bpm")]
|
||||
fn set_bpm (&mut self, bpm: f64) -> Perhaps<ClockCommand> {
|
||||
Ok(Some(ClockCommand::SetBpm { bpm: self.timebase().bpm.set(bpm) }))
|
||||
}
|
||||
|
||||
#[command(SetQuant = "quant")]
|
||||
fn set_quant (&mut self, quant: f64) -> Perhaps<ClockCommand> {
|
||||
Ok(Some(ClockCommand::SetQuant { quant: self.quant.set(quant) }))
|
||||
}
|
||||
|
||||
#[command(SetSync = "sync")]
|
||||
fn set_sync (&mut self, sync: f64) -> Perhaps<ClockCommand> {
|
||||
Ok(Some(ClockCommand::SetSync { sync: self.sync.set(sync) }))
|
||||
}
|
||||
|
||||
#[command(Play = "play")]
|
||||
fn play (&mut self, position: Option<u32>) -> Perhaps<ClockCommand> {
|
||||
self.play_from(position)?;
|
||||
Ok(None) /* TODO Some(Pause(previousPosition)) */
|
||||
}
|
||||
|
||||
#[command(Pause = "pause")]
|
||||
fn pause (&mut self, position: Option<u32>) -> Perhaps<ClockCommand> {
|
||||
self.pause_at(position)?;
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
#[command(TogglePlayback = "toggle")]
|
||||
fn toggle (&mut self, position: u32) -> Perhaps<ClockCommand> {
|
||||
Ok(if self.is_rolling() {
|
||||
self.pause_at(Some(position))?; None
|
||||
} else {
|
||||
self.play_from(Some(position))?; None
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// The source of time.
|
||||
|
|
@ -86,6 +111,23 @@ pub trait HasClock: AsRef<Clock> + AsMut<Clock> {
|
|||
#[cfg(feature = "port")] pub click_out: Arc<RwLock<Option<AudioOutput>>>,
|
||||
}
|
||||
|
||||
impl <T: AsRef<Clock>+AsMut<Clock>> HasClock for T {}
|
||||
|
||||
pub trait HasClock: AsRef<Clock> + AsMut<Clock> {
|
||||
fn clock (&self) -> &Clock {
|
||||
self.as_ref()
|
||||
}
|
||||
fn clock_mut (&mut self) -> &mut Clock {
|
||||
self.as_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: HasClock> Act<T> for ClockCommand {
|
||||
fn act (&self, state: &mut T) -> Perhaps<Self> {
|
||||
self.act(state.clock_mut()) // awesome
|
||||
}
|
||||
}
|
||||
|
||||
/// Quantization setting for launching clips
|
||||
///
|
||||
/// ```
|
||||
|
|
@ -183,35 +225,6 @@ impl Quantize {
|
|||
}
|
||||
}
|
||||
|
||||
/// Define and implement a unit of time
|
||||
#[macro_export] macro_rules! impl_time_unit {
|
||||
($T:ident) => {
|
||||
impl Gettable<f64> for $T {
|
||||
fn get (&self) -> f64 { self.0.load(Relaxed) }
|
||||
}
|
||||
impl InteriorMutable<f64> for $T {
|
||||
fn set (&self, value: f64) -> f64 {
|
||||
let old = self.get();
|
||||
self.0.store(value, Relaxed);
|
||||
old
|
||||
}
|
||||
}
|
||||
impl TimeUnit for $T {}
|
||||
impl_op!($T, Add, add, |a, b|{a + b});
|
||||
impl_op!($T, Sub, sub, |a, b|{a - b});
|
||||
impl_op!($T, Mul, mul, |a, b|{a * b});
|
||||
impl_op!($T, Div, div, |a, b|{a / b});
|
||||
impl_op!($T, Rem, rem, |a, b|{a % b});
|
||||
impl From<f64> for $T { fn from (value: f64) -> Self { Self(value.into()) } }
|
||||
impl From<usize> for $T { fn from (value: usize) -> Self { Self((value as f64).into()) } }
|
||||
impl From<$T> for f64 { fn from (value: $T) -> Self { value.get() } }
|
||||
impl From<$T> for usize { fn from (value: $T) -> Self { value.get() as usize } }
|
||||
impl From<&$T> for f64 { fn from (value: &$T) -> Self { value.get() } }
|
||||
impl From<&$T> for usize { fn from (value: &$T) -> Self { value.get() as usize } }
|
||||
impl Clone for $T { fn clone (&self) -> Self { Self(self.get().into()) } }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for Clock {
|
||||
fn fmt (&self, f: &mut Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
|
||||
f.debug_struct("Clock")
|
||||
|
|
@ -397,14 +410,38 @@ impl Clock {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: HasClock> Act<T> for ClockCommand {
|
||||
fn act (&self, state: &mut T) -> Perhaps<Self> {
|
||||
self.act(state.clock_mut()) // awesome
|
||||
impl_has!(Clock: |self: Track|self.sequencer.clock);
|
||||
impl_default!(Timebase: Self::new(48000f64, 150f64, DEFAULT_PPQ));
|
||||
|
||||
/// Define and implement a unit of time
|
||||
#[macro_export] macro_rules! impl_time_unit {
|
||||
($T:ident) => {
|
||||
impl Gettable<f64> for $T {
|
||||
fn get (&self) -> f64 { self.0.load(Relaxed) }
|
||||
}
|
||||
impl InteriorMutable<f64> for $T {
|
||||
fn set (&self, value: f64) -> f64 {
|
||||
let old = self.get();
|
||||
self.0.store(value, Relaxed);
|
||||
old
|
||||
}
|
||||
}
|
||||
impl TimeUnit for $T {}
|
||||
impl_op!($T, Add, add, |a, b|{a + b});
|
||||
impl_op!($T, Sub, sub, |a, b|{a - b});
|
||||
impl_op!($T, Mul, mul, |a, b|{a * b});
|
||||
impl_op!($T, Div, div, |a, b|{a / b});
|
||||
impl_op!($T, Rem, rem, |a, b|{a % b});
|
||||
impl From<f64> for $T { fn from (value: f64) -> Self { Self(value.into()) } }
|
||||
impl From<usize> for $T { fn from (value: usize) -> Self { Self((value as f64).into()) } }
|
||||
impl From<$T> for f64 { fn from (value: $T) -> Self { value.get() } }
|
||||
impl From<$T> for usize { fn from (value: $T) -> Self { value.get() as usize } }
|
||||
impl From<&$T> for f64 { fn from (value: &$T) -> Self { value.get() } }
|
||||
impl From<&$T> for usize { fn from (value: &$T) -> Self { value.get() as usize } }
|
||||
impl Clone for $T { fn clone (&self) -> Self { Self(self.get().into()) } }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "clock")] impl_has!(Clock: |self: Track|self.sequencer.clock);
|
||||
impl_default!(Timebase: Self::new(48000f64, 150f64, DEFAULT_PPQ));
|
||||
impl_time_unit!(SampleCount);
|
||||
impl_time_unit!(SampleRate);
|
||||
impl_time_unit!(Microsecond);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue