pub(crate) use tek_core::*; pub(crate) use tek_core::crossterm::event::{KeyCode, KeyModifiers}; pub(crate) use tek_jack::{*, jack::*}; pub(crate) use std::sync::{Arc, atomic::Ordering}; pub(crate) use atomic_float::AtomicF64; submod! { timebase ticks transport transport_focus transport_handle transport_render } /// (pulses, name) pub const NOTE_DURATIONS: [(usize, &str);26] = [ (1, "1/384"), (2, "1/192"), (3, "1/128"), (4, "1/96"), (6, "1/64"), (8, "1/48"), (12, "1/32"), (16, "1/24"), (24, "1/16"), (32, "1/12"), (48, "1/8"), (64, "1/6"), (96, "1/4"), (128, "1/3"), (192, "1/2"), (256, "2/3"), (384, "1/1"), (512, "4/3"), (576, "3/2"), (768, "2/1"), (1152, "3/1"), (1536, "4/1"), (2304, "6/1"), (3072, "8/1"), (3456, "9/1"), (6144, "16/1"), ]; /// Returns the next shorter length pub fn prev_note_length (ppq: usize) -> usize { for i in 1..=16 { let length = NOTE_DURATIONS[16-i].0; if length < ppq { return length } } ppq } /// Returns the next longer length pub fn next_note_length (ppq: usize) -> usize { for (length, _) in &NOTE_DURATIONS { if *length > ppq { return *length } } ppq } pub fn ppq_to_name (ppq: usize) -> &'static str { for (length, name) in &NOTE_DURATIONS { if *length == ppq { return name } } "" }