mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
readd todos
This commit is contained in:
parent
3c990e9f63
commit
3d669d7d24
19 changed files with 299 additions and 299 deletions
|
|
@ -1,4 +1 @@
|
|||
mod phrase; pub(crate) use phrase::*;
|
||||
mod scene; pub(crate) use scene::*;
|
||||
mod track; pub(crate) use track::*;
|
||||
mod sampler; pub(crate) use sampler::*;
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
use crate::*;
|
||||
|
||||
/// Supported plugin formats.
|
||||
#[derive(Default)]
|
||||
pub enum PluginKind {
|
||||
#[default] None,
|
||||
LV2(LV2Plugin),
|
||||
VST2 { instance: ::vst::host::PluginInstance },
|
||||
VST3,
|
||||
}
|
||||
|
||||
impl Debug for PluginKind {
|
||||
fn fmt (&self, f: &mut Formatter<'_>) -> std::result::Result<(), Error> {
|
||||
write!(f, "{}", match self {
|
||||
Self::None => "(none)",
|
||||
Self::LV2(_) => "LV2",
|
||||
Self::VST2{..} => "VST2",
|
||||
Self::VST3 => "VST3",
|
||||
})
|
||||
}
|
||||
}
|
||||
3
crates/tek/src/audio.rs
Normal file
3
crates/tek/src/audio.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
pub(crate) mod audio_in; pub(crate) use audio_in::*;
|
||||
pub(crate) mod audio_out; pub(crate) use audio_out::*;
|
||||
pub(crate) mod sampler; pub(crate) use sampler::*;
|
||||
0
crates/tek/src/audio/audio_in.rs
Normal file
0
crates/tek/src/audio/audio_in.rs
Normal file
0
crates/tek/src/audio/audio_out.rs
Normal file
0
crates/tek/src/audio/audio_out.rs
Normal file
|
|
@ -1,11 +1,11 @@
|
|||
use crate::*;
|
||||
|
||||
pub(crate) mod activate; pub(crate) use activate::*;
|
||||
pub(crate) mod audio; pub(crate) use audio::*;
|
||||
pub(crate) mod client; pub(crate) use client::*;
|
||||
pub(crate) mod from_jack; pub(crate) use from_jack::*;
|
||||
pub(crate) mod jack_event; pub(crate) use jack_event::*;
|
||||
pub(crate) mod ports; pub(crate) use ports::*;
|
||||
pub(crate) mod activate; pub(crate) use self::activate::*;
|
||||
pub(crate) mod audio; pub(crate) use self::audio::*;
|
||||
pub(crate) mod client; pub(crate) use self::client::*;
|
||||
pub(crate) mod from_jack; pub(crate) use self::from_jack::*;
|
||||
pub(crate) mod jack_event; pub(crate) use self::jack_event::*;
|
||||
pub(crate) mod ports; pub(crate) use self::ports::*;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
pub mod core; pub(crate) use self::core::*;
|
||||
pub mod api; pub(crate) use self::api::*;
|
||||
pub mod tui; pub(crate) use self::tui::*;
|
||||
pub mod edn; pub(crate) use self::edn::*;
|
||||
pub mod jack; pub(crate) use self::jack::*;
|
||||
pub mod midi; pub(crate) use self::midi::*;
|
||||
pub mod time; pub(crate) use self::time::*;
|
||||
pub mod space; pub(crate) use self::space::*;
|
||||
pub mod time; pub(crate) use self::time::*;
|
||||
pub mod space; pub(crate) use self::space::*;
|
||||
pub mod tui; pub(crate) use self::tui::*;
|
||||
pub mod edn; pub(crate) use self::edn::*;
|
||||
pub mod jack; pub(crate) use self::jack::*;
|
||||
pub mod midi; pub(crate) use self::midi::*;
|
||||
pub mod audio; pub(crate) use self::audio::*;
|
||||
//pub mod plugin; pub(crate) use self::plugin::*;
|
||||
|
||||
/// Standard result type.
|
||||
pub type Usually<T> = Result<T, Box<dyn Error>>;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
use crate::*;
|
||||
|
||||
pub(crate) mod midi_note; pub(crate) use midi_note::*;
|
||||
pub(crate) mod midi_in; pub(crate) use midi_in::*;
|
||||
pub(crate) mod midi_out; pub(crate) use midi_out::*;
|
||||
pub(crate) mod midi_player; pub(crate) use midi_player::*;
|
||||
pub(crate) mod midi_launch; pub(crate) use midi_launch::*;
|
||||
pub(crate) mod midi_note; pub(crate) use midi_note::*;
|
||||
pub(crate) mod midi_out; pub(crate) use midi_out::*;
|
||||
pub(crate) mod midi_phrase; pub(crate) use midi_phrase::*;
|
||||
pub(crate) mod midi_play; pub(crate) use midi_play::*;
|
||||
pub(crate) mod midi_rec; pub(crate) use midi_rec::*;
|
||||
pub(crate) mod midi_scene; pub(crate) use midi_scene::*;
|
||||
pub(crate) mod midi_track; pub(crate) use midi_track::*;
|
||||
|
||||
/// Add "all notes off" to the start of a buffer.
|
||||
pub fn all_notes_off (output: &mut [Vec<Vec<u8>>]) {
|
||||
|
|
@ -55,3 +57,257 @@ pub const MIDI_NOTE_NAMES: [&'static str;128] = [
|
|||
"C9", "C#9", "D9", "D#9", "E9", "F9", "F#9", "G9", "G#9", "A9", "A#9", "B9",
|
||||
"C10", "C#10", "D10", "D#10", "E10", "F10", "F#10", "G10",
|
||||
];
|
||||
|
||||
pub trait MidiPlayerApi: MidiRecordApi + MidiPlaybackApi + Send + Sync {}
|
||||
|
||||
impl MidiPlayerApi for PhrasePlayerModel {}
|
||||
|
||||
pub trait HasPlayer {
|
||||
fn player (&self) -> &impl MidiPlayerApi;
|
||||
fn player_mut (&mut self) -> &mut impl MidiPlayerApi;
|
||||
}
|
||||
|
||||
#[macro_export] macro_rules! has_player {
|
||||
(|$self:ident:$Struct:ident$(<$($L:lifetime),*$($T:ident$(:$U:path)?),*>)?|$cb:expr) => {
|
||||
impl $(<$($L),*$($T $(: $U)?),*>)? HasPlayer for $Struct $(<$($L),*$($T),*>)? {
|
||||
fn player (&$self) -> &impl MidiPlayerApi { &$cb }
|
||||
fn player_mut (&mut $self) -> &mut impl MidiPlayerApi { &mut$cb }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 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
|
||||
}
|
||||
}
|
||||
|
||||
has_clock!(|self:PhrasePlayerModel|&self.clock);
|
||||
|
||||
impl HasMidiIns for PhrasePlayerModel {
|
||||
fn midi_ins (&self) -> &Vec<Port<MidiIn>> {
|
||||
&self.midi_ins
|
||||
}
|
||||
fn midi_ins_mut (&mut self) -> &mut Vec<Port<MidiIn>> {
|
||||
&mut self.midi_ins
|
||||
}
|
||||
}
|
||||
|
||||
impl HasMidiOuts for PhrasePlayerModel {
|
||||
fn midi_outs (&self) -> &Vec<Port<MidiOut>> {
|
||||
&self.midi_outs
|
||||
}
|
||||
fn midi_outs_mut (&mut self) -> &mut Vec<Port<MidiOut>> {
|
||||
&mut self.midi_outs
|
||||
}
|
||||
fn midi_note (&mut self) -> &mut Vec<u8> {
|
||||
&mut self.note_buf
|
||||
}
|
||||
}
|
||||
|
||||
/// Hosts the JACK callback for a single MIDI player
|
||||
pub struct PlayerAudio<'a, T: MidiPlayerApi>(
|
||||
/// Player
|
||||
pub &'a mut T,
|
||||
/// Note buffer
|
||||
pub &'a mut Vec<u8>,
|
||||
/// Note chunk buffer
|
||||
pub &'a mut Vec<Vec<Vec<u8>>>,
|
||||
);
|
||||
|
||||
/// JACK process callback for a sequencer's phrase player/recorder.
|
||||
impl<'a, T: MidiPlayerApi> Audio for PlayerAudio<'a, T> {
|
||||
fn process (&mut self, _: &Client, scope: &ProcessScope) -> Control {
|
||||
let model = &mut self.0;
|
||||
let note_buf = &mut self.1;
|
||||
let midi_buf = &mut self.2;
|
||||
// Clear output buffer(s)
|
||||
model.clear(scope, midi_buf, false);
|
||||
// Write chunk of phrase to output, handle switchover
|
||||
if model.play(scope, note_buf, midi_buf) {
|
||||
model.switchover(scope, note_buf, midi_buf);
|
||||
}
|
||||
if model.has_midi_ins() {
|
||||
if model.recording() || model.monitoring() {
|
||||
// Record and/or monitor input
|
||||
model.record(scope, midi_buf)
|
||||
} else if model.has_midi_outs() && model.monitoring() {
|
||||
// Monitor input to output
|
||||
model.monitor(scope, midi_buf)
|
||||
}
|
||||
}
|
||||
// Write to output port(s)
|
||||
model.write(scope, midi_buf);
|
||||
Control::Continue
|
||||
}
|
||||
}
|
||||
|
||||
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 MidiPlaybackApi for PhrasePlayerModel {
|
||||
fn notes_out (&self) -> &Arc<RwLock<[bool; 128]>> {
|
||||
&self.notes_in
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
//#[derive(Debug)]
|
||||
//pub struct MIDIPlayer {
|
||||
///// Global timebase
|
||||
//pub clock: Arc<Clock>,
|
||||
///// Start time and phrase being played
|
||||
//pub play_phrase: Option<(Moment, Option<Arc<RwLock<Phrase>>>)>,
|
||||
///// Start time and next phrase
|
||||
//pub next_phrase: Option<(Moment, Option<Arc<RwLock<Phrase>>>)>,
|
||||
///// 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_inputs: Vec<Port<MidiIn>>,
|
||||
///// Play from current sequence to MIDI ports
|
||||
//pub midi_outputs: Vec<Port<MidiOut>>,
|
||||
///// MIDI output buffer
|
||||
//pub midi_note: Vec<u8>,
|
||||
///// MIDI output buffer
|
||||
//pub midi_chunk: Vec<Vec<Vec<u8>>>,
|
||||
///// Notes currently held at input
|
||||
//pub notes_in: Arc<RwLock<[bool; 128]>>,
|
||||
///// Notes currently held at output
|
||||
//pub notes_out: Arc<RwLock<[bool; 128]>>,
|
||||
//}
|
||||
|
||||
///// 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())?
|
||||
//],
|
||||
//})
|
||||
//}
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -1,255 +0,0 @@
|
|||
use crate::*;
|
||||
|
||||
pub trait MidiPlayerApi: MidiRecordApi + MidiPlaybackApi + Send + Sync {}
|
||||
|
||||
impl MidiPlayerApi for PhrasePlayerModel {}
|
||||
|
||||
pub trait HasPlayer {
|
||||
fn player (&self) -> &impl MidiPlayerApi;
|
||||
fn player_mut (&mut self) -> &mut impl MidiPlayerApi;
|
||||
}
|
||||
|
||||
#[macro_export] macro_rules! has_player {
|
||||
(|$self:ident:$Struct:ident$(<$($L:lifetime),*$($T:ident$(:$U:path)?),*>)?|$cb:expr) => {
|
||||
impl $(<$($L),*$($T $(: $U)?),*>)? HasPlayer for $Struct $(<$($L),*$($T),*>)? {
|
||||
fn player (&$self) -> &impl MidiPlayerApi { &$cb }
|
||||
fn player_mut (&mut $self) -> &mut impl MidiPlayerApi { &mut$cb }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 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
|
||||
}
|
||||
}
|
||||
|
||||
has_clock!(|self:PhrasePlayerModel|&self.clock);
|
||||
|
||||
impl HasMidiIns for PhrasePlayerModel {
|
||||
fn midi_ins (&self) -> &Vec<Port<MidiIn>> {
|
||||
&self.midi_ins
|
||||
}
|
||||
fn midi_ins_mut (&mut self) -> &mut Vec<Port<MidiIn>> {
|
||||
&mut self.midi_ins
|
||||
}
|
||||
}
|
||||
|
||||
impl HasMidiOuts for PhrasePlayerModel {
|
||||
fn midi_outs (&self) -> &Vec<Port<MidiOut>> {
|
||||
&self.midi_outs
|
||||
}
|
||||
fn midi_outs_mut (&mut self) -> &mut Vec<Port<MidiOut>> {
|
||||
&mut self.midi_outs
|
||||
}
|
||||
fn midi_note (&mut self) -> &mut Vec<u8> {
|
||||
&mut self.note_buf
|
||||
}
|
||||
}
|
||||
|
||||
/// Hosts the JACK callback for a single MIDI player
|
||||
pub struct PlayerAudio<'a, T: MidiPlayerApi>(
|
||||
/// Player
|
||||
pub &'a mut T,
|
||||
/// Note buffer
|
||||
pub &'a mut Vec<u8>,
|
||||
/// Note chunk buffer
|
||||
pub &'a mut Vec<Vec<Vec<u8>>>,
|
||||
);
|
||||
|
||||
/// JACK process callback for a sequencer's phrase player/recorder.
|
||||
impl<'a, T: MidiPlayerApi> Audio for PlayerAudio<'a, T> {
|
||||
fn process (&mut self, _: &Client, scope: &ProcessScope) -> Control {
|
||||
let model = &mut self.0;
|
||||
let note_buf = &mut self.1;
|
||||
let midi_buf = &mut self.2;
|
||||
// Clear output buffer(s)
|
||||
model.clear(scope, midi_buf, false);
|
||||
// Write chunk of phrase to output, handle switchover
|
||||
if model.play(scope, note_buf, midi_buf) {
|
||||
model.switchover(scope, note_buf, midi_buf);
|
||||
}
|
||||
if model.has_midi_ins() {
|
||||
if model.recording() || model.monitoring() {
|
||||
// Record and/or monitor input
|
||||
model.record(scope, midi_buf)
|
||||
} else if model.has_midi_outs() && model.monitoring() {
|
||||
// Monitor input to output
|
||||
model.monitor(scope, midi_buf)
|
||||
}
|
||||
}
|
||||
// Write to output port(s)
|
||||
model.write(scope, midi_buf);
|
||||
Control::Continue
|
||||
}
|
||||
}
|
||||
|
||||
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 MidiPlaybackApi for PhrasePlayerModel {
|
||||
fn notes_out (&self) -> &Arc<RwLock<[bool; 128]>> {
|
||||
&self.notes_in
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
//#[derive(Debug)]
|
||||
//pub struct MIDIPlayer {
|
||||
///// Global timebase
|
||||
//pub clock: Arc<Clock>,
|
||||
///// Start time and phrase being played
|
||||
//pub play_phrase: Option<(Moment, Option<Arc<RwLock<Phrase>>>)>,
|
||||
///// Start time and next phrase
|
||||
//pub next_phrase: Option<(Moment, Option<Arc<RwLock<Phrase>>>)>,
|
||||
///// 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_inputs: Vec<Port<MidiIn>>,
|
||||
///// Play from current sequence to MIDI ports
|
||||
//pub midi_outputs: Vec<Port<MidiOut>>,
|
||||
///// MIDI output buffer
|
||||
//pub midi_note: Vec<u8>,
|
||||
///// MIDI output buffer
|
||||
//pub midi_chunk: Vec<Vec<Vec<u8>>>,
|
||||
///// Notes currently held at input
|
||||
//pub notes_in: Arc<RwLock<[bool; 128]>>,
|
||||
///// Notes currently held at output
|
||||
//pub notes_out: Arc<RwLock<[bool; 128]>>,
|
||||
//}
|
||||
|
||||
///// 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())?
|
||||
//],
|
||||
//})
|
||||
//}
|
||||
//}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
pub(crate) mod lv2; pub(crate) use lv2::*;
|
||||
use crate::*;
|
||||
|
||||
/// A plugin device.
|
||||
|
|
@ -15,6 +16,26 @@ pub struct Plugin {
|
|||
pub audio_ins: Vec<Port<AudioIn>>,
|
||||
pub audio_outs: Vec<Port<AudioOut>>,
|
||||
}
|
||||
|
||||
/// Supported plugin formats.
|
||||
#[derive(Default)]
|
||||
pub enum PluginKind {
|
||||
#[default] None,
|
||||
LV2(LV2Plugin),
|
||||
VST2 { instance: ::vst::host::PluginInstance },
|
||||
VST3,
|
||||
}
|
||||
|
||||
impl Debug for PluginKind {
|
||||
fn fmt (&self, f: &mut Formatter<'_>) -> std::result::Result<(), Error> {
|
||||
write!(f, "{}", match self {
|
||||
Self::None => "(none)",
|
||||
Self::LV2(_) => "LV2",
|
||||
Self::VST2{..} => "VST2",
|
||||
Self::VST3 => "VST3",
|
||||
})
|
||||
}
|
||||
}
|
||||
impl Plugin {
|
||||
pub fn new_lv2 (
|
||||
jack: &Arc<RwLock<JackClient>>,
|
||||
|
|
@ -62,7 +83,7 @@ impl From<&Arc<RwLock<Plugin>>> for PluginAudio {
|
|||
}
|
||||
}
|
||||
|
||||
audio!(|self: PluginAudio, _, _|{
|
||||
audio!(|self: PluginAudio, client_, _scope|{
|
||||
let state = &mut*self.0.write().unwrap();
|
||||
match state.plugin.as_mut() {
|
||||
Some(PluginKind::LV2(LV2Plugin {
|
||||
|
|
@ -1,6 +1,4 @@
|
|||
use crate::*;
|
||||
use crate::api::ArrangerTrackCommand;
|
||||
use crate::api::ArrangerSceneCommand;
|
||||
/// Root view for standalone `tek_arranger`
|
||||
pub struct ArrangerTui {
|
||||
pub jack: Arc<RwLock<JackClient>>,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
use super::*;
|
||||
use crate::{
|
||||
PhrasePoolCommand as Pool,
|
||||
tui::phrase_rename::PhraseRenameCommand as Rename,
|
||||
tui::phrase_length::PhraseLengthCommand as Length,
|
||||
tui::file_browser::FileBrowserCommand as Browse,
|
||||
api::PhrasePoolCommand as Pool,
|
||||
};
|
||||
use Ordering::Relaxed;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue