fix timing by cleaning it

This commit is contained in:
🪞👃🪞 2024-07-01 16:23:39 +03:00
parent 55a8b67bfb
commit c4d8692b71
5 changed files with 69 additions and 97 deletions

View file

@ -9,20 +9,6 @@ pub struct Timebase {
pub ppq: AtomicUsize,
}
enum QuantizeMode {
Forward,
Backward,
Nearest,
}
struct Loop<T> {
repeat: bool,
pre_start: T,
start: T,
end: T,
post_end: T,
}
/// NoteDuration in musical terms. Has definite usec value
/// for given bpm and sample rate.
pub enum NoteDuration {
@ -32,79 +18,84 @@ pub enum NoteDuration {
}
impl Timebase {
#[inline] pub fn rate (&self) -> usize {
#[inline] fn rate (&self) -> usize {
self.rate.load(Ordering::Relaxed)
}
#[inline] pub fn bpm (&self) -> usize {
self.bpm.load(Ordering::Relaxed)
}
#[inline] pub fn ppq (&self) -> usize {
self.ppq.load(Ordering::Relaxed)
}
#[inline] pub fn pulse_to_frame (&self, pulses: usize) -> usize {
let beat = self.bpm() / 60;
let quaver = beat / 4;
let pulse = quaver / self.ppq();
pulse * pulses
}
#[inline] pub fn frame_to_pulse (&self, frames: usize) -> usize {
let beat = self.bpm() / 60;
let quaver = beat / 4;
let pulse = quaver / self.ppq();
frames / pulse
}
#[inline] fn beats_per_second (&self) -> f64 {
self.bpm() as f64 / 60000.0
}
#[inline] fn frames_per_second (&self) -> usize {
self.rate()
}
#[inline] pub fn frames_per_beat (&self) -> f64 {
self.frames_per_second() as f64 / self.beats_per_second()
}
#[inline] pub fn frames_per_tick (&self) -> f64 {
self.frames_per_second() as f64 / self.ticks_per_second()
}
#[inline] fn frames_per_loop (&self, steps: f64, steps_per_beat: f64) -> f64 {
self.frames_per_beat() * steps / steps_per_beat
}
#[inline] fn ticks_per_beat (&self) -> f64 {
self.ppq.load(Ordering::Relaxed) as f64
}
#[inline] fn ticks_per_second (&self) -> f64 {
self.beats_per_second() * self.ticks_per_beat()
#[inline] fn frame_usec (&self) -> usize {
1_000_000 / self.rate()
}
#[inline] pub fn frame_to_usec (&self, frame: usize) -> usize {
frame * 1000000 / self.rate()
}
#[inline] pub fn usec_to_frame (&self, usec: usize) -> usize {
#[inline] pub fn bpm (&self) -> usize {
self.bpm.load(Ordering::Relaxed)
}
#[inline] fn beat_usec (&self) -> usize {
60_000_000_000_000 / self.bpm()
}
#[inline] fn beats_per_second (&self) -> f64 {
self.bpm() as f64 / 60000000.0
}
#[inline] pub fn ppq (&self) -> usize {
self.ppq.load(Ordering::Relaxed)
}
#[inline] fn pulse_usec (&self) -> usize {
self.beat_usec() / self.ppq()
}
#[inline] fn pulse_frame (&self) -> usize {
self.pulse_usec() / self.frame_usec()
}
#[inline] pub fn pulses_frames (&self, pulses: usize) -> usize {
self.pulse_frame() * pulses
}
#[inline] pub fn frames_pulses (&self, frames: usize) -> usize {
frames / self.pulse_frame()
}
#[inline] pub fn frames_per_tick (&self) -> f64 {
self.rate() as f64 / self.ticks_per_second()
}
#[inline] fn ticks_per_second (&self) -> f64 {
self.beats_per_second() * self.ppq() as f64
}
#[inline] 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.bpm()
}
#[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()
self.beat_usec() / divisor
}
#[inline] pub fn note_to_usec (&self, note: &NoteDuration) -> usize {
match note {
NoteDuration::Nth(time, flies) =>
self.usec_per_beat() * *time / *flies,
self.beat_usec() * *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))
}
#[inline] pub fn quantize (&self, step: &NoteDuration, time: usize) -> (usize, usize) {
let step = self.note_to_usec(step);
let time = time / step;
let offset = time % step;
(time, offset)
}
#[inline] pub fn quantize_into <T, U> (&self, step: &NoteDuration, events: U) -> Vec<(usize, T)>
where U: std::iter::Iterator<Item=(usize, T)> + Sized
{
events
.map(|(time, event)|(self.quantize(step, time).0, event))
.collect()
}
pub fn frames_to_ticks (&self, start: usize, end: usize, quant: usize) -> Vec<(usize, usize)> {
let start_frame = start % quant;
let end_frame = end % quant;
@ -142,18 +133,5 @@ impl Timebase {
}
ticks
}
pub fn quantize (&self, step: &NoteDuration, time: usize) -> (usize, usize) {
let step = self.note_to_usec(step);
let time = time / step;
let offset = time % step;
(time, offset)
}
pub fn quantize_into <T, U> (&self, step: &NoteDuration, events: U) -> Vec<(usize, T)>
where U: std::iter::Iterator<Item=(usize, T)> + Sized
{
events
.map(|(time, event)|(self.quantize(step, time).0, event))
.collect()
}
}