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 std::time::Duration;
|
||||||
pub(crate) use atomic_float::*;
|
pub(crate) use atomic_float::*;
|
||||||
use better_panic::{Settings, Verbosity};
|
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::cmp::{Ord, Eq, PartialEq};
|
||||||
use std::fmt::{Debug, Display};
|
use std::fmt::{Debug, Display};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
use std::iter::Iterator;
|
||||||
|
|
||||||
pub trait TimeUnit: 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
|
impl<T> TimeUnit for T where T: Mul<Self, Output=Self> + Div<Self, Output=Self>
|
||||||
where T: Mul<Self, Output=Self> + Div<Self, Output=Self> + From<f64> + Sized {}
|
+ Rem<Self, Output=Self> + From<f64> + Copy {}
|
||||||
|
|
||||||
/// Trait for struct that defines a sample rate in hertz (samples per second)
|
/// Trait for struct that defines a sample rate in hertz (samples per second)
|
||||||
pub trait TimeSR<T: TimeUnit> {
|
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() }
|
#[inline] fn usec_per_beat (&self) -> T { T::from(60_000_000f64) / self.bpm() }
|
||||||
/// Return the number of beats in a second
|
/// Return the number of beats in a second
|
||||||
#[inline] fn beat_per_second (&self) -> T { self.bpm() / T::from(60_000_000f64) }
|
#[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)
|
/// Trait for struct that defines a MIDI resolution in pulses per quaver (beat)
|
||||||
|
|
@ -72,6 +97,12 @@ pub struct Timebase {
|
||||||
/// Ticks per beat
|
/// Ticks per beat
|
||||||
pub ppq: AtomicF64,
|
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)]
|
#[derive(Debug)]
|
||||||
pub struct TransportTime {
|
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 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); }
|
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)
|
/// (pulses, name)
|
||||||
pub const NOTE_DURATIONS: [(usize, &str);26] = [
|
pub const NOTE_DURATIONS: [(usize, &str);26] = [
|
||||||
(1, "1/384"),
|
(1, "1/384"),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue