mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
store Timebase with Instant
This commit is contained in:
parent
eba7044916
commit
276e7ac3c5
2 changed files with 91 additions and 60 deletions
|
|
@ -155,7 +155,7 @@ pub trait PulsesPerQuaver<U: TimeUnit> {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait FramePosition<U: TimeUnit> {
|
||||
pub trait SamplePosition<U: TimeUnit> {
|
||||
fn sample (&self) -> U;
|
||||
fn set_sample (&self, sample: U);
|
||||
}
|
||||
|
|
@ -233,54 +233,85 @@ impl PulsesPerQuaver<f64> for Timebase {
|
|||
#[derive(Debug, Default)]
|
||||
/// Represents a point in time in all scales
|
||||
pub struct Instant {
|
||||
timebase: Arc<Timebase>,
|
||||
/// Current time in microseconds
|
||||
pub usec: AtomicUsize,
|
||||
usec: AtomicUsize,
|
||||
/// Current time in audio samples
|
||||
pub sample: AtomicUsize,
|
||||
sample: AtomicUsize,
|
||||
/// Current time in MIDI pulses
|
||||
pub pulse: AtomicF64,
|
||||
pulse: AtomicF64,
|
||||
}
|
||||
impl FramePosition<usize> for Instant {
|
||||
impl SampleRate<f64> for Instant {
|
||||
#[inline] fn sr (&self) -> f64 { self.timebase.sr() }
|
||||
#[inline] fn set_sr (&self, sr: f64) { self.timebase.set_sr(sr); }
|
||||
}
|
||||
impl BeatsPerMinute<f64> for Instant {
|
||||
#[inline] fn bpm (&self) -> f64 { self.timebase.bpm() }
|
||||
#[inline] fn set_bpm (&self, bpm: f64) { self.timebase.set_bpm(bpm); }
|
||||
}
|
||||
impl PulsesPerQuaver<f64> for Instant {
|
||||
const DEFAULT_PPQ: f64 = 96f64;
|
||||
#[inline] fn ppq (&self) -> f64 { self.timebase.ppq() }
|
||||
#[inline] fn set_ppq (&self, ppq: f64) { self.timebase.set_ppq(ppq); }
|
||||
}
|
||||
impl SamplePosition<usize> for Instant {
|
||||
#[inline] fn sample (&self) -> usize { self.sample.load(Ordering::Relaxed) }
|
||||
#[inline] fn set_sample (&self, sample: usize) { self.sample.store(sample, Ordering::Relaxed); }
|
||||
#[inline] fn set_sample (&self, sample: usize) {
|
||||
self.sample.store(sample, Ordering::Relaxed);
|
||||
self.set_usec(self.timebase.samples_to_usec(sample as f64) as usize);
|
||||
self.set_pulse(self.timebase.samples_to_pulse(sample as f64));
|
||||
}
|
||||
}
|
||||
impl UsecPosition<usize> for Instant {
|
||||
#[inline] fn usec (&self) -> usize { self.usec.load(Ordering::Relaxed) }
|
||||
#[inline] fn set_usec (&self, usec: usize) { self.usec.store(usec, Ordering::Relaxed); }
|
||||
#[inline] fn set_usec (&self, usec: usize) {
|
||||
self.usec.store(usec, Ordering::Relaxed);
|
||||
self.set_sample(self.timebase.usecs_to_sample(usec as f64) as usize);
|
||||
self.set_pulse(self.timebase.usecs_to_pulse(usec as f64));
|
||||
}
|
||||
}
|
||||
impl PulsePosition<f64> for Instant {
|
||||
#[inline] fn pulse (&self) -> f64 { self.pulse.load(Ordering::Relaxed) }
|
||||
#[inline] fn set_pulse (&self, usec: f64) { self.pulse.store(usec, Ordering::Relaxed); }
|
||||
#[inline] fn set_pulse (&self, pulse: f64) {
|
||||
self.pulse.store(pulse, Ordering::Relaxed);
|
||||
self.set_sample(self.timebase.pulses_to_sample(pulse) as usize);
|
||||
self.set_usec(self.timebase.pulses_to_usec(pulse) as usize);
|
||||
}
|
||||
}
|
||||
impl PulsePosition<usize> for Instant {
|
||||
#[inline] fn pulse (&self) -> usize { self.pulse.load(Ordering::Relaxed) as usize }
|
||||
#[inline] fn set_pulse (&self, usec: usize) { self.pulse.store(usec as f64, Ordering::Relaxed); }
|
||||
#[inline] fn set_pulse (&self, pulse: usize) {
|
||||
PulsePosition::<f64>::set_pulse(self, pulse as f64)
|
||||
}
|
||||
}
|
||||
impl Instant {
|
||||
pub fn from_usec (timebase: &Timebase, usec: usize) -> Self {
|
||||
pub fn from_usec (timebase: &Arc<Timebase>, usec: usize) -> Self {
|
||||
Self {
|
||||
usec: usec.into(),
|
||||
sample: (timebase.usecs_to_sample(usec as f64) as usize).into(),
|
||||
pulse: timebase.usecs_to_pulse(usec as f64).into()
|
||||
usec: usec.into(),
|
||||
sample: (timebase.usecs_to_sample(usec as f64) as usize).into(),
|
||||
pulse: timebase.usecs_to_pulse(usec as f64).into(),
|
||||
timebase: timebase.clone(),
|
||||
}
|
||||
}
|
||||
pub fn from_sample (timebase: &Timebase, sample: usize) -> Self {
|
||||
pub fn from_sample (timebase: &Arc<Timebase>, sample: usize) -> Self {
|
||||
Self {
|
||||
sample: sample.into(),
|
||||
usec: (timebase.samples_to_usec(sample as f64) as usize).into(),
|
||||
pulse: timebase.samples_to_pulse(sample as f64).into()
|
||||
sample: sample.into(),
|
||||
usec: (timebase.samples_to_usec(sample as f64) as usize).into(),
|
||||
pulse: timebase.samples_to_pulse(sample as f64).into(),
|
||||
timebase: timebase.clone(),
|
||||
}
|
||||
}
|
||||
pub fn from_pulse (timebase: &Timebase, pulse: f64) -> Self {
|
||||
pub fn from_pulse (timebase: &Arc<Timebase>, pulse: f64) -> Self {
|
||||
Self {
|
||||
pulse: pulse.into(),
|
||||
sample: (timebase.pulses_to_sample(pulse) as usize).into(),
|
||||
usec: (timebase.pulses_to_usec(pulse) as usize).into()
|
||||
pulse: pulse.into(),
|
||||
sample: (timebase.pulses_to_sample(pulse) as usize).into(),
|
||||
usec: (timebase.pulses_to_usec(pulse) as usize).into(),
|
||||
timebase: timebase.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// (pulses, name)
|
||||
/// (pulses, name), assuming 96 PPQ
|
||||
pub const NOTE_DURATIONS: [(usize, &str);26] = [
|
||||
(1, "1/384"),
|
||||
(2, "1/192"),
|
||||
|
|
|
|||
|
|
@ -12,6 +12,44 @@ pub struct TransportTime {
|
|||
/// Launch quantization factor
|
||||
pub sync: AtomicUsize,
|
||||
}
|
||||
impl SampleRate<f64> for TransportTime {
|
||||
#[inline] fn sr (&self) -> f64 { self.timebase.sr() }
|
||||
#[inline] fn set_sr (&self, sr: f64) { self.timebase.set_sr(sr); }
|
||||
}
|
||||
impl BeatsPerMinute<f64> for TransportTime {
|
||||
#[inline] fn bpm (&self) -> f64 { self.timebase.bpm() }
|
||||
#[inline] fn set_bpm (&self, bpm: f64) { self.timebase.set_bpm(bpm); }
|
||||
}
|
||||
impl PulsesPerQuaver<f64> for TransportTime {
|
||||
const DEFAULT_PPQ: f64 = Timebase::DEFAULT_PPQ;
|
||||
#[inline] fn ppq (&self) -> f64 { self.timebase.ppq() }
|
||||
#[inline] fn set_ppq (&self, ppq: f64) { self.timebase.set_ppq(ppq); }
|
||||
}
|
||||
impl PulsesPerQuaver<usize> for TransportTime {
|
||||
const DEFAULT_PPQ: usize = Timebase::DEFAULT_PPQ as usize;
|
||||
#[inline] fn ppq (&self) -> usize { self.timebase.ppq() as usize }
|
||||
#[inline] fn set_ppq (&self, ppq: usize) { self.timebase.set_ppq(ppq as f64); }
|
||||
}
|
||||
impl SamplePosition<usize> for TransportTime {
|
||||
#[inline] fn sample (&self) -> usize { self.instant.sample() }
|
||||
#[inline] fn set_sample (&self, sample: usize) { self.instant.set_sample(sample) }
|
||||
}
|
||||
impl UsecPosition<usize> for TransportTime {
|
||||
#[inline] fn usec (&self) -> usize { self.instant.usec() }
|
||||
#[inline] fn set_usec (&self, usec: usize) { self.instant.set_usec(usec) }
|
||||
}
|
||||
impl PulsePosition<usize> for TransportTime {
|
||||
#[inline] fn pulse (&self) -> usize { self.instant.pulse() }
|
||||
#[inline] fn set_pulse (&self, usec: usize) { self.instant.set_pulse(usec); }
|
||||
}
|
||||
impl Quantize<usize> for TransportTime {
|
||||
#[inline] fn quant (&self) -> usize { self.quant.load(Ordering::Relaxed) }
|
||||
#[inline] fn set_quant (&self, quant: usize) { self.quant.store(quant, Ordering::Relaxed); }
|
||||
}
|
||||
impl LaunchSync<usize> for TransportTime {
|
||||
#[inline] fn sync (&self) -> usize { self.sync.load(Ordering::Relaxed) }
|
||||
#[inline] fn set_sync (&self, sync: usize) { self.sync.store(sync, Ordering::Relaxed); }
|
||||
}
|
||||
/// Stores and displays time-related state.
|
||||
pub struct TransportToolbar<E: Engine> {
|
||||
_engine: PhantomData<E>,
|
||||
|
|
@ -34,44 +72,6 @@ pub struct TransportToolbar<E: Engine> {
|
|||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum TransportToolbarFocus { Bpm, Sync, PlayPause, Clock, Quant, }
|
||||
|
||||
impl SampleRate<f64> for TransportTime {
|
||||
#[inline] fn sr (&self) -> f64 { self.timebase.sr() }
|
||||
#[inline] fn set_sr (&self, sr: f64) { self.timebase.set_sr(sr); }
|
||||
}
|
||||
impl BeatsPerMinute<f64> for TransportTime {
|
||||
#[inline] fn bpm (&self) -> f64 { self.timebase.bpm() }
|
||||
#[inline] fn set_bpm (&self, bpm: f64) { self.timebase.set_bpm(bpm); }
|
||||
}
|
||||
impl PulsesPerQuaver<f64> for TransportTime {
|
||||
const DEFAULT_PPQ: f64 = Timebase::DEFAULT_PPQ;
|
||||
#[inline] fn ppq (&self) -> f64 { self.timebase.ppq() }
|
||||
#[inline] fn set_ppq (&self, ppq: f64) { self.timebase.set_ppq(ppq); }
|
||||
}
|
||||
impl PulsesPerQuaver<usize> for TransportTime {
|
||||
const DEFAULT_PPQ: usize = Timebase::DEFAULT_PPQ as usize;
|
||||
#[inline] fn ppq (&self) -> usize { self.timebase.ppq() as usize }
|
||||
#[inline] fn set_ppq (&self, ppq: usize) { self.timebase.set_ppq(ppq as f64); }
|
||||
}
|
||||
impl FramePosition<usize> for TransportTime {
|
||||
#[inline] fn sample (&self) -> usize { self.instant.sample() }
|
||||
#[inline] fn set_sample (&self, sample: usize) { self.instant.set_sample(sample) }
|
||||
}
|
||||
impl UsecPosition<usize> for TransportTime {
|
||||
#[inline] fn usec (&self) -> usize { self.instant.usec() }
|
||||
#[inline] fn set_usec (&self, usec: usize) { self.instant.set_usec(usec) }
|
||||
}
|
||||
impl PulsePosition<usize> for TransportTime {
|
||||
#[inline] fn pulse (&self) -> usize { self.instant.pulse() }
|
||||
#[inline] fn set_pulse (&self, usec: usize) { self.instant.set_pulse(usec); }
|
||||
}
|
||||
impl Quantize<usize> for TransportTime {
|
||||
#[inline] fn quant (&self) -> usize { self.quant.load(Ordering::Relaxed) }
|
||||
#[inline] fn set_quant (&self, quant: usize) { self.quant.store(quant, Ordering::Relaxed); }
|
||||
}
|
||||
impl LaunchSync<usize> for TransportTime {
|
||||
#[inline] fn sync (&self) -> usize { self.sync.load(Ordering::Relaxed) }
|
||||
#[inline] fn set_sync (&self, sync: usize) { self.sync.store(sync, Ordering::Relaxed); }
|
||||
}
|
||||
impl<E: Engine> TransportToolbar<E> {
|
||||
pub fn new (
|
||||
clock: Option<&Arc<TransportTime>>,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue