mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
move PhrasePlayerModel to api/
This commit is contained in:
parent
391a3dba08
commit
e34a895357
10 changed files with 185 additions and 193 deletions
|
|
@ -5,42 +5,102 @@ pub trait HasPlayer {
|
||||||
fn player_mut (&mut self) -> &mut impl MidiPlayerApi;
|
fn player_mut (&mut self) -> &mut impl MidiPlayerApi;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait MidiPlayerApi: MidiRecordApi + MidiPlaybackApi + Send + Sync {}
|
/// Contains state for playing a phrase
|
||||||
|
pub struct PhrasePlayerModel {
|
||||||
|
/// State of clock and playhead
|
||||||
|
pub(crate) clock: ClockModel,
|
||||||
|
/// Start time and phrase being played
|
||||||
|
pub(crate) play_phrase: Option<(Moment, Option<Arc<RwLock<Phrase>>>)>,
|
||||||
|
/// Start time and next phrase
|
||||||
|
pub(crate) next_phrase: Option<(Moment, Option<Arc<RwLock<Phrase>>>)>,
|
||||||
|
/// Play input through output.
|
||||||
|
pub(crate) monitoring: bool,
|
||||||
|
/// Write input to sequence.
|
||||||
|
pub(crate) recording: bool,
|
||||||
|
/// Overdub input to sequence.
|
||||||
|
pub(crate) overdub: bool,
|
||||||
|
/// Send all notes off
|
||||||
|
pub(crate) reset: bool, // TODO?: after Some(nframes)
|
||||||
|
/// Record from MIDI ports to current sequence.
|
||||||
|
pub midi_ins: Vec<Port<MidiIn>>,
|
||||||
|
/// Play from current sequence to MIDI ports
|
||||||
|
pub midi_outs: Vec<Port<MidiOut>>,
|
||||||
|
/// Notes currently held at input
|
||||||
|
pub(crate) notes_in: Arc<RwLock<[bool; 128]>>,
|
||||||
|
/// Notes currently held at output
|
||||||
|
pub(crate) notes_out: Arc<RwLock<[bool; 128]>>,
|
||||||
|
/// MIDI output buffer
|
||||||
|
pub note_buf: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
pub trait HasPlayPhrase: HasClock {
|
impl std::fmt::Debug for PhrasePlayerModel {
|
||||||
fn reset (&self) -> bool;
|
fn fmt (&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
|
||||||
fn reset_mut (&mut self) -> &mut bool;
|
f.debug_struct("PhrasePlayerModel")
|
||||||
fn play_phrase (&self) -> &Option<(Moment, Option<Arc<RwLock<Phrase>>>)>;
|
.field("clock", &self.clock)
|
||||||
fn play_phrase_mut (&mut self) -> &mut Option<(Moment, Option<Arc<RwLock<Phrase>>>)>;
|
.field("play_phrase", &self.play_phrase)
|
||||||
fn next_phrase (&self) -> &Option<(Moment, Option<Arc<RwLock<Phrase>>>)>;
|
.field("next_phrase", &self.next_phrase)
|
||||||
fn next_phrase_mut (&mut self) -> &mut Option<(Moment, Option<Arc<RwLock<Phrase>>>)>;
|
.finish()
|
||||||
fn pulses_since_start (&self) -> Option<f64> {
|
|
||||||
if let Some((started, Some(_))) = self.play_phrase().as_ref() {
|
|
||||||
let elapsed = self.clock().playhead.pulse.get() - started.pulse.get();
|
|
||||||
Some(elapsed)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn pulses_since_start_looped (&self) -> Option<f64> {
|
|
||||||
if let Some((started, Some(phrase))) = self.play_phrase().as_ref() {
|
|
||||||
let elapsed = self.clock().playhead.pulse.get() - started.pulse.get();
|
|
||||||
let length = phrase.read().unwrap().length.max(1); // prevent div0 on empty phrase
|
|
||||||
let elapsed = (elapsed as usize % length) as f64;
|
|
||||||
Some(elapsed)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn enqueue_next (&mut self, phrase: Option<&Arc<RwLock<Phrase>>>) {
|
|
||||||
let start = self.clock().next_launch_pulse() as f64;
|
|
||||||
let instant = Moment::from_pulse(&self.clock().timebase(), start);
|
|
||||||
let phrase = phrase.map(|p|p.clone());
|
|
||||||
*self.next_phrase_mut() = Some((instant, phrase));
|
|
||||||
*self.reset_mut() = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<&ClockModel> for PhrasePlayerModel {
|
||||||
|
fn from (clock: &ClockModel) -> Self {
|
||||||
|
Self {
|
||||||
|
clock: clock.clone(),
|
||||||
|
midi_ins: vec![],
|
||||||
|
midi_outs: vec![],
|
||||||
|
note_buf: vec![0;8],
|
||||||
|
reset: true,
|
||||||
|
recording: false,
|
||||||
|
monitoring: false,
|
||||||
|
overdub: false,
|
||||||
|
play_phrase: None,
|
||||||
|
next_phrase: None,
|
||||||
|
notes_in: RwLock::new([false;128]).into(),
|
||||||
|
notes_out: RwLock::new([false;128]).into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<(&ClockModel, &Arc<RwLock<Phrase>>)> for PhrasePlayerModel {
|
||||||
|
fn from ((clock, phrase): (&ClockModel, &Arc<RwLock<Phrase>>)) -> Self {
|
||||||
|
let mut model = Self::from(clock);
|
||||||
|
model.play_phrase = Some((Moment::zero(&clock.timebase), Some(phrase.clone())));
|
||||||
|
model
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HasClock for PhrasePlayerModel {
|
||||||
|
fn clock (&self) -> &ClockModel {
|
||||||
|
&self.clock
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HasMidiIns for PhrasePlayerModel {
|
||||||
|
fn midi_ins (&self) -> &Vec<Port<jack::MidiIn>> {
|
||||||
|
&self.midi_ins
|
||||||
|
}
|
||||||
|
fn midi_ins_mut (&mut self) -> &mut Vec<Port<jack::MidiIn>> {
|
||||||
|
&mut self.midi_ins
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HasMidiOuts for PhrasePlayerModel {
|
||||||
|
fn midi_outs (&self) -> &Vec<Port<jack::MidiOut>> {
|
||||||
|
&self.midi_outs
|
||||||
|
}
|
||||||
|
fn midi_outs_mut (&mut self) -> &mut Vec<Port<jack::MidiOut>> {
|
||||||
|
&mut self.midi_outs
|
||||||
|
}
|
||||||
|
fn midi_note (&mut self) -> &mut Vec<u8> {
|
||||||
|
&mut self.note_buf
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait MidiPlayerApi: MidiRecordApi + MidiPlaybackApi + Send + Sync {}
|
||||||
|
|
||||||
|
impl MidiPlayerApi for PhrasePlayerModel {}
|
||||||
|
|
||||||
pub trait MidiRecordApi: HasClock + HasPlayPhrase + HasMidiIns {
|
pub trait MidiRecordApi: HasClock + HasPlayPhrase + HasMidiIns {
|
||||||
fn notes_in (&self) -> &Arc<RwLock<[bool;128]>>;
|
fn notes_in (&self) -> &Arc<RwLock<[bool;128]>>;
|
||||||
|
|
||||||
|
|
@ -115,6 +175,30 @@ pub trait MidiRecordApi: HasClock + HasPlayPhrase + HasMidiIns {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl MidiRecordApi for PhrasePlayerModel {
|
||||||
|
fn recording (&self) -> bool {
|
||||||
|
self.recording
|
||||||
|
}
|
||||||
|
fn recording_mut (&mut self) -> &mut bool {
|
||||||
|
&mut self.recording
|
||||||
|
}
|
||||||
|
fn monitoring (&self) -> bool {
|
||||||
|
self.monitoring
|
||||||
|
}
|
||||||
|
fn monitoring_mut (&mut self) -> &mut bool {
|
||||||
|
&mut self.monitoring
|
||||||
|
}
|
||||||
|
fn overdub (&self) -> bool {
|
||||||
|
self.overdub
|
||||||
|
}
|
||||||
|
fn overdub_mut (&mut self) -> &mut bool {
|
||||||
|
&mut self.overdub
|
||||||
|
}
|
||||||
|
fn notes_in (&self) -> &Arc<RwLock<[bool; 128]>> {
|
||||||
|
&self.notes_in
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait MidiPlaybackApi: HasPlayPhrase + HasClock + HasMidiOuts {
|
pub trait MidiPlaybackApi: HasPlayPhrase + HasClock + HasMidiOuts {
|
||||||
|
|
||||||
fn notes_out (&self) -> &Arc<RwLock<[bool;128]>>;
|
fn notes_out (&self) -> &Arc<RwLock<[bool;128]>>;
|
||||||
|
|
@ -248,6 +332,67 @@ pub trait MidiPlaybackApi: HasPlayPhrase + HasClock + HasMidiOuts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl MidiPlaybackApi for PhrasePlayerModel {
|
||||||
|
fn notes_out (&self) -> &Arc<RwLock<[bool; 128]>> {
|
||||||
|
&self.notes_in
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait HasPlayPhrase: HasClock {
|
||||||
|
fn reset (&self) -> bool;
|
||||||
|
fn reset_mut (&mut self) -> &mut bool;
|
||||||
|
fn play_phrase (&self) -> &Option<(Moment, Option<Arc<RwLock<Phrase>>>)>;
|
||||||
|
fn play_phrase_mut (&mut self) -> &mut Option<(Moment, Option<Arc<RwLock<Phrase>>>)>;
|
||||||
|
fn next_phrase (&self) -> &Option<(Moment, Option<Arc<RwLock<Phrase>>>)>;
|
||||||
|
fn next_phrase_mut (&mut self) -> &mut Option<(Moment, Option<Arc<RwLock<Phrase>>>)>;
|
||||||
|
fn pulses_since_start (&self) -> Option<f64> {
|
||||||
|
if let Some((started, Some(_))) = self.play_phrase().as_ref() {
|
||||||
|
let elapsed = self.clock().playhead.pulse.get() - started.pulse.get();
|
||||||
|
Some(elapsed)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn pulses_since_start_looped (&self) -> Option<f64> {
|
||||||
|
if let Some((started, Some(phrase))) = self.play_phrase().as_ref() {
|
||||||
|
let elapsed = self.clock().playhead.pulse.get() - started.pulse.get();
|
||||||
|
let length = phrase.read().unwrap().length.max(1); // prevent div0 on empty phrase
|
||||||
|
let elapsed = (elapsed as usize % length) as f64;
|
||||||
|
Some(elapsed)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn enqueue_next (&mut self, phrase: Option<&Arc<RwLock<Phrase>>>) {
|
||||||
|
let start = self.clock().next_launch_pulse() as f64;
|
||||||
|
let instant = Moment::from_pulse(&self.clock().timebase(), start);
|
||||||
|
let phrase = phrase.map(|p|p.clone());
|
||||||
|
*self.next_phrase_mut() = Some((instant, phrase));
|
||||||
|
*self.reset_mut() = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HasPlayPhrase for PhrasePlayerModel {
|
||||||
|
fn reset (&self) -> bool {
|
||||||
|
self.reset
|
||||||
|
}
|
||||||
|
fn reset_mut (&mut self) -> &mut bool {
|
||||||
|
&mut self.reset
|
||||||
|
}
|
||||||
|
fn play_phrase (&self) -> &Option<(Moment, Option<Arc<RwLock<Phrase>>>)> {
|
||||||
|
&self.play_phrase
|
||||||
|
}
|
||||||
|
fn play_phrase_mut (&mut self) -> &mut Option<(Moment, Option<Arc<RwLock<Phrase>>>)> {
|
||||||
|
&mut self.play_phrase
|
||||||
|
}
|
||||||
|
fn next_phrase (&self) -> &Option<(Moment, Option<Arc<RwLock<Phrase>>>)> {
|
||||||
|
&self.next_phrase
|
||||||
|
}
|
||||||
|
fn next_phrase_mut (&mut self) -> &mut Option<(Moment, Option<Arc<RwLock<Phrase>>>)> {
|
||||||
|
&mut self.next_phrase
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Add "all notes off" to the start of a buffer.
|
/// Add "all notes off" to the start of a buffer.
|
||||||
pub fn all_notes_off (output: &mut [Vec<Vec<u8>>]) {
|
pub fn all_notes_off (output: &mut [Vec<Vec<u8>>]) {
|
||||||
let mut buf = vec![];
|
let mut buf = vec![];
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
use crate::*;
|
|
||||||
|
|
||||||
mod audio; pub(crate) use audio::*;
|
mod audio; pub(crate) use audio::*;
|
||||||
mod color; pub(crate) use color::*;
|
mod color; pub(crate) use color::*;
|
||||||
mod command; pub(crate) use command::*;
|
mod command; pub(crate) use command::*;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
pub use clojure_reader::{edn::{read, Edn}, error::Error as EdnError};
|
pub use clojure_reader::edn::Edn;
|
||||||
|
//pub use clojure_reader::{edn::{read, Edn}, error::Error as EdnError};
|
||||||
|
|
||||||
/// EDN parsing helper.
|
/// EDN parsing helper.
|
||||||
#[macro_export] macro_rules! edn {
|
#[macro_export] macro_rules! edn {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use midly::num::u7;
|
|
||||||
|
|
||||||
pub fn to_note_name (n: usize) -> &'static str {
|
pub fn to_note_name (n: usize) -> &'static str {
|
||||||
if n > 127 {
|
if n > 127 {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
use crate::*;
|
|
||||||
|
|
||||||
mod align; pub(crate) use align::*;
|
mod align; pub(crate) use align::*;
|
||||||
mod bsp; pub(crate) use bsp::*;
|
mod bsp; pub(crate) use bsp::*;
|
||||||
mod cond; pub(crate) use cond::*;
|
mod cond; pub(crate) use cond::*;
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ pub(crate) use ratatui::{
|
||||||
pub(crate) use jack;
|
pub(crate) use jack;
|
||||||
pub(crate) use jack::{
|
pub(crate) use jack::{
|
||||||
Client, ProcessScope, Control, CycleTimes,
|
Client, ProcessScope, Control, CycleTimes,
|
||||||
Port, PortSpec, MidiIn, MidiOut, AudioIn, AudioOut, Unowned,
|
Port, PortSpec, MidiIn, MidiOut, AudioOut, Unowned,
|
||||||
Transport, TransportState, MidiIter, RawMidi,
|
Transport, TransportState, MidiIter, RawMidi,
|
||||||
contrib::ClosureProcessHandler,
|
contrib::ClosureProcessHandler,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ mod piano_horizontal; pub(crate) use piano_horizontal::*;
|
||||||
mod phrase_length; pub(crate) use phrase_length::*;
|
mod phrase_length; pub(crate) use phrase_length::*;
|
||||||
mod phrase_rename; pub(crate) use phrase_rename::*;
|
mod phrase_rename; pub(crate) use phrase_rename::*;
|
||||||
mod phrase_list; pub(crate) use phrase_list::*;
|
mod phrase_list; pub(crate) use phrase_list::*;
|
||||||
mod phrase_player; pub(crate) use phrase_player::*;
|
|
||||||
mod port_select; pub(crate) use port_select::*;
|
mod port_select; pub(crate) use port_select::*;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::{*, api::ClockCommand::{Play, Pause}};
|
use crate::{*, api::ClockCommand::{Play, Pause}};
|
||||||
use KeyCode::{Tab, BackTab, Char, Enter, Esc};
|
use KeyCode::{Tab, BackTab, Char};
|
||||||
use SequencerCommand::*;
|
use SequencerCommand::*;
|
||||||
use SequencerFocus::*;
|
use SequencerFocus::*;
|
||||||
use PhraseCommand::*;
|
use PhraseCommand::*;
|
||||||
|
|
|
||||||
|
|
@ -127,12 +127,10 @@ render!(|self: TransportView|{
|
||||||
struct PlayPause(bool);
|
struct PlayPause(bool);
|
||||||
render!(|self: PlayPause|Tui::bg(
|
render!(|self: PlayPause|Tui::bg(
|
||||||
if self.0{Color::Rgb(0,128,0)}else{Color::Rgb(128,64,0)},
|
if self.0{Color::Rgb(0,128,0)}else{Color::Rgb(128,64,0)},
|
||||||
Tui::outset_x(1, Tui::fixed_x(9, col!(|add|{
|
Tui::outset_x(1, Tui::fixed_x(9, col!(|add|if self.0 {
|
||||||
if self.0 {
|
add(&Tui::fg(Color::Rgb(0, 255, 0), col!(["▶ PLAYING", "▒ ▒ ▒ ▒ ▒"])))
|
||||||
add(&col!([Tui::fg(Color::Rgb(0, 255, 0), "▶ PLAYING"), ""]))
|
} else {
|
||||||
} else {
|
add(&Tui::fg(Color::Rgb(255, 128, 0), col!(["▒ ▒ ▒ ▒ ▒", "⏹ STOPPED"])))
|
||||||
add(&col!(["", Tui::fg(Color::Rgb(255, 128, 0), "⏹ STOPPED")]))
|
|
||||||
}
|
|
||||||
})))
|
})))
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,146 +0,0 @@
|
||||||
use crate::*;
|
|
||||||
|
|
||||||
/// Contains state for playing a phrase
|
|
||||||
pub struct PhrasePlayerModel {
|
|
||||||
/// State of clock and playhead
|
|
||||||
pub(crate) clock: ClockModel,
|
|
||||||
/// Start time and phrase being played
|
|
||||||
pub(crate) play_phrase: Option<(Moment, Option<Arc<RwLock<Phrase>>>)>,
|
|
||||||
/// Start time and next phrase
|
|
||||||
pub(crate) next_phrase: Option<(Moment, Option<Arc<RwLock<Phrase>>>)>,
|
|
||||||
/// Play input through output.
|
|
||||||
pub(crate) monitoring: bool,
|
|
||||||
/// Write input to sequence.
|
|
||||||
pub(crate) recording: bool,
|
|
||||||
/// Overdub input to sequence.
|
|
||||||
pub(crate) overdub: bool,
|
|
||||||
/// Send all notes off
|
|
||||||
pub(crate) reset: bool, // TODO?: after Some(nframes)
|
|
||||||
/// Record from MIDI ports to current sequence.
|
|
||||||
pub midi_ins: Vec<Port<MidiIn>>,
|
|
||||||
/// Play from current sequence to MIDI ports
|
|
||||||
pub midi_outs: Vec<Port<MidiOut>>,
|
|
||||||
/// Notes currently held at input
|
|
||||||
pub(crate) notes_in: Arc<RwLock<[bool; 128]>>,
|
|
||||||
/// Notes currently held at output
|
|
||||||
pub(crate) notes_out: Arc<RwLock<[bool; 128]>>,
|
|
||||||
/// MIDI output buffer
|
|
||||||
pub note_buf: Vec<u8>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::fmt::Debug for PhrasePlayerModel {
|
|
||||||
fn fmt (&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
|
|
||||||
f.debug_struct("PhrasePlayerModel")
|
|
||||||
.field("clock", &self.clock)
|
|
||||||
.field("play_phrase", &self.play_phrase)
|
|
||||||
.field("next_phrase", &self.next_phrase)
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&ClockModel> for PhrasePlayerModel {
|
|
||||||
fn from (clock: &ClockModel) -> Self {
|
|
||||||
Self {
|
|
||||||
clock: clock.clone(),
|
|
||||||
midi_ins: vec![],
|
|
||||||
midi_outs: vec![],
|
|
||||||
note_buf: vec![0;8],
|
|
||||||
reset: true,
|
|
||||||
recording: false,
|
|
||||||
monitoring: false,
|
|
||||||
overdub: false,
|
|
||||||
play_phrase: None,
|
|
||||||
next_phrase: None,
|
|
||||||
notes_in: RwLock::new([false;128]).into(),
|
|
||||||
notes_out: RwLock::new([false;128]).into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<(&ClockModel, &Arc<RwLock<Phrase>>)> for PhrasePlayerModel {
|
|
||||||
fn from ((clock, phrase): (&ClockModel, &Arc<RwLock<Phrase>>)) -> Self {
|
|
||||||
let mut model = Self::from(clock);
|
|
||||||
model.play_phrase = Some((Moment::zero(&clock.timebase), Some(phrase.clone())));
|
|
||||||
model
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HasClock for PhrasePlayerModel {
|
|
||||||
fn clock (&self) -> &ClockModel {
|
|
||||||
&self.clock
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HasPlayPhrase for PhrasePlayerModel {
|
|
||||||
fn reset (&self) -> bool {
|
|
||||||
self.reset
|
|
||||||
}
|
|
||||||
fn reset_mut (&mut self) -> &mut bool {
|
|
||||||
&mut self.reset
|
|
||||||
}
|
|
||||||
fn play_phrase (&self) -> &Option<(Moment, Option<Arc<RwLock<Phrase>>>)> {
|
|
||||||
&self.play_phrase
|
|
||||||
}
|
|
||||||
fn play_phrase_mut (&mut self) -> &mut Option<(Moment, Option<Arc<RwLock<Phrase>>>)> {
|
|
||||||
&mut self.play_phrase
|
|
||||||
}
|
|
||||||
fn next_phrase (&self) -> &Option<(Moment, Option<Arc<RwLock<Phrase>>>)> {
|
|
||||||
&self.next_phrase
|
|
||||||
}
|
|
||||||
fn next_phrase_mut (&mut self) -> &mut Option<(Moment, Option<Arc<RwLock<Phrase>>>)> {
|
|
||||||
&mut self.next_phrase
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HasMidiIns for PhrasePlayerModel {
|
|
||||||
fn midi_ins (&self) -> &Vec<Port<jack::MidiIn>> {
|
|
||||||
&self.midi_ins
|
|
||||||
}
|
|
||||||
fn midi_ins_mut (&mut self) -> &mut Vec<Port<jack::MidiIn>> {
|
|
||||||
&mut self.midi_ins
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MidiRecordApi for PhrasePlayerModel {
|
|
||||||
fn recording (&self) -> bool {
|
|
||||||
self.recording
|
|
||||||
}
|
|
||||||
fn recording_mut (&mut self) -> &mut bool {
|
|
||||||
&mut self.recording
|
|
||||||
}
|
|
||||||
fn monitoring (&self) -> bool {
|
|
||||||
self.monitoring
|
|
||||||
}
|
|
||||||
fn monitoring_mut (&mut self) -> &mut bool {
|
|
||||||
&mut self.monitoring
|
|
||||||
}
|
|
||||||
fn overdub (&self) -> bool {
|
|
||||||
self.overdub
|
|
||||||
}
|
|
||||||
fn overdub_mut (&mut self) -> &mut bool {
|
|
||||||
&mut self.overdub
|
|
||||||
}
|
|
||||||
fn notes_in (&self) -> &Arc<RwLock<[bool; 128]>> {
|
|
||||||
&self.notes_in
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HasMidiOuts for PhrasePlayerModel {
|
|
||||||
fn midi_outs (&self) -> &Vec<Port<jack::MidiOut>> {
|
|
||||||
&self.midi_outs
|
|
||||||
}
|
|
||||||
fn midi_outs_mut (&mut self) -> &mut Vec<Port<jack::MidiOut>> {
|
|
||||||
&mut self.midi_outs
|
|
||||||
}
|
|
||||||
fn midi_note (&mut self) -> &mut Vec<u8> {
|
|
||||||
&mut self.note_buf
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MidiPlaybackApi for PhrasePlayerModel {
|
|
||||||
fn notes_out (&self) -> &Arc<RwLock<[bool; 128]>> {
|
|
||||||
&self.notes_in
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MidiPlayerApi for PhrasePlayerModel {}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue