mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
71 lines
2.1 KiB
Rust
71 lines
2.1 KiB
Rust
use crate::*;
|
|
|
|
pub const DEFAULT_PPQ: f64 = 96.0;
|
|
|
|
/// FIXME: remove this and use PPQ from timebase everywhere:
|
|
pub const PPQ: usize = 96;
|
|
|
|
/// MIDI resolution in PPQ (pulses per quarter note)
|
|
#[derive(Debug, Default)] pub struct PulsesPerQuaver(AtomicF64);
|
|
impl_time_unit!(PulsesPerQuaver);
|
|
|
|
/// Timestamp in MIDI pulses
|
|
#[derive(Debug, Default)] pub struct Pulse(AtomicF64);
|
|
impl_time_unit!(Pulse);
|
|
|
|
/// Tempo in beats per minute
|
|
#[derive(Debug, Default)] pub struct BeatsPerMinute(AtomicF64);
|
|
impl_time_unit!(BeatsPerMinute);
|
|
|
|
/// Quantization setting for launching clips
|
|
#[derive(Debug, Default)] pub struct LaunchSync(AtomicF64);
|
|
impl_time_unit!(LaunchSync);
|
|
impl LaunchSync {
|
|
pub fn next (&self) -> f64 {
|
|
NoteDuration::next(self.get() as usize) as f64
|
|
}
|
|
pub fn prev (&self) -> f64 {
|
|
NoteDuration::prev(self.get() as usize) as f64
|
|
}
|
|
}
|
|
|
|
/// Quantization setting for notes
|
|
#[derive(Debug, Default)] pub struct Quantize(AtomicF64);
|
|
impl_time_unit!(Quantize);
|
|
impl Quantize {
|
|
pub fn next (&self) -> f64 {
|
|
NoteDuration::next(self.get() as usize) as f64
|
|
}
|
|
pub fn prev (&self) -> f64 {
|
|
NoteDuration::prev(self.get() as usize) as f64
|
|
}
|
|
}
|
|
|
|
/// Iterator that emits subsequent ticks within a range.
|
|
pub struct TicksIterator {
|
|
pub spp: f64,
|
|
pub sample: usize,
|
|
pub start: usize,
|
|
pub end: usize,
|
|
}
|
|
impl Iterator for TicksIterator {
|
|
type Item = (usize, usize);
|
|
fn next (&mut self) -> Option<Self::Item> {
|
|
loop {
|
|
if self.sample > self.end { return None }
|
|
let spp = self.spp;
|
|
let sample = self.sample as f64;
|
|
let start = self.start;
|
|
let end = self.end;
|
|
self.sample += 1;
|
|
//println!("{spp} {sample} {start} {end}");
|
|
let jitter = sample.rem_euclid(spp); // ramps
|
|
let next_jitter = (sample + 1.0).rem_euclid(spp);
|
|
if jitter > next_jitter { // at crossing:
|
|
let time = (sample as usize) % (end as usize-start as usize);
|
|
let tick = (sample / spp) as usize;
|
|
return Some((time, tick))
|
|
}
|
|
}
|
|
}
|
|
}
|