mirror of
https://codeberg.org/unspeaker/tek.git
synced 2026-04-03 21:00:44 +02:00
wip: nromalize
This commit is contained in:
parent
7ff1d989a9
commit
513b8354a3
14 changed files with 2324 additions and 2337 deletions
168
app/tick.rs
Normal file
168
app/tick.rs
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
pub trait HasClock: AsRef<Clock> + AsMut<Clock> {
|
||||
fn clock (&self) -> &Clock { self.as_ref() }
|
||||
fn clock_mut (&mut self) -> &mut Clock { self.as_mut() }
|
||||
}
|
||||
|
||||
|
||||
/// Temporal resolutions: sample rate, tempo, MIDI pulses per quaver (beat)
|
||||
///
|
||||
/// ```
|
||||
/// let _ = tek::Timebase::default();
|
||||
/// ```
|
||||
#[derive(Debug, Clone)] pub struct Timebase {
|
||||
/// Audio samples per second
|
||||
pub sr: SampleRate,
|
||||
/// MIDI beats per minute
|
||||
pub bpm: Bpm,
|
||||
/// MIDI ticks per beat
|
||||
pub ppq: Ppq,
|
||||
}
|
||||
|
||||
/// Iterator that emits subsequent ticks within a range.
|
||||
///
|
||||
/// ```
|
||||
/// let iter = tek::Ticker::default();
|
||||
/// ```
|
||||
#[derive(Debug, Default)] pub struct Ticker {
|
||||
pub spp: f64,
|
||||
pub sample: usize,
|
||||
pub start: usize,
|
||||
pub end: usize,
|
||||
}
|
||||
|
||||
/// A point in time in all time scales (microsecond, sample, MIDI pulse)
|
||||
///
|
||||
/// ```
|
||||
/// let _ = tek::Moment::default();
|
||||
/// ```
|
||||
#[derive(Debug, Default, Clone)] pub struct Moment {
|
||||
pub timebase: Arc<Timebase>,
|
||||
/// Current time in microseconds
|
||||
pub usec: Microsecond,
|
||||
/// Current time in audio samples
|
||||
pub sample: SampleCount,
|
||||
/// Current time in MIDI pulses
|
||||
pub pulse: Pulse,
|
||||
}
|
||||
|
||||
///
|
||||
/// ```
|
||||
/// let _ = tek::Moment2::default();
|
||||
/// ```
|
||||
#[derive(Debug, Clone, Default)] pub enum Moment2 {
|
||||
#[default] None,
|
||||
Zero,
|
||||
Usec(Microsecond),
|
||||
Sample(SampleCount),
|
||||
Pulse(Pulse),
|
||||
}
|
||||
|
||||
/// MIDI resolution in PPQ (pulses per quarter note)
|
||||
///
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
#[derive(Debug, Default)] pub struct Ppq (pub(crate) AtomicF64);
|
||||
|
||||
/// Timestamp in MIDI pulses
|
||||
///
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
#[derive(Debug, Default)] pub struct Pulse (pub(crate) AtomicF64);
|
||||
|
||||
/// Tempo in beats per minute
|
||||
///
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
#[derive(Debug, Default)] pub struct Bpm (pub(crate) AtomicF64);
|
||||
|
||||
/// Quantization setting for launching clips
|
||||
///
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
#[derive(Debug, Default)] pub struct LaunchSync (pub(crate) AtomicF64);
|
||||
|
||||
/// Quantization setting for notes
|
||||
///
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
#[derive(Debug, Default)] pub struct Quantize (pub(crate) AtomicF64);
|
||||
|
||||
/// Timestamp in audio samples
|
||||
///
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
#[derive(Debug, Default)] pub struct SampleCount (pub(crate) AtomicF64);
|
||||
|
||||
/// Audio sample rate in Hz (samples per second)
|
||||
///
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
#[derive(Debug, Default)] pub struct SampleRate (pub(crate) AtomicF64);
|
||||
|
||||
/// Timestamp in microseconds
|
||||
///
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
#[derive(Debug, Default)] pub struct Microsecond (pub(crate) AtomicF64);
|
||||
|
||||
/// The source of time.
|
||||
///
|
||||
/// ```
|
||||
/// let clock = tek::Clock::default();
|
||||
/// ```
|
||||
#[derive(Clone, Default)] pub struct Clock {
|
||||
/// JACK transport handle.
|
||||
pub transport: Arc<Option<Transport>>,
|
||||
/// Global temporal resolution (shared by [Moment] fields)
|
||||
pub timebase: Arc<Timebase>,
|
||||
/// Current global sample and usec (monotonic from JACK clock)
|
||||
pub global: Arc<Moment>,
|
||||
/// Global sample and usec at which playback started
|
||||
pub started: Arc<RwLock<Option<Moment>>>,
|
||||
/// Playback offset (when playing not from start)
|
||||
pub offset: Arc<Moment>,
|
||||
/// Current playhead position
|
||||
pub playhead: Arc<Moment>,
|
||||
/// Note quantization factor
|
||||
pub quant: Arc<Quantize>,
|
||||
/// Launch quantization factor
|
||||
pub sync: Arc<LaunchSync>,
|
||||
/// Size of buffer in samples
|
||||
pub chunk: Arc<AtomicUsize>,
|
||||
// Cache of formatted strings
|
||||
pub view_cache: Arc<RwLock<ClockView>>,
|
||||
/// For syncing the clock to an external source
|
||||
#[cfg(feature = "port")] pub midi_in: Arc<RwLock<Option<MidiInput>>>,
|
||||
/// For syncing other devices to this clock
|
||||
#[cfg(feature = "port")] pub midi_out: Arc<RwLock<Option<MidiOutput>>>,
|
||||
/// For emitting a metronome
|
||||
#[cfg(feature = "port")] pub click_out: Arc<RwLock<Option<AudioOutput>>>,
|
||||
}
|
||||
|
||||
/// A unit of time, represented as an atomic 64-bit float.
|
||||
///
|
||||
/// According to https://stackoverflow.com/a/873367, as per IEEE754,
|
||||
/// every integer between 1 and 2^53 can be represented exactly.
|
||||
/// This should mean that, even at 192kHz sampling rate, over 1 year of audio
|
||||
/// can be clocked in microseconds with f64 without losing precision.
|
||||
pub trait TimeUnit: InteriorMutable<f64> {}
|
||||
|
||||
/// Contains memoized renders of clock values.
|
||||
///
|
||||
/// Performance optimization.
|
||||
#[derive(Debug)] pub struct ClockView {
|
||||
pub sr: Memo<Option<(bool, f64)>, String>,
|
||||
pub buf: Memo<Option<f64>, String>,
|
||||
pub lat: Memo<Option<f64>, String>,
|
||||
pub bpm: Memo<Option<f64>, String>,
|
||||
pub beat: Memo<Option<f64>, String>,
|
||||
pub time: Memo<Option<f64>, String>,
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue