//! MIDI sequencer use crate::*; impl> HasSequencer for T { fn sequencer (&self) -> &Sequencer { self.get() } fn sequencer_mut (&mut self) -> &mut Sequencer { self.get_mut() } } pub trait HasSequencer { fn sequencer (&self) -> &Sequencer; fn sequencer_mut (&mut self) -> &mut Sequencer; } /// Contains state for playing a clip pub struct Sequencer { /// State of clock and playhead pub clock: Clock, /// Start time and clip being played pub play_clip: Option<(Moment, Option>>)>, /// Start time and next clip pub next_clip: Option<(Moment, Option>>)>, /// Play input through output. pub monitoring: bool, /// Write input to sequence. pub recording: bool, /// Overdub input to sequence. pub overdub: bool, /// Send all notes off pub reset: bool, // TODO?: after Some(nframes) /// Record from MIDI ports to current sequence. pub midi_ins: Vec, /// Play from current sequence to MIDI ports pub midi_outs: Vec, /// Notes currently held at input pub notes_in: Arc>, /// Notes currently held at output pub notes_out: Arc>, /// MIDI output buffer pub note_buf: Vec, /// MIDI output buffer pub midi_buf: Vec>>, } impl Default for Sequencer { fn default () -> Self { Self { play_clip: None, next_clip: None, recording: false, monitoring: false, overdub: false, notes_in: RwLock::new([false;128]).into(), notes_out: RwLock::new([false;128]).into(), note_buf: vec![0;8], midi_buf: vec![], reset: true, midi_ins: vec![], midi_outs: vec![], clock: Clock::default(), } } } impl Sequencer { pub fn new ( name: impl AsRef, jack: &Jack, clock: Option<&Clock>, clip: Option<&Arc>>, midi_from: &[PortConnect], midi_to: &[PortConnect], ) -> Usually { let _name = name.as_ref(); let clock = clock.cloned().unwrap_or_default(); Ok(Self { midi_ins: vec![JackMidiIn::new(jack, format!("M/{}", name.as_ref()), midi_from)?,], midi_outs: vec![JackMidiOut::new(jack, format!("{}/M", name.as_ref()), midi_to)?, ], play_clip: clip.map(|clip|(Moment::zero(&clock.timebase), Some(clip.clone()))), clock, reset: true, notes_in: RwLock::new([false;128]).into(), notes_out: RwLock::new([false;128]).into(), ..Default::default() }) } } impl std::fmt::Debug for Sequencer { fn fmt (&self, f: &mut Formatter<'_>) -> std::result::Result<(), std::fmt::Error> { f.debug_struct("Sequencer") .field("clock", &self.clock) .field("play_clip", &self.play_clip) .field("next_clip", &self.next_clip) .finish() } } has!(Clock: |self: Sequencer|self.clock); has!(Vec: |self:Sequencer| self.midi_ins); has!(Vec: |self:Sequencer| self.midi_outs); impl MidiMonitor for Sequencer { fn notes_in (&self) -> &Arc> { &self.notes_in } fn monitoring (&self) -> bool { self.monitoring } fn monitoring_mut (&mut self) -> &mut bool { &mut self.monitoring } } impl MidiRecord for Sequencer { fn recording (&self) -> bool { self.recording } fn recording_mut (&mut self) -> &mut bool { &mut self.recording } fn overdub (&self) -> bool { self.overdub } fn overdub_mut (&mut self) -> &mut bool { &mut self.overdub } } 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>>)> { &self.play_clip } fn play_clip_mut (&mut self) -> &mut Option<(Moment, Option>>)> { &mut self.play_clip } fn next_clip (&self) -> &Option<(Moment, Option>>)> { &self.next_clip } fn next_clip_mut (&mut self) -> &mut Option<(Moment, Option>>)> { &mut self.next_clip } }