/// Number of data frames in a second. #[derive(Debug)] pub struct Hz(pub u32); /// One data frame. #[derive(Debug)] pub struct Frame(pub u32); /// One microsecond. #[derive(Debug)] pub struct Usec(pub u64); /// Beats per minute as `120000` = 120.000BPM #[derive(Debug)] pub struct Tempo(pub u64); /// Time signature: N/Mths per bar. #[derive(Debug)] pub struct Signature(pub u32, pub u32); /// NoteDuration in musical terms. Has definite usec value /// for given bpm and sample rate. pub enum NoteDuration { Nth(u16, u16), Dotted(Box), Tuplet(u16, Box), } impl Frame { #[inline] pub fn to_usec (&self, rate: &Hz) -> Usec { Usec((self.0 as u64 * 1000000) / rate.0 as u64) } } impl Usec { #[inline] pub fn to_frame (&self, rate: &Hz) -> Frame { Frame(((self.0 * rate.0 as u64) / 1000) as u32) } } impl Tempo { #[inline] pub fn usec_per_bar (&self, beats: u64) -> Usec { Usec(beats * self.usec_per_beat().0) } #[inline] pub fn usec_per_beat (&self) -> Usec { Usec(60_000_000_000 / self.0 as u64) } #[inline] pub fn usec_per_step (&self, divisor: u64) -> Usec { Usec(self.usec_per_beat().0 / divisor as u64) } #[inline] pub fn quantize (&self, step: &NoteDuration, time: Usec) -> Usec { let step = step.to_usec(self); let t = time.0 / step.0; Usec(step.0 * t) } #[inline] pub fn quantize_into (&self, step: &NoteDuration, events: U) -> Vec<(Usec, T)> where U: std::iter::Iterator + Sized { events .map(|(time, event)|(self.quantize(step, time), event)) .collect() } } impl NoteDuration { fn to_usec (&self, bpm: &Tempo) -> Usec { Usec(match self { Self::Nth(time, flies) => bpm.usec_per_beat().0 * *time as u64 / *flies as u64, Self::Dotted(duration) => duration.to_usec(bpm).0 * 3 / 2, Self::Tuplet(n, duration) => duration.to_usec(bpm).0 * 2 / *n as u64, }) } fn to_frame (&self, bpm: &Tempo, rate: &Hz) -> Frame { self.to_usec(bpm).to_frame(rate) } } struct Loop { repeat: bool, pre_start: T, start: T, end: T, post_end: T, }