mirror of
https://codeberg.org/unspeaker/tek.git
synced 2026-10-08 18:56:42 +02:00
modularize sequencer
This commit is contained in:
parent
c4349dfb47
commit
3e3276bed0
12 changed files with 712 additions and 700 deletions
104
src/midi_play.rs
Normal file
104
src/midi_play.rs
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
use crate::*;
|
||||
|
||||
pub trait HasPlayClip: HasClock {
|
||||
fn reset (&self) -> bool;
|
||||
fn reset_mut (&mut self) -> &mut bool;
|
||||
fn play_clip (&self) -> &Option<(Moment, Option<Arc<RwLock<MidiClip>>>)>;
|
||||
fn play_clip_mut (&mut self) -> &mut Option<(Moment, Option<Arc<RwLock<MidiClip>>>)>;
|
||||
fn next_clip (&self) -> &Option<(Moment, Option<Arc<RwLock<MidiClip>>>)>;
|
||||
fn next_clip_mut (&mut self) -> &mut Option<(Moment, Option<Arc<RwLock<MidiClip>>>)>;
|
||||
|
||||
fn pulses_since_start (&self) -> Option<f64> {
|
||||
if let Some((started, Some(_))) = self.play_clip().as_ref() {
|
||||
let elapsed = self.clock().playhead.pulse.get() - started.pulse.get();
|
||||
return Some(elapsed)
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn pulses_since_start_looped (&self) -> Option<(f64, f64)> {
|
||||
if let Some((started, Some(clip))) = self.play_clip().as_ref() {
|
||||
let elapsed = self.clock().playhead.pulse.get() - started.pulse.get();
|
||||
let length = clip.try_read().unwrap().length.max(1); // prevent div0 on empty clip
|
||||
let times = (elapsed as usize / length) as f64;
|
||||
let elapsed = (elapsed as usize % length) as f64;
|
||||
return Some((times, elapsed))
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn enqueue_next (&mut self, clip: Option<&Arc<RwLock<MidiClip>>>) {
|
||||
*self.next_clip_mut() = Some((self.clock().next_launch_instant(), clip.cloned()));
|
||||
*self.reset_mut() = true;
|
||||
}
|
||||
|
||||
fn play_status (&self) -> impl Draw<Tui> {
|
||||
let (name, color): (Arc<str>, ItemTheme) = if let Some((_, Some(clip))) = self.play_clip() {
|
||||
let MidiClip { ref name, color, .. } = *clip.try_read().unwrap();
|
||||
(name.clone(), color)
|
||||
} else {
|
||||
("".into(), ItemTheme::G[64].into())
|
||||
};
|
||||
field_v(color, "Now:", format!("{} {}", self.play_status_time(), name))
|
||||
}
|
||||
|
||||
fn play_status_time (&self) -> String {
|
||||
self.pulses_since_start_looped()
|
||||
.map(|(times, time)|format!("{:>3}x {:>}", times+1.0, self.clock().timebase.format_beats_1(time)))
|
||||
.unwrap_or_else(||String::from(" "))
|
||||
.into()
|
||||
}
|
||||
|
||||
fn next_status (&self) -> impl Draw<Tui> {
|
||||
let mut time: Arc<str> = String::from("--.-.--").into();
|
||||
let mut name: Arc<str> = String::from("").into();
|
||||
let mut color = ItemTheme::G[64];
|
||||
let clock = self.clock();
|
||||
if let Some((t, Some(clip))) = self.next_clip() {
|
||||
let clip = clip.try_read().unwrap();
|
||||
name = clip.name.clone();
|
||||
color = clip.color.clone();
|
||||
time = {
|
||||
let target = t.pulse.get();
|
||||
let current = clock.playhead.pulse.get();
|
||||
if target > current {
|
||||
let remaining = target - current;
|
||||
format!("-{:>}", clock.timebase.format_beats_1(remaining))
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
}.into()
|
||||
} else if let Some((t, Some(clip))) = self.play_clip() {
|
||||
let clip = clip.try_read().unwrap();
|
||||
if clip.looped {
|
||||
name = clip.name.clone();
|
||||
color = clip.color.clone();
|
||||
let target = t.pulse.get() + clip.length as f64;
|
||||
let current = clock.playhead.pulse.get();
|
||||
if target > current {
|
||||
time = format!("-{:>}", clock.timebase.format_beats_0(target - current)).into()
|
||||
}
|
||||
} else {
|
||||
name = "Stop".to_string().into();
|
||||
}
|
||||
};
|
||||
field_v(color, "Next:", format!("{} {}", time, name))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature="clip")] impl HasPlayClip for Sequencer {
|
||||
fn reset (&self) -> bool { self.reset }
|
||||
fn reset_mut (&mut self) -> &mut bool { &mut self.reset }
|
||||
fn play_clip (&self) -> &Option<(Moment, Option<Arc<RwLock<MidiClip>>>)> {
|
||||
&self.play_clip
|
||||
}
|
||||
fn play_clip_mut (&mut self) -> &mut Option<(Moment, Option<Arc<RwLock<MidiClip>>>)> {
|
||||
&mut self.play_clip
|
||||
}
|
||||
fn next_clip (&self) -> &Option<(Moment, Option<Arc<RwLock<MidiClip>>>)> {
|
||||
&self.next_clip
|
||||
}
|
||||
fn next_clip_mut (&mut self) -> &mut Option<(Moment, Option<Arc<RwLock<MidiClip>>>)> {
|
||||
&mut self.next_clip
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue