add converting constructors for Instant

This commit is contained in:
🪞👃🪞 2024-10-27 16:52:46 +02:00
parent fec6294c7b
commit b60aca88d3

View file

@ -27,10 +27,18 @@ pub trait SampleRate<U: TimeUnit> {
#[inline] fn usec_per_sample (&self) -> U where U: TimeFloat {
U::from(1_000_000f64 / self.sr().into())
}
/// Return the duration of a sample in microseconds (floating)
#[inline] fn sample_per_usec (&self) -> U where U: TimeFloat {
U::from(self.sr().into() / 1_000_000f64)
}
/// Convert a number of samples to microseconds (floating)
#[inline] fn samples_to_usec (&self, samples: U) -> U where U: TimeFloat {
samples * self.usec_per_sample()
}
/// Convert a number of microseconds to samples (floating)
#[inline] fn usecs_to_sample (&self, usecs: U) -> U where U: TimeFloat, Self: SampleRate<U> {
usecs * self.sample_per_usec()
}
}
/// Trait for struct that defines a tempo in beats per minute
@ -79,11 +87,11 @@ pub trait PulsesPerQuaver<U: TimeUnit> {
fn ppq (&self) -> U;
/// Set the PPQ
fn set_ppq (&self, ppq: U);
/// Return number of pulses to which a number of microseconds corresponds (BPM-dependent)
#[inline] fn usecs_to_pulse (&self, usec: U) -> U
/// Return duration of a pulse in microseconds (BPM-dependent)
#[inline] fn pulse_per_usec (&self) -> U
where U: TimeFloat, Self: BeatsPerMinute<U>
{
usec / self.usec_per_pulse()
self.ppq() / self.usec_per_beat()
}
/// Return duration of a pulse in microseconds (BPM-dependent)
#[inline] fn usec_per_pulse (&self) -> U
@ -91,6 +99,18 @@ pub trait PulsesPerQuaver<U: TimeUnit> {
{
self.usec_per_beat() / self.ppq()
}
/// Return number of pulses to which a number of microseconds corresponds (BPM-dependent)
#[inline] fn usecs_to_pulse (&self, usec: U) -> U
where U: TimeFloat, Self: BeatsPerMinute<U>
{
usec / self.pulse_per_usec()
}
/// Convert a number of pulses to a sample number (SR- and BPM-dependent)
#[inline] fn pulses_to_usec (&self, pulse: U) -> U
where U: TimeFloat, Self: SampleRate<U> + BeatsPerMinute<U>
{
pulse / self.usec_per_pulse()
}
/// Return number of pulses in a second (BPM-dependent)
#[inline] fn pulses_per_second (&self) -> U
where U: TimeFloat, Self: BeatsPerMinute<U>
@ -236,6 +256,29 @@ 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); }
}
impl Instant {
pub fn from_usec (timebase: &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()
}
}
pub fn from_sample (timebase: &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()
}
}
pub fn from_pulse (timebase: &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()
}
}
}
/// (pulses, name)
pub const NOTE_DURATIONS: [(usize, &str);26] = [