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> { pub trait LaunchSync<T> {
fn sync (&self) -> T; fn sync (&self) -> T;
fn set_sync (&self, sync: T); fn set_sync (&self, sync: T);
#[inline] fn next_launch (&self) -> T where Self: FramePosition<T> {
todo!("next_launch")
}
} }
pub trait Quantize<T> { pub trait Quantize<T> {

View file

@ -123,7 +123,7 @@ impl<E: Engine> Arranger<E> {
let mut app = Self { let mut app = Self {
focus_cursor: (0, 1), focus_cursor: (0, 1),
phrases_split: 20, phrases_split: 20,
arrangement_split: 20, arrangement_split: 21,
editor: PhraseEditor::new(), editor: PhraseEditor::new(),
status: ArrangerStatusBar::ArrangementClip, status: ArrangerStatusBar::ArrangementClip,
clock: if let Some(ref transport) = transport { clock: if let Some(ref transport) = transport {
@ -237,13 +237,13 @@ impl<E: Engine> Arrangement<E> {
match self.selected { match self.selected {
ArrangementFocus::Scene(s) => { ArrangementFocus::Scene(s) => {
for (t, track) in self.tracks.iter_mut().enumerate() { for (t, track) in self.tracks.iter_mut().enumerate() {
track.player.phrase = self.scenes[s].clips[t].clone(); let start = self.clock.next_launch();
track.player.reset = true; track.player.enqueue_next(start, self.scenes[s].clips[t].as_ref());
} }
}, },
ArrangementFocus::Clip(t, s) => { ArrangementFocus::Clip(t, s) => {
self.tracks[t].player.phrase = self.scenes[s].clips[t].clone(); let start = self.clock.next_launch();
self.tracks[t].player.reset = true; 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 { .all(|(track_index, clip)|match clip {
Some(clip) => tracks Some(clip) => tracks
.get(track_index) .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() *phrase.read().unwrap() == *clip.read().unwrap()
} else { } else {
false 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 max_w = w.saturating_sub(1).min(name.len()).max(2);
let name = format!("{}", &name[0..max_w]); let name = format!("{}", &name[0..max_w]);
let time1 = track.player.phrase.as_ref() 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("")); .unwrap_or(String::from(""));
let time2 = track.player.switch_at.as_ref() let time2 = track.player.switch_at.as_ref()
.map(|t|format!("{:>}", t.load(Ordering::Relaxed))) .map(|t|format!("{:>}", t.load(Ordering::Relaxed)))

View file

@ -115,12 +115,10 @@ pub struct PhrasePlayer<E: Engine> {
_engine: PhantomData<E>, _engine: PhantomData<E>,
/// Global timebase /// Global timebase
pub clock: Arc<TransportTime>, pub clock: Arc<TransportTime>,
/// Phrase being played /// Start time and phrase being played
pub phrase: Option<Arc<RwLock<Phrase>>>, pub phrase: Option<(AtomicUsize, Option<Arc<RwLock<Phrase>>>)>,
/// Next phrase /// Start time and next phrase
pub next_phrase: Option<Arc<RwLock<Phrase>>>, pub next_phrase: Option<(AtomicUsize, Option<Arc<RwLock<Phrase>>>)>,
/// Current point in playing phrase
pub now: Arc<AtomicUsize>,
/// Frames remaining until switch to next phrase /// Frames remaining until switch to next phrase
pub switch_at: Option<AtomicUsize>, pub switch_at: Option<AtomicUsize>,
/// Play input through output. /// Play input through output.
@ -336,7 +334,6 @@ impl<E: Engine> PhrasePlayer<E> {
clock: clock.clone(), clock: clock.clone(),
phrase: None, phrase: None,
next_phrase: None, next_phrase: None,
now: Arc::new(0.into()),
switch_at: None, switch_at: None,
notes_in: Arc::new(RwLock::new([false;128])), notes_in: Arc::new(RwLock::new([false;128])),
notes_out: 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_monitor (&mut self) { self.monitoring = !self.monitoring; }
pub fn toggle_record (&mut self) { self.recording = !self.recording; } pub fn toggle_record (&mut self) { self.recording = !self.recording; }
pub fn toggle_overdub (&mut self) { self.overdub = !self.overdub; } 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 /// Displays and edits phrase length
pub struct PhraseLength<E: Engine> { pub struct PhraseLength<E: Engine> {

View file

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