wip: enqueue synced (!!!)

This commit is contained in:
🪞👃🪞 2024-10-26 19:12:26 +03:00
parent 2d1c901b8c
commit 89dcc2afe2
5 changed files with 26 additions and 15 deletions

View file

@ -106,6 +106,9 @@ pub trait UsecPosition<T> {
pub trait LaunchSync<T> {
fn sync (&self) -> T;
fn set_sync (&self, sync: T);
#[inline] fn next_launch (&self) -> T where Self: FramePosition<T> {
todo!("next_launch")
}
}
pub trait Quantize<T> {

View file

@ -123,7 +123,7 @@ impl<E: Engine> Arranger<E> {
let mut app = Self {
focus_cursor: (0, 1),
phrases_split: 20,
arrangement_split: 20,
arrangement_split: 21,
editor: PhraseEditor::new(),
status: ArrangerStatusBar::ArrangementClip,
clock: if let Some(ref transport) = transport {
@ -237,13 +237,13 @@ impl<E: Engine> Arrangement<E> {
match self.selected {
ArrangementFocus::Scene(s) => {
for (t, track) in self.tracks.iter_mut().enumerate() {
track.player.phrase = self.scenes[s].clips[t].clone();
track.player.reset = true;
let start = self.clock.next_launch();
track.player.enqueue_next(start, self.scenes[s].clips[t].as_ref());
}
},
ArrangementFocus::Clip(t, s) => {
self.tracks[t].player.phrase = self.scenes[s].clips[t].clone();
self.tracks[t].player.reset = true;
let start = self.clock.next_launch();
self.tracks[t].player.enqueue_next(start, self.scenes[s].clips[t].as_ref());
},
_ => {}
}
@ -689,7 +689,7 @@ impl Scene {
.all(|(track_index, clip)|match clip {
Some(clip) => tracks
.get(track_index)
.map(|track|if let Some(phrase) = &track.player.phrase {
.map(|track|if let Some((_, Some(phrase))) = &track.player.phrase {
*phrase.read().unwrap() == *clip.read().unwrap()
} else {
false

View file

@ -169,7 +169,9 @@ impl<'a> Content for VerticalArranger<'a, Tui> {
let max_w = w.saturating_sub(1).min(name.len()).max(2);
let name = format!("{}", &name[0..max_w]);
let time1 = track.player.phrase.as_ref()
.map(|_|format!("{:>}", track.player.now.load(Ordering::Relaxed)))
.map(|_|track.player.frames_since_start())
.flatten()
.map(|t|format!("{t:>}"))
.unwrap_or(String::from(""));
let time2 = track.player.switch_at.as_ref()
.map(|t|format!("{:>}", t.load(Ordering::Relaxed)))

View file

@ -115,12 +115,10 @@ pub struct PhrasePlayer<E: Engine> {
_engine: PhantomData<E>,
/// Global timebase
pub clock: Arc<TransportTime>,
/// Phrase being played
pub phrase: Option<Arc<RwLock<Phrase>>>,
/// Next phrase
pub next_phrase: Option<Arc<RwLock<Phrase>>>,
/// Current point in playing phrase
pub now: Arc<AtomicUsize>,
/// Start time and phrase being played
pub phrase: Option<(AtomicUsize, Option<Arc<RwLock<Phrase>>>)>,
/// Start time and next phrase
pub next_phrase: Option<(AtomicUsize, Option<Arc<RwLock<Phrase>>>)>,
/// Frames remaining until switch to next phrase
pub switch_at: Option<AtomicUsize>,
/// Play input through output.
@ -336,7 +334,6 @@ impl<E: Engine> PhrasePlayer<E> {
clock: clock.clone(),
phrase: None,
next_phrase: None,
now: Arc::new(0.into()),
switch_at: None,
notes_in: Arc::new(RwLock::new([false;128])),
notes_out: Arc::new(RwLock::new([false;128])),
@ -351,6 +348,15 @@ impl<E: Engine> PhrasePlayer<E> {
pub fn toggle_monitor (&mut self) { self.monitoring = !self.monitoring; }
pub fn toggle_record (&mut self) { self.recording = !self.recording; }
pub fn toggle_overdub (&mut self) { self.overdub = !self.overdub; }
pub fn enqueue_next (&mut self, start_at: usize, phrase: Option<&Arc<RwLock<Phrase>>>) {
self.next_phrase = Some((start_at.into(), phrase.map(|p|p.clone())));
self.reset = true;
}
pub fn frames_since_start (&self) -> Option<usize> {
self.phrase.as_ref()
.map(|(started,_)|started.load(Ordering::Relaxed))
.map(|started|started - self.clock.frame())
}
}
/// Displays and edits phrase length
pub struct PhraseLength<E: Engine> {

View file

@ -58,7 +58,7 @@ impl<E: Engine> PhrasePlayer<E> {
if let (
Some(TransportState::Rolling),
Some((start_frame, _)),
Some(ref phrase)
Some((_started, Some(ref phrase)))
) = (playing, started, &self.phrase) {
phrase.read().map(|phrase|{
if self.midi_out.is_some() {