use crate::core::*; use crate::model::*; pub struct Track { pub name: String, /// Play input through output. pub monitoring: bool, /// Write input to sequence. pub recording: bool, /// Overdub input to sequence. pub overdub: bool, /// Map: tick -> MIDI events at tick pub phrases: Vec, /// Phrase selector pub sequence: Option, /// Output from current sequence. pub midi_out: Port, /// Red keys on piano roll. pub notes_on: Vec, /// Device chain pub devices: Vec>>>, /// Device selector pub device: usize, } impl Track { pub fn new ( name: &str, jack: &Client, phrases: Option>, devices: Option>>>>, ) -> Usually { Ok(Self { name: name.to_string(), midi_out: jack.register_port(name, MidiOut)?, notes_on: vec![], monitoring: false, recording: false, overdub: true, sequence: None, phrases: phrases.unwrap_or_else(||vec![]), devices: devices.unwrap_or_else(||vec![]), device: 0, }) } pub fn device (&self, i: usize) -> Option>> { self.devices.get(i).map(|d|d.lock().unwrap()) } pub fn active_device (&self) -> Option>> { self.device(self.device) } pub fn first_device (&self) -> Option>> { self.device(0) } pub fn last_device (&self) -> Option>> { self.device(self.devices.len().saturating_sub(1)) } pub fn phrase (&self) -> Option<&Phrase> { if let Some(phrase) = self.sequence { return self.phrases.get(phrase) } else { None } } pub fn phrase_mut (&mut self) -> Option<&mut Phrase> { if let Some(phrase) = self.sequence { return self.phrases.get_mut(phrase) } else { None } } } ports!(Track { audio: { outs: |track|{ if let Some(device) = track.last_device() { device.audio_outs() } else { Ok(vec![]) } }, } midi: { ins: |track|if let Some(device) = track.first_device() { device.midi_ins() } else { Ok(vec![]) }, outs: |track|Ok(vec![ &track.midi_out ]), } });