mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
207 lines
5.3 KiB
Rust
207 lines
5.3 KiB
Rust
use crate::*;
|
|
|
|
impl ClockApi for Clock {
|
|
fn quant (&self) -> &Quantize {
|
|
&self.quant
|
|
}
|
|
fn sync (&self) -> &LaunchSync {
|
|
&self.sync
|
|
}
|
|
fn current (&self) -> &Instant {
|
|
&self.current
|
|
}
|
|
}
|
|
|
|
impl PlayheadApi for Clock {}
|
|
|
|
impl HasJack for TransportModel {
|
|
fn jack (&self) -> &Arc<RwLock<JackClient>> {
|
|
&self.jack
|
|
}
|
|
}
|
|
|
|
impl HasClock for TransportModel {
|
|
fn clock (&self) -> &Arc<Clock> {
|
|
&self.clock
|
|
}
|
|
}
|
|
|
|
//impl TransportModelApi for TransportModel {
|
|
//fn transport (&self) -> &jack::Transport {
|
|
//&self.transport
|
|
//}
|
|
//fn metronome (&self) -> bool {
|
|
//self.metronome
|
|
//}
|
|
//}
|
|
|
|
impl Debug for TransportModel {
|
|
fn fmt (&self, f: &mut Formatter<'_>) -> std::result::Result<(), Error> {
|
|
f.debug_struct("transport")
|
|
.field("jack", &self.jack)
|
|
.field("transport", &"(JACK transport)")
|
|
.field("clock", &self.clock)
|
|
.field("metronome", &self.metronome)
|
|
.finish()
|
|
}
|
|
}
|
|
|
|
impl HasJack for ArrangerModel {
|
|
fn jack (&self) -> &Arc<RwLock<JackClient>> {
|
|
&self.transport.jack()
|
|
}
|
|
}
|
|
|
|
impl HasClock for ArrangerModel {
|
|
fn clock (&self) -> &Arc<Clock> {
|
|
&self.transport.clock()
|
|
}
|
|
}
|
|
|
|
//impl TransportModelApi for ArrangerModel {
|
|
//fn transport (&self) -> &jack::Transport {
|
|
//&self.transport.transport()
|
|
//}
|
|
//fn metronome (&self) -> bool {
|
|
//self.transport.metronome()
|
|
//}
|
|
//}
|
|
|
|
impl PhrasePoolModelApi for ArrangerModel {
|
|
fn phrases (&self) -> &Vec<Arc<RwLock<Phrase>>> {
|
|
&self.phrases
|
|
}
|
|
fn phrases_mut (&mut self) -> &mut Vec<Arc<RwLock<Phrase>>> {
|
|
&mut self.phrases
|
|
}
|
|
}
|
|
|
|
impl ArrangerApi for ArrangerModel {
|
|
fn name (&self) -> &Arc<RwLock<String>> {
|
|
&self.name
|
|
}
|
|
fn tracks (&self) -> &Vec<ArrangerTrack> {
|
|
&self.tracks
|
|
}
|
|
fn tracks_mut (&mut self) -> &mut Vec<ArrangerTrack> {
|
|
&mut self.tracks
|
|
}
|
|
fn scenes (&self) -> &Vec<ArrangerScene> {
|
|
&self.scenes
|
|
}
|
|
fn scenes_mut (&mut self) -> &mut Vec<ArrangerScene> {
|
|
&mut self.scenes
|
|
}
|
|
}
|
|
|
|
impl ArrangerScene {
|
|
|
|
//TODO
|
|
//pub fn from_edn <'a, 'e> (args: &[Edn<'e>]) -> Usually<Self> {
|
|
//let mut name = None;
|
|
//let mut clips = vec![];
|
|
//edn!(edn in args {
|
|
//Edn::Map(map) => {
|
|
//let key = map.get(&Edn::Key(":name"));
|
|
//if let Some(Edn::Str(n)) = key {
|
|
//name = Some(*n);
|
|
//} else {
|
|
//panic!("unexpected key in scene '{name:?}': {key:?}")
|
|
//}
|
|
//},
|
|
//Edn::Symbol("_") => {
|
|
//clips.push(None);
|
|
//},
|
|
//Edn::Int(i) => {
|
|
//clips.push(Some(*i as usize));
|
|
//},
|
|
//_ => panic!("unexpected in scene '{name:?}': {edn:?}")
|
|
//});
|
|
//Ok(ArrangerScene {
|
|
//name: Arc::new(name.unwrap_or("").to_string().into()),
|
|
//color: ItemColor::random(),
|
|
//clips,
|
|
//})
|
|
//}
|
|
}
|
|
|
|
impl HasJack for SequencerModel {
|
|
fn jack (&self) -> &Arc<RwLock<JackClient>> {
|
|
self.transport.jack()
|
|
}
|
|
}
|
|
|
|
impl HasClock for SequencerModel {
|
|
fn clock (&self) -> &Arc<Clock> {
|
|
self.transport.clock()
|
|
}
|
|
}
|
|
|
|
//impl TransportModelApi for SequencerModel {
|
|
//fn transport (&self) -> &jack::Transport {
|
|
//&self.transport.transport()
|
|
//}
|
|
//fn metronome (&self) -> bool {
|
|
//self.transport.metronome()
|
|
//}
|
|
//}
|
|
|
|
impl PhrasePoolModelApi for SequencerModel {
|
|
fn phrases (&self) -> &Vec<Arc<RwLock<Phrase>>> {
|
|
&self.phrases
|
|
}
|
|
fn phrases_mut (&mut self) -> &mut Vec<Arc<RwLock<Phrase>>> {
|
|
&mut self.phrases
|
|
}
|
|
}
|
|
|
|
impl HasPlayer for SequencerModel {
|
|
fn player (&self) -> &MIDIPlayer {
|
|
&self.player
|
|
}
|
|
fn player_mut (&mut self) -> &mut MIDIPlayer {
|
|
&mut self.player
|
|
}
|
|
}
|
|
|
|
impl From<Instant> for Clock {
|
|
fn from (current: Instant) -> Self {
|
|
Self {
|
|
playing: Some(TransportState::Stopped).into(),
|
|
started: None.into(),
|
|
quant: 24.into(),
|
|
sync: (current.timebase.ppq.get() * 4.).into(),
|
|
current,
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Methods used primarily by the process callback
|
|
impl MIDIPlayer {
|
|
pub fn new (
|
|
jack: &Arc<RwLock<JackClient>>,
|
|
clock: &Arc<Clock>,
|
|
name: &str
|
|
) -> Usually<Self> {
|
|
let jack = jack.read().unwrap();
|
|
Ok(Self {
|
|
clock: clock.clone(),
|
|
phrase: None,
|
|
next_phrase: None,
|
|
notes_in: Arc::new(RwLock::new([false;128])),
|
|
notes_out: Arc::new(RwLock::new([false;128])),
|
|
monitoring: false,
|
|
recording: false,
|
|
overdub: true,
|
|
reset: true,
|
|
midi_note: Vec::with_capacity(8),
|
|
midi_chunk: vec![Vec::with_capacity(16);16384],
|
|
midi_outputs: vec![
|
|
jack.client().register_port(format!("{name}_out0").as_str(), MidiOut::default())?
|
|
],
|
|
midi_inputs: vec![
|
|
jack.client().register_port(format!("{name}_in0").as_str(), MidiIn::default())?
|
|
],
|
|
})
|
|
}
|
|
}
|