mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-08 20:56:43 +01:00
feat: draw bpm and bbt
This commit is contained in:
parent
c06b9d16e2
commit
b1df7bf4e6
3 changed files with 100 additions and 90 deletions
111
src/time.rs
111
src/time.rs
|
|
@ -32,48 +32,71 @@ pub enum NoteDuration {
|
|||
}
|
||||
|
||||
impl Timebase {
|
||||
pub fn rate (&self) -> usize {
|
||||
#[inline] pub fn rate (&self) -> usize {
|
||||
self.rate.load(Ordering::Relaxed)
|
||||
}
|
||||
pub fn tempo (&self) -> usize {
|
||||
#[inline] pub fn tempo (&self) -> usize {
|
||||
self.tempo.load(Ordering::Relaxed)
|
||||
}
|
||||
pub fn ppq (&self) -> usize {
|
||||
#[inline] pub fn ppq (&self) -> usize {
|
||||
self.ppq.load(Ordering::Relaxed)
|
||||
}
|
||||
|
||||
/// Beats per second
|
||||
#[inline] fn bps (&self) -> f64 {
|
||||
#[inline] fn beats_per_second (&self) -> f64 {
|
||||
self.tempo() as f64 / 60000.0
|
||||
}
|
||||
/// Frames per second
|
||||
#[inline] fn fps (&self) -> usize {
|
||||
#[inline] fn frames_per_second (&self) -> usize {
|
||||
self.rate()
|
||||
}
|
||||
/// Frames per beat
|
||||
#[inline] pub fn fpb (&self) -> f64 {
|
||||
self.fps() as f64 / self.bps()
|
||||
#[inline] pub fn frames_per_beat (&self) -> f64 {
|
||||
self.frames_per_second() as f64 / self.beats_per_second()
|
||||
}
|
||||
/// Frames per tick FIXME double times
|
||||
#[inline] fn fpt (&self) -> f64 {
|
||||
self.fps() as f64 / self.tps()
|
||||
#[inline] pub fn frames_per_tick (&self) -> f64 {
|
||||
self.frames_per_second() as f64 / self.ticks_per_second()
|
||||
}
|
||||
/// Frames per loop
|
||||
#[inline] fn fpl (&self, steps: f64, steps_per_beat: f64) -> f64 {
|
||||
self.fpb() * steps / steps_per_beat
|
||||
#[inline] fn frames_per_loop (&self, steps: f64, steps_per_beat: f64) -> f64 {
|
||||
self.frames_per_beat() * steps / steps_per_beat
|
||||
}
|
||||
/// Ticks per beat
|
||||
#[inline] fn tpb (&self) -> f64 {
|
||||
#[inline] fn ticks_per_beat (&self) -> f64 {
|
||||
self.ppq.load(Ordering::Relaxed) as f64
|
||||
}
|
||||
/// Ticks per second
|
||||
#[inline] fn tps (&self) -> f64 {
|
||||
self.bps() * self.tpb()
|
||||
#[inline] fn ticks_per_second (&self) -> f64 {
|
||||
self.beats_per_second() * self.ticks_per_beat()
|
||||
}
|
||||
#[inline] pub fn frame_to_usec (&self, frame: usize) -> usize {
|
||||
frame * 1000000 / self.rate()
|
||||
}
|
||||
#[inline] pub fn usec_to_frame (&self, usec: usize) -> usize {
|
||||
usec * self.rate() / 1000
|
||||
}
|
||||
#[inline] pub fn usec_per_bar (&self, beats_per_bar: usize) -> usize {
|
||||
self.usec_per_beat() * beats_per_bar
|
||||
}
|
||||
#[inline] pub fn usec_per_beat (&self) -> usize {
|
||||
60_000_000_000 / self.tempo()
|
||||
}
|
||||
#[inline] pub fn usec_per_step (&self, divisor: usize) -> usize {
|
||||
self.usec_per_beat() / divisor
|
||||
}
|
||||
#[inline] pub fn usec_per_tick (&self) -> usize {
|
||||
self.usec_per_beat() / self.ppq()
|
||||
}
|
||||
#[inline] pub fn note_to_usec (&self, note: &NoteDuration) -> usize {
|
||||
match note {
|
||||
NoteDuration::Nth(time, flies) =>
|
||||
self.usec_per_beat() * *time / *flies,
|
||||
NoteDuration::Dotted(note) =>
|
||||
self.note_to_usec(note) * 3 / 2,
|
||||
NoteDuration::Tuplet(n, note) =>
|
||||
self.note_to_usec(note) * 2 / *n,
|
||||
}
|
||||
}
|
||||
#[inline] pub fn note_to_frame (&self, note: &NoteDuration) -> usize {
|
||||
self.usec_to_frame(self.note_to_usec(note))
|
||||
}
|
||||
pub fn frames_to_ticks (&self, start: usize, end: usize, fpl: usize) -> Vec<(usize, usize)> {
|
||||
let start_frame = start % fpl;
|
||||
let end_frame = end % fpl;
|
||||
let fpt = self.fpt();
|
||||
let fpt = self.frames_per_tick();
|
||||
let mut ticks = vec![];
|
||||
let mut add_frame = |frame: f64|{
|
||||
let jitter = frame.rem_euclid(fpt);
|
||||
|
|
@ -107,48 +130,8 @@ impl Timebase {
|
|||
}
|
||||
ticks
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn frame_to_usec (&self, frame: usize) -> usize {
|
||||
frame * 1000000 / self.rate()
|
||||
}
|
||||
#[inline]
|
||||
pub fn usec_to_frame (&self, usec: usize) -> usize {
|
||||
usec * self.rate() / 1000
|
||||
}
|
||||
#[inline]
|
||||
pub fn usec_per_bar (&self, beats_per_bar: usize) -> usize {
|
||||
self.usec_per_beat() * beats_per_bar
|
||||
}
|
||||
#[inline]
|
||||
pub fn usec_per_beat (&self) -> usize {
|
||||
60_000_000_000 / self.tempo()
|
||||
}
|
||||
#[inline]
|
||||
pub fn usec_per_step (&self, divisor: usize) -> usize {
|
||||
self.usec_per_beat() / divisor
|
||||
}
|
||||
#[inline]
|
||||
pub fn usec_per_tick (&self) -> usize {
|
||||
self.usec_per_beat() / self.ppq()
|
||||
}
|
||||
#[inline]
|
||||
pub fn usec_per_note (&self, note: &NoteDuration) -> usize {
|
||||
match note {
|
||||
NoteDuration::Nth(time, flies) =>
|
||||
self.usec_per_beat() * *time / *flies,
|
||||
NoteDuration::Dotted(note) =>
|
||||
self.usec_per_note(note) * 3 / 2,
|
||||
NoteDuration::Tuplet(n, note) =>
|
||||
self.usec_per_note(note) * 2 / *n,
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
pub fn frame_per_note (&self, note: &NoteDuration) -> usize {
|
||||
self.usec_to_frame(self.usec_per_note(note))
|
||||
}
|
||||
pub fn quantize (&self, step: &NoteDuration, time: usize) -> (usize, usize) {
|
||||
let step = self.usec_per_note(step);
|
||||
let step = self.note_to_usec(step);
|
||||
let time = time / step;
|
||||
let offset = time % step;
|
||||
(time, offset)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue