wip: tying it together...

This commit is contained in:
🪞👃🪞 2024-11-01 02:15:51 +02:00
parent bbafb72e9b
commit ad2f75bee6
7 changed files with 76 additions and 115 deletions

View file

@ -117,31 +117,29 @@ pub struct PhraseEditor<E: Engine> {
/// Phrase player.
pub struct PhrasePlayer {
/// Global timebase
pub clock: Arc<TransportTime>,
pub clock: Arc<TransportTime>,
/// Start time and phrase being played
pub phrase: Option<(AtomicUsize, Option<Arc<RwLock<Phrase>>>)>,
/// Start time (FIXME move into phrase, using Instant)
pub started: Option<(usize, usize)>,
pub phrase: Option<(Instant, Option<Arc<RwLock<Phrase>>>)>,
/// Start time and next phrase
pub next_phrase: Option<(AtomicUsize, Option<Arc<RwLock<Phrase>>>)>,
pub next_phrase: Option<(Instant, Option<Arc<RwLock<Phrase>>>)>,
/// Play input through output.
pub monitoring: bool,
pub monitoring: bool,
/// Write input to sequence.
pub recording: bool,
pub recording: bool,
/// Overdub input to sequence.
pub overdub: bool,
pub overdub: bool,
/// Send all notes off
pub reset: bool, // TODO?: after Some(nframes)
pub reset: bool, // TODO?: after Some(nframes)
/// Record from MIDI ports to current sequence.
pub midi_inputs: Vec<Port<MidiIn>>,
pub midi_inputs: Vec<Port<MidiIn>>,
/// Play from current sequence to MIDI ports
pub midi_outputs: Vec<Port<MidiOut>>,
pub midi_outputs: Vec<Port<MidiOut>>,
/// MIDI output buffer
pub midi_out_buf: Vec<Vec<Vec<u8>>>,
pub midi_out_buf: Vec<Vec<Vec<u8>>>,
/// Notes currently held at input
pub notes_in: Arc<RwLock<[bool; 128]>>,
pub notes_in: Arc<RwLock<[bool; 128]>>,
/// Notes currently held at output
pub notes_out: Arc<RwLock<[bool; 128]>>,
pub notes_out: Arc<RwLock<[bool; 128]>>,
}
/// Focus layout of sequencer app
impl<E: Engine> FocusGrid<SequencerFocus> for Sequencer<E> {
@ -377,7 +375,6 @@ impl PhrasePlayer {
Self {
clock: clock.clone(),
phrase: None,
started: None,
next_phrase: None,
notes_in: Arc::new(RwLock::new([false;128])),
notes_out: Arc::new(RwLock::new([false;128])),
@ -395,21 +392,22 @@ impl PhrasePlayer {
pub fn toggle_overdub (&mut self) { self.overdub = !self.overdub; }
pub fn enqueue_next (&mut self, phrase: Option<&Arc<RwLock<Phrase>>>) {
let start = self.clock.next_launch_pulse();
self.next_phrase = Some((start.into(), phrase.map(|p|p.clone())));
self.next_phrase = Some((
Instant::from_pulse(&self.clock.timebase, start as f64),
phrase.map(|p|p.clone())
));
self.reset = true;
}
pub fn frames_since_start (&self) -> Option<usize> {
pub fn samples_since_start (&self) -> Option<usize> {
self.phrase.as_ref()
.map(|(started,_)|started.load(Ordering::Relaxed))
.map(|(started,_)|started.sample())
.map(|started|started - self.clock.sample())
}
pub fn playing_phrase (&self) -> Option<(usize, Arc<RwLock<Phrase>>)> {
if let (
Some(TransportState::Rolling),
Some((start_frame, _)),
Some((_started, Some(ref phrase)))
) = (*self.clock.playing.read().unwrap(), self.started, &self.phrase) {
Some((start_frame, phrase.clone()))
Some(TransportState::Rolling), Some((started, Some(ref phrase)))
) = (*self.clock.playing.read().unwrap(), &self.phrase) {
Some((started.sample(), phrase.clone()))
} else {
None
}