mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-09 05:06:43 +01:00
wip(108e): layout refactor
This commit is contained in:
parent
265d4a3953
commit
ddb3c28c01
21 changed files with 1141 additions and 825 deletions
|
|
@ -33,18 +33,35 @@ impl<T: HasClock> Command<T> for ClockCommand {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Timeline {
|
||||
pub timebase: Arc<Timebase>,
|
||||
pub started: Arc<RwLock<Option<Moment>>>,
|
||||
pub loopback: Arc<RwLock<Option<Moment>>>,
|
||||
}
|
||||
|
||||
impl Default for Timeline {
|
||||
fn default () -> Self {
|
||||
Self {
|
||||
timebase: Arc::new(Timebase::default()),
|
||||
started: RwLock::new(None).into(),
|
||||
loopback: RwLock::new(None).into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ClockModel {
|
||||
/// JACK transport handle.
|
||||
pub transport: Arc<Transport>,
|
||||
/// Global temporal resolution (shared by [Instant] fields)
|
||||
/// Global temporal resolution (shared by [Moment] fields)
|
||||
pub timebase: Arc<Timebase>,
|
||||
/// Current global sample and usec (monotonic from JACK clock)
|
||||
pub global: Arc<Instant>,
|
||||
pub global: Arc<Moment>,
|
||||
/// Global sample and usec at which playback started
|
||||
pub started: Arc<RwLock<Option<Instant>>>,
|
||||
pub started: Arc<RwLock<Option<Moment>>>,
|
||||
/// Current playhead position
|
||||
pub playhead: Arc<Instant>,
|
||||
pub playhead: Arc<Moment>,
|
||||
/// Note quantization factor
|
||||
pub quant: Arc<Quantize>,
|
||||
/// Launch quantization factor
|
||||
|
|
@ -64,8 +81,8 @@ impl From<&Arc<RwLock<JackClient>>> for ClockModel {
|
|||
sync: Arc::new(384.into()),
|
||||
transport: Arc::new(transport),
|
||||
chunk: Arc::new((chunk as usize).into()),
|
||||
global: Arc::new(Instant::zero(&timebase)),
|
||||
playhead: Arc::new(Instant::zero(&timebase)),
|
||||
global: Arc::new(Moment::zero(&timebase)),
|
||||
playhead: Arc::new(Moment::zero(&timebase)),
|
||||
started: RwLock::new(None).into(),
|
||||
timebase,
|
||||
}
|
||||
|
|
@ -147,7 +164,7 @@ impl ClockModel {
|
|||
match self.transport.query_state()? {
|
||||
TransportState::Rolling => {
|
||||
if started.is_none() {
|
||||
*started = Some(Instant::from_sample(&self.timebase, current_frames as f64));
|
||||
*started = Some(Moment::from_sample(&self.timebase, current_frames as f64));
|
||||
}
|
||||
},
|
||||
TransportState::Stopped => {
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@ pub trait MidiPlayerApi: MidiRecordApi + MidiPlaybackApi + Send + Sync {}
|
|||
pub trait HasPlayPhrase: HasClock {
|
||||
fn reset (&self) -> bool;
|
||||
fn reset_mut (&mut self) -> &mut bool;
|
||||
fn play_phrase (&self) -> &Option<(Instant, Option<Arc<RwLock<Phrase>>>)>;
|
||||
fn play_phrase_mut (&mut self) -> &mut Option<(Instant, Option<Arc<RwLock<Phrase>>>)>;
|
||||
fn next_phrase (&self) -> &Option<(Instant, Option<Arc<RwLock<Phrase>>>)>;
|
||||
fn next_phrase_mut (&mut self) -> &mut Option<(Instant, Option<Arc<RwLock<Phrase>>>)>;
|
||||
fn play_phrase (&self) -> &Option<(Moment, Option<Arc<RwLock<Phrase>>>)>;
|
||||
fn play_phrase_mut (&mut self) -> &mut Option<(Moment, Option<Arc<RwLock<Phrase>>>)>;
|
||||
fn next_phrase (&self) -> &Option<(Moment, Option<Arc<RwLock<Phrase>>>)>;
|
||||
fn next_phrase_mut (&mut self) -> &mut Option<(Moment, Option<Arc<RwLock<Phrase>>>)>;
|
||||
fn pulses_since_start (&self) -> Option<f64> {
|
||||
if let Some((started, Some(_))) = self.play_phrase().as_ref() {
|
||||
Some(self.clock().playhead.pulse.get() - started.pulse.get())
|
||||
|
|
@ -23,7 +23,7 @@ pub trait HasPlayPhrase: HasClock {
|
|||
}
|
||||
fn enqueue_next (&mut self, phrase: Option<&Arc<RwLock<Phrase>>>) {
|
||||
let start = self.clock().next_launch_pulse() as f64;
|
||||
let instant = Instant::from_pulse(&self.clock().timebase(), start);
|
||||
let instant = Moment::from_pulse(&self.clock().timebase(), start);
|
||||
let phrase = phrase.map(|p|p.clone());
|
||||
*self.next_phrase_mut() = Some((instant, phrase));
|
||||
*self.reset_mut() = true;
|
||||
|
|
@ -206,7 +206,7 @@ pub trait MidiPlaybackApi: HasPlayPhrase + HasClock + HasMidiOuts {
|
|||
// Samples elapsed since phrase was supposed to start
|
||||
let skipped = sample0 - start;
|
||||
// Switch over to enqueued phrase
|
||||
let started = Instant::from_sample(&self.clock().timebase(), start as f64);
|
||||
let started = Moment::from_sample(&self.clock().timebase(), start as f64);
|
||||
*self.play_phrase_mut() = Some((started, phrase.clone()));
|
||||
// Unset enqueuement (TODO: where to implement looping?)
|
||||
*self.next_phrase_mut() = None
|
||||
|
|
@ -306,9 +306,9 @@ impl<'a, T: MidiPlayerApi> Audio for PlayerAudio<'a, T> {
|
|||
///// Global timebase
|
||||
//pub clock: Arc<Clock>,
|
||||
///// Start time and phrase being played
|
||||
//pub play_phrase: Option<(Instant, Option<Arc<RwLock<Phrase>>>)>,
|
||||
//pub play_phrase: Option<(Moment, Option<Arc<RwLock<Phrase>>>)>,
|
||||
///// Start time and next phrase
|
||||
//pub next_phrase: Option<(Instant, Option<Arc<RwLock<Phrase>>>)>,
|
||||
//pub next_phrase: Option<(Moment, Option<Arc<RwLock<Phrase>>>)>,
|
||||
///// Play input through output.
|
||||
//pub monitoring: bool,
|
||||
///// Write input to sequence.
|
||||
|
|
|
|||
0
crates/tek_api/src/api_timeline.ts
Normal file
0
crates/tek_api/src/api_timeline.ts
Normal file
|
|
@ -455,8 +455,8 @@ fn query_ports(client: &Client, names: Vec<String>) -> BTreeMap<String, Port<Uno
|
|||
//}
|
||||
//}
|
||||
|
||||
//impl From<Instant> for Clock {
|
||||
//fn from (current: Instant) -> Self {
|
||||
//impl From<Moment> for Clock {
|
||||
//fn from (current: Moment) -> Self {
|
||||
//Self {
|
||||
//playing: Some(TransportState::Stopped).into(),
|
||||
//started: None.into(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue