mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
wip: more time traits
This commit is contained in:
parent
5a18a2023d
commit
e6a37cfc36
2 changed files with 36 additions and 47 deletions
|
|
@ -16,7 +16,7 @@ pub(crate) use std::thread::{spawn, JoinHandle};
|
|||
pub(crate) use std::time::Duration;
|
||||
pub(crate) use atomic_float::*;
|
||||
use better_panic::{Settings, Verbosity};
|
||||
use std::ops::{Add, Sub, Mul, Div};
|
||||
use std::ops::{Add, Sub, Mul, Div, Rem};
|
||||
use std::cmp::{Ord, Eq, PartialEq};
|
||||
use std::fmt::{Debug, Display};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
use crate::*;
|
||||
use std::iter::Iterator;
|
||||
|
||||
pub trait TimeUnit: Mul<Self, Output=Self> + Div<Self, Output=Self> + From<f64> + Sized {}
|
||||
|
||||
impl<T> TimeUnit for T
|
||||
where T: Mul<Self, Output=Self> + Div<Self, Output=Self> + From<f64> + Sized {}
|
||||
pub trait TimeUnit: Mul<Self, Output=Self> + Div<Self, Output=Self>
|
||||
+ Rem<Self, Output=Self> + From<f64> + Copy {}
|
||||
impl<T> TimeUnit for T where T: Mul<Self, Output=Self> + Div<Self, Output=Self>
|
||||
+ Rem<Self, Output=Self> + From<f64> + Copy {}
|
||||
|
||||
/// Trait for struct that defines a sample rate in hertz (samples per second)
|
||||
pub trait TimeSR<T: TimeUnit> {
|
||||
|
|
@ -27,6 +28,30 @@ pub trait TimeBPM<T: TimeUnit> {
|
|||
#[inline] fn usec_per_beat (&self) -> T { T::from(60_000_000f64) / self.bpm() }
|
||||
/// Return the number of beats in a second
|
||||
#[inline] fn beat_per_second (&self) -> T { self.bpm() / T::from(60_000_000f64) }
|
||||
/// Return the duration of a note in microseconds
|
||||
#[inline] fn note_to_usec (&self, (num, den): (T, T)) -> T {
|
||||
T::from(4.0) * self.usec_per_beat() * num / den
|
||||
}
|
||||
/// Return the quantized position of a moment in time given a step
|
||||
#[inline] fn quantize (&self, step: (T, T), time: T) -> (T, T) {
|
||||
let step = self.note_to_usec(step);
|
||||
(time / step, time % step)
|
||||
}
|
||||
/// Quantize a collection of events
|
||||
#[inline] fn quantize_into <E: Iterator<Item=(T, T)> + Sized, U> (
|
||||
&self, step: (T, T), events: E
|
||||
) -> Vec<(T, U)> {
|
||||
let step = (step.0.into(), step.1.into());
|
||||
events
|
||||
.map(|(time, event)|(self.quantize(step, time).0, event))
|
||||
.collect()
|
||||
}
|
||||
#[inline] fn note_to_frame (&self, note: (T, T)) -> T where Self: TimeSR<T> {
|
||||
self.usec_to_frame(self.note_to_usec(note))
|
||||
}
|
||||
#[inline] fn usec_to_frame (&self, usec: T) -> T where Self: TimeSR<T> {
|
||||
usec * self.sr() / T::from(1000f64)
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait for struct that defines a MIDI resolution in pulses per quaver (beat)
|
||||
|
|
@ -72,6 +97,12 @@ pub struct Timebase {
|
|||
/// Ticks per beat
|
||||
pub ppq: AtomicF64,
|
||||
}
|
||||
impl Default for Timebase { fn default () -> Self { Self::new(48000f64, 150f64, 96f64) } }
|
||||
impl Timebase {
|
||||
pub fn new (s: impl Into<AtomicF64>, b: impl Into<AtomicF64>, p: impl Into<AtomicF64>) -> Self {
|
||||
Self { sr: s.into(), bpm: b.into(), ppq: p.into() }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TransportTime {
|
||||
|
|
@ -133,48 +164,6 @@ pub trait TimePoint<T>: TimeFrame<T> + TimePulse<T> + TimeUsec<T> {}
|
|||
pub trait TimeSync<T> { fn sync (&self) -> T; fn set_sync (&self, sync: T) -> T; }
|
||||
pub trait TimeQuant<T> { fn quant (&self) -> T; fn set_quant (&self, quant: T); }
|
||||
|
||||
impl Default for Timebase {
|
||||
fn default () -> Self { Self::new(48000f64, 150f64, 96f64) }
|
||||
}
|
||||
|
||||
impl Timebase {
|
||||
pub fn new (
|
||||
sr: impl Into<AtomicF64>, bpm: impl Into<AtomicF64>, ppq: impl Into<AtomicF64>
|
||||
) -> Self {
|
||||
Self { sr: sr.into(), bpm: bpm.into(), ppq: ppq.into() }
|
||||
}
|
||||
|
||||
#[inline] pub fn note_to_usec (&self, (num, den): (f64, f64)) -> f64 {
|
||||
4.0 * self.usec_per_beat() * num / den
|
||||
}
|
||||
|
||||
#[inline] pub fn note_to_frame (&self, note: (f64, f64)) -> f64 {
|
||||
self.usec_to_frame(self.note_to_usec(note))
|
||||
}
|
||||
#[inline] fn usec_to_frame (&self, usec: f64) -> f64 {
|
||||
usec * self.sr() / 1000.0
|
||||
}
|
||||
|
||||
#[inline] pub fn quantize (
|
||||
&self, step: (f64, f64), time: f64
|
||||
) -> (f64, f64) {
|
||||
let step = self.note_to_usec(step);
|
||||
(time / step, time % step)
|
||||
}
|
||||
|
||||
#[inline] pub fn quantize_into <E, T> (
|
||||
&self, step: (f64, f64), events: E
|
||||
) -> Vec<(f64, T)>
|
||||
where E: std::iter::Iterator<Item=(f64, T)> + Sized
|
||||
{
|
||||
let step = (step.0.into(), step.1.into());
|
||||
events
|
||||
.map(|(time, event)|(self.quantize(step, time).0, event))
|
||||
.collect()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// (pulses, name)
|
||||
pub const NOTE_DURATIONS: [(usize, &str);26] = [
|
||||
(1, "1/384"),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue