pub struct Timebase { /// Sample rate rate: u64, /// Current frame frame: u64, /// Beats per bar signature: (u64, u64), /// Beats per minute bpm: f64, } impl Timebase { pub fn new (rate: u64, signature: (u64, u64), bpm: f64) -> Self { Self { rate, frame: 0, signature, bpm, } } pub fn seconds (&self) -> f64 { self.frame as f64 / self.rate as f64 } pub fn minutes (&self) -> f64 { self.seconds / 60.0 } pub fn beats (&self) -> f64 { self.minutes / self.bpm } pub fn bar (&self) -> u64 { ((self.beats() * self.signature.0 as f64) / self.signature.1 as f64) as u64 } pub fn beat (&self) -> u64 { ((self.beats() * self.signature.0 as f64) % self.signature.1 as f64) as u64 } pub fn time_string (&self) -> String { let minutes = self.minutes() as u64; let seconds = self.seconds() as u64; let milliseconds = self.seconds() - seconds; format!("{minutes}:{seconds}.{milliseconds:03}") } pub fn beat_string (&self) -> String { let beats = self.beats() as u64; format!("{beats} {}/{}", minutes, self.beat(), self.signature.1) } }