mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
200 lines
6.7 KiB
Rust
200 lines
6.7 KiB
Rust
use crate::*;
|
|
|
|
macro_rules! impl_jack_api {
|
|
($Struct:ident $(:: $field:ident)*) => {
|
|
impl JackApi for $Struct {
|
|
fn jack (&self) -> &Arc<RwLock<JackClient>> {
|
|
&self$(.$field)*
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
macro_rules! impl_clock_api {
|
|
($Struct:ident $(:: $field:ident)*) => {
|
|
impl ClockApi for $Struct {
|
|
fn quant (&self) -> &Arc<Quantize> {
|
|
&self$(.$field)*.quant
|
|
}
|
|
fn sync (&self) -> &Arc<LaunchSync> {
|
|
&self$(.$field)*.sync
|
|
}
|
|
fn current (&self) -> &Arc<Instant> {
|
|
&self$(.$field)*.current
|
|
}
|
|
fn transport_handle (&self) -> &Arc<Transport> {
|
|
&self$(.$field)*.transport
|
|
}
|
|
fn transport_state (&self) -> &Arc<RwLock<Option<TransportState>>> {
|
|
&self$(.$field)*.playing
|
|
}
|
|
fn transport_offset (&self) -> &Arc<RwLock<Option<(usize, usize)>>> {
|
|
&self$(.$field)*.started
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
macro_rules! impl_has_phrases {
|
|
($Struct:ident $(:: $field:ident)*) => {
|
|
impl HasPhrases for $Struct {
|
|
fn phrases (&self) -> &Vec<Arc<RwLock<Phrase>>> {
|
|
&self$(.$field)*.phrases
|
|
}
|
|
fn phrases_mut (&mut self) -> &mut Vec<Arc<RwLock<Phrase>>> {
|
|
&mut self$(.$field)*.phrases
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
macro_rules! impl_midi_player {
|
|
($Struct:ident $(:: $field:ident)*) => {
|
|
impl HasPhrase for $Struct {
|
|
fn reset (&self) -> bool {
|
|
self$(.$field)*.reset
|
|
}
|
|
fn reset_mut (&mut self) -> &mut bool {
|
|
&mut self$(.$field)*.reset
|
|
}
|
|
fn phrase (&self) -> &Option<(Instant, Option<Arc<RwLock<Phrase>>>)> {
|
|
&self$(.$field)*.play_phrase
|
|
}
|
|
fn phrase_mut (&mut self) -> &mut Option<(Instant, Option<Arc<RwLock<Phrase>>>)> {
|
|
&mut self$(.$field)*.play_phrase
|
|
}
|
|
fn next_phrase (&self) -> &Option<(Instant, Option<Arc<RwLock<Phrase>>>)> {
|
|
&self$(.$field)*.next_phrase
|
|
}
|
|
fn next_phrase_mut (&mut self) -> &mut Option<(Instant, Option<Arc<RwLock<Phrase>>>)> {
|
|
&mut self$(.$field)*.next_phrase
|
|
}
|
|
}
|
|
impl MidiInputApi for $Struct {
|
|
fn midi_ins (&self) -> &Vec<Port<jack::MidiIn>> {
|
|
&self$(.$field)*.midi_ins
|
|
}
|
|
fn midi_ins_mut (&mut self) -> &mut Vec<Port<jack::MidiIn>> {
|
|
&mut self$(.$field)*.midi_ins
|
|
}
|
|
fn recording (&self) -> bool {
|
|
self$(.$field)*.recording
|
|
}
|
|
fn recording_mut (&mut self) -> &mut bool {
|
|
&mut self$(.$field)*.recording
|
|
}
|
|
fn monitoring (&self) -> bool {
|
|
self$(.$field)*.monitoring
|
|
}
|
|
fn monitoring_mut (&mut self) -> &mut bool {
|
|
&mut self$(.$field)*.monitoring
|
|
}
|
|
fn overdub (&self) -> bool {
|
|
self$(.$field)*.overdub
|
|
}
|
|
fn overdub_mut (&mut self) -> &mut bool {
|
|
&mut self$(.$field)*.overdub
|
|
}
|
|
fn notes_in (&self) -> &Arc<RwLock<[bool; 128]>> {
|
|
&self$(.$field)*.notes_in
|
|
}
|
|
}
|
|
impl MidiOutputApi for $Struct {
|
|
fn midi_outs (&self) -> &Vec<Port<jack::MidiOut>> {
|
|
&self$(.$field)*.midi_outs
|
|
}
|
|
fn midi_outs_mut (&mut self) -> &mut Vec<Port<jack::MidiOut>> {
|
|
&mut self$(.$field)*.midi_outs
|
|
}
|
|
fn midi_note (&mut self) -> &mut Vec<u8> {
|
|
&mut self$(.$field)*.note_buf
|
|
}
|
|
fn notes_out (&self) -> &Arc<RwLock<[bool; 128]>> {
|
|
&self$(.$field)*.notes_in
|
|
}
|
|
}
|
|
impl MidiPlayerApi for $Struct {}
|
|
}
|
|
}
|
|
|
|
macro_rules! impl_phrases_control {
|
|
($Struct:ident $(:: $field:ident)*) => {
|
|
impl PhrasesControl for $Struct {
|
|
fn phrase_index (&self) -> usize {
|
|
self.phrases.phrase.load(Ordering::Relaxed)
|
|
}
|
|
fn set_phrase_index (&self, value: usize) {
|
|
self.phrases.phrase.store(value, Ordering::Relaxed);
|
|
}
|
|
fn phrases_mode (&self) -> &Option<PhrasesMode> {
|
|
&self.phrases.mode
|
|
}
|
|
fn phrases_mode_mut (&mut self) -> &mut Option<PhrasesMode> {
|
|
&mut self.phrases.mode
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
macro_rules! impl_phrase_editor_control {
|
|
($Struct:ident $(:: $field:ident)* [$Focus:expr]) => {
|
|
impl PhraseEditorControl for $Struct {
|
|
fn edit_phrase (&self, phrase: &Option<Arc<RwLock<Phrase>>>) {
|
|
//self.editor.show(self.selected_phrase().as_ref());
|
|
//state.editor.phrase = phrase.clone();
|
|
//state.focus(ArrangerFocus::PhraseEditor);
|
|
//state.focus_enter();
|
|
todo!("edit_phrase")
|
|
}
|
|
fn editing_phrase (&self) -> &Option<Arc<RwLock<Phrase>>> {
|
|
todo!("editing_phrase")
|
|
}
|
|
fn phrase_editor_entered (&self) -> bool {
|
|
self.entered && self.focused() == $Focus
|
|
}
|
|
fn time_axis (&self) -> &RwLock<ScaledAxis<usize>> {
|
|
&self.editor.time_axis
|
|
}
|
|
fn note_axis (&self) -> &RwLock<FixedAxis<usize>> {
|
|
&self.editor.note_axis
|
|
}
|
|
fn note_len (&self) -> usize {
|
|
self.editor.note_len
|
|
}
|
|
fn note_len_mut (&mut self) -> &mut usize {
|
|
&mut self.editor.note_len
|
|
}
|
|
fn put_note (&mut self) {
|
|
todo!("put_note")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl_jack_api!(TransportTui::jack);
|
|
impl_jack_api!(SequencerTui::jack);
|
|
impl_jack_api!(ArrangerTui::jack);
|
|
|
|
impl_clock_api!(TransportTui::clock);
|
|
impl_clock_api!(SequencerTui::clock);
|
|
impl_clock_api!(ArrangerTui::clock);
|
|
impl_clock_api!(PhrasePlayerModel::clock);
|
|
impl_clock_api!(ArrangerTrack::player::clock);
|
|
|
|
impl_has_phrases!(PhrasesModel);
|
|
impl_has_phrases!(SequencerTui::phrases);
|
|
impl_has_phrases!(ArrangerTui::phrases);
|
|
|
|
impl_midi_player!(SequencerTui::player);
|
|
impl_midi_player!(ArrangerTrack::player);
|
|
impl_midi_player!(PhrasePlayerModel);
|
|
|
|
impl_phrases_control!(SequencerTui);
|
|
impl_phrases_control!(ArrangerTui);
|
|
|
|
impl_phrase_editor_control!(SequencerTui [
|
|
AppFocus::Content(SequencerFocus::PhraseEditor)
|
|
]);
|
|
impl_phrase_editor_control!(ArrangerTui [
|
|
AppFocus::Content(ArrangerFocus::PhraseEditor)
|
|
]);
|