mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 12:16:42 +01:00
change Device from trait to enum
This commit is contained in:
parent
866d88c8ec
commit
1cc3a58826
8 changed files with 150 additions and 92 deletions
|
|
@ -15,6 +15,8 @@ view!(TuiOut: |self: Tek| self.size.of(View(self, self.view)); {
|
||||||
().boxed(),//self.view_sample(self.is_editing()).boxed(),
|
().boxed(),//self.view_sample(self.is_editing()).boxed(),
|
||||||
":sampler" =>
|
":sampler" =>
|
||||||
().boxed(),//self.view_sampler(self.is_editing(), &self.editor).boxed(),
|
().boxed(),//self.view_sampler(self.is_editing(), &self.editor).boxed(),
|
||||||
|
":samples-grid" =>
|
||||||
|
self.tracks[0].sampler(0).map(|s|s.view_grid()).boxed(),
|
||||||
":status" =>
|
":status" =>
|
||||||
self.view_status().boxed(),
|
self.view_status().boxed(),
|
||||||
":pool" => self.pool.as_ref()
|
":pool" => self.pool.as_ref()
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
pub trait Device: Send + Sync + std::fmt::Debug {
|
|
||||||
fn boxed <'a> (self) -> Box<dyn Device + 'a> where Self: Sized + 'a { Box::new(self) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Device for Sampler {}
|
|
||||||
|
|
||||||
#[cfg(feature = "host")]
|
|
||||||
impl Device for Plugin {}
|
|
||||||
|
|
|
||||||
|
|
@ -247,60 +247,6 @@ impl HasSelection for Tek {
|
||||||
fn selected_mut (&mut self) -> &mut Selection { &mut self.selected }
|
fn selected_mut (&mut self) -> &mut Selection { &mut self.selected }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait HasTracks: HasSelection + HasClock + HasJack + HasEditor + Send + Sync {
|
|
||||||
fn midi_ins (&self) -> &Vec<JackMidiIn>;
|
|
||||||
fn midi_outs (&self) -> &Vec<JackMidiOut>;
|
|
||||||
fn tracks (&self) -> &Vec<Track>;
|
|
||||||
fn tracks_mut (&mut self) -> &mut Vec<Track>;
|
|
||||||
fn track_longest (&self) -> usize {
|
|
||||||
self.tracks().iter().map(|s|s.name.len()).fold(0, usize::max)
|
|
||||||
}
|
|
||||||
const WIDTH_OFFSET: usize = 1;
|
|
||||||
fn track_next_name (&self) -> Arc<str> {
|
|
||||||
format!("Track{:02}", self.tracks().len() + 1).into()
|
|
||||||
}
|
|
||||||
fn track (&self) -> Option<&Track> {
|
|
||||||
self.selected().track().and_then(|s|self.tracks().get(s))
|
|
||||||
}
|
|
||||||
fn track_mut (&mut self) -> Option<&mut Track> {
|
|
||||||
self.selected().track().and_then(|s|self.tracks_mut().get_mut(s))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Default)] pub struct Track {
|
|
||||||
/// Name of track
|
|
||||||
pub name: Arc<str>,
|
|
||||||
/// Preferred width of track column
|
|
||||||
pub width: usize,
|
|
||||||
/// Identifying color of track
|
|
||||||
pub color: ItemPalette,
|
|
||||||
/// MIDI player state
|
|
||||||
pub player: MidiPlayer,
|
|
||||||
/// Device chain
|
|
||||||
pub devices: Vec<Box<dyn Device>>,
|
|
||||||
/// Inputs of 1st device
|
|
||||||
pub audio_ins: Vec<JackAudioIn>,
|
|
||||||
/// Outputs of last device
|
|
||||||
pub audio_outs: Vec<JackAudioOut>,
|
|
||||||
}
|
|
||||||
|
|
||||||
has_clock!(|self: Track|self.player.clock);
|
|
||||||
|
|
||||||
has_player!(|self: Track|self.player);
|
|
||||||
|
|
||||||
impl Track {
|
|
||||||
const MIN_WIDTH: usize = 9;
|
|
||||||
fn width_inc (&mut self) { self.width += 1; }
|
|
||||||
fn width_dec (&mut self) { if self.width > Track::MIN_WIDTH { self.width -= 1; } }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HasTracks for Tek {
|
|
||||||
fn midi_ins (&self) -> &Vec<JackMidiIn> { &self.midi_ins }
|
|
||||||
fn midi_outs (&self) -> &Vec<JackMidiOut> { &self.midi_outs }
|
|
||||||
fn tracks (&self) -> &Vec<Track> { &self.tracks }
|
|
||||||
fn tracks_mut (&mut self) -> &mut Vec<Track> { &mut self.tracks }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait HasScenes: HasSelection + HasEditor + Send + Sync {
|
pub trait HasScenes: HasSelection + HasEditor + Send + Sync {
|
||||||
fn scenes (&self) -> &Vec<Scene>;
|
fn scenes (&self) -> &Vec<Scene>;
|
||||||
fn scenes_mut (&mut self) -> &mut Vec<Scene>;
|
fn scenes_mut (&mut self) -> &mut Vec<Scene>;
|
||||||
|
|
@ -361,3 +307,97 @@ impl HasScenes for Tek {
|
||||||
fn scenes (&self) -> &Vec<Scene> { &self.scenes }
|
fn scenes (&self) -> &Vec<Scene> { &self.scenes }
|
||||||
fn scenes_mut (&mut self) -> &mut Vec<Scene> { &mut self.scenes }
|
fn scenes_mut (&mut self) -> &mut Vec<Scene> { &mut self.scenes }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait HasTracks: HasSelection + HasClock + HasJack + HasEditor + Send + Sync {
|
||||||
|
fn midi_ins (&self) -> &Vec<JackMidiIn>;
|
||||||
|
fn midi_outs (&self) -> &Vec<JackMidiOut>;
|
||||||
|
fn tracks (&self) -> &Vec<Track>;
|
||||||
|
fn tracks_mut (&mut self) -> &mut Vec<Track>;
|
||||||
|
fn track_longest (&self) -> usize {
|
||||||
|
self.tracks().iter().map(|s|s.name.len()).fold(0, usize::max)
|
||||||
|
}
|
||||||
|
const WIDTH_OFFSET: usize = 1;
|
||||||
|
fn track_next_name (&self) -> Arc<str> {
|
||||||
|
format!("Track{:02}", self.tracks().len() + 1).into()
|
||||||
|
}
|
||||||
|
fn track (&self) -> Option<&Track> {
|
||||||
|
self.selected().track().and_then(|s|self.tracks().get(s))
|
||||||
|
}
|
||||||
|
fn track_mut (&mut self) -> Option<&mut Track> {
|
||||||
|
self.selected().track().and_then(|s|self.tracks_mut().get_mut(s))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)] pub struct Track {
|
||||||
|
/// Name of track
|
||||||
|
pub name: Arc<str>,
|
||||||
|
/// Preferred width of track column
|
||||||
|
pub width: usize,
|
||||||
|
/// Identifying color of track
|
||||||
|
pub color: ItemPalette,
|
||||||
|
/// MIDI player state
|
||||||
|
pub player: MidiPlayer,
|
||||||
|
/// Device chain
|
||||||
|
pub devices: Vec<Device>,
|
||||||
|
/// Inputs of 1st device
|
||||||
|
pub audio_ins: Vec<JackAudioIn>,
|
||||||
|
/// Outputs of last device
|
||||||
|
pub audio_outs: Vec<JackAudioOut>,
|
||||||
|
}
|
||||||
|
|
||||||
|
has_clock!(|self: Track|self.player.clock);
|
||||||
|
|
||||||
|
has_player!(|self: Track|self.player);
|
||||||
|
|
||||||
|
impl Track {
|
||||||
|
pub const MIN_WIDTH: usize = 9;
|
||||||
|
pub fn width_inc (&mut self) {
|
||||||
|
self.width += 1;
|
||||||
|
}
|
||||||
|
pub fn width_dec (&mut self) {
|
||||||
|
if self.width > Track::MIN_WIDTH {
|
||||||
|
self.width -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn sequencer (&self, mut nth: usize) -> Option<&MidiPlayer> {
|
||||||
|
for device in self.devices.iter() {
|
||||||
|
match device {
|
||||||
|
Device::Sequencer(s) => if nth == 0 {
|
||||||
|
return Some(s);
|
||||||
|
} else {
|
||||||
|
nth -= 1;
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
pub fn sampler (&self, mut nth: usize) -> Option<&Sampler> {
|
||||||
|
for device in self.devices.iter() {
|
||||||
|
match device {
|
||||||
|
Device::Sampler(s) => if nth == 0 {
|
||||||
|
return Some(s);
|
||||||
|
} else {
|
||||||
|
nth -= 1;
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HasTracks for Tek {
|
||||||
|
fn midi_ins (&self) -> &Vec<JackMidiIn> { &self.midi_ins }
|
||||||
|
fn midi_outs (&self) -> &Vec<JackMidiOut> { &self.midi_outs }
|
||||||
|
fn tracks (&self) -> &Vec<Track> { &self.tracks }
|
||||||
|
fn tracks_mut (&mut self) -> &mut Vec<Track> { &mut self.tracks }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Device {
|
||||||
|
Sequencer(MidiPlayer),
|
||||||
|
Sampler(Sampler),
|
||||||
|
#[cfg(feature="host")]
|
||||||
|
Plugin(Plugin),
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ edition = { workspace = true }
|
||||||
version = { workspace = true }
|
version = { workspace = true }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tek = { workspace = true }
|
tek = { workspace = true }
|
||||||
clap = { workspace = true }
|
clap = { workspace = true }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
||||||
|
|
@ -128,19 +128,51 @@ impl Cli {
|
||||||
keys_scene: SourceIter(include_str!("./edn/arranger_keys_scene.edn")),
|
keys_scene: SourceIter(include_str!("./edn/arranger_keys_scene.edn")),
|
||||||
keys_mix: SourceIter(include_str!("./edn/arranger_keys_mix.edn")),
|
keys_mix: SourceIter(include_str!("./edn/arranger_keys_mix.edn")),
|
||||||
tracks: match mode {
|
tracks: match mode {
|
||||||
Mode::Sequencer => vec![Track::default()],
|
|
||||||
Mode::Groovebox | Mode::Sampler => vec![Track {
|
Mode::Sequencer => vec![
|
||||||
devices: vec![
|
Track {
|
||||||
Device::boxed(Sampler::new(
|
devices: vec![
|
||||||
jack,
|
Device::Sequencer(
|
||||||
&"sampler",
|
MidiPlayer::default()
|
||||||
midi_froms.as_slice(),
|
),
|
||||||
audio_froms,
|
],
|
||||||
audio_tos
|
..Track::default()
|
||||||
)?)
|
},
|
||||||
],
|
],
|
||||||
..Track::default()
|
|
||||||
}],
|
Mode::Groovebox => vec![
|
||||||
|
Track {
|
||||||
|
devices: vec![
|
||||||
|
Device::Sequencer(
|
||||||
|
MidiPlayer::default()
|
||||||
|
),
|
||||||
|
Device::Sampler(Sampler::new(
|
||||||
|
jack,
|
||||||
|
&"sampler",
|
||||||
|
midi_froms.as_slice(),
|
||||||
|
audio_froms,
|
||||||
|
audio_tos
|
||||||
|
)?)
|
||||||
|
],
|
||||||
|
..Track::default()
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
Mode::Sampler => vec![
|
||||||
|
Track {
|
||||||
|
devices: vec![
|
||||||
|
Device::Sampler(Sampler::new(
|
||||||
|
jack,
|
||||||
|
&"sampler",
|
||||||
|
midi_froms.as_slice(),
|
||||||
|
audio_froms,
|
||||||
|
audio_tos
|
||||||
|
)?)
|
||||||
|
],
|
||||||
|
..Track::default()
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
_ => vec![]
|
_ => vec![]
|
||||||
},
|
},
|
||||||
scenes,
|
scenes,
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,8 @@ pub trait MidiPlaybackApi: HasPlayClip + HasClock + HasMidiOuts {
|
||||||
fn clear (
|
fn clear (
|
||||||
&mut self, scope: &ProcessScope, out: &mut [Vec<Vec<u8>>], reset: bool
|
&mut self, scope: &ProcessScope, out: &mut [Vec<Vec<u8>>], reset: bool
|
||||||
) {
|
) {
|
||||||
for frame in &mut out[0..scope.n_frames() as usize] {
|
let n_frames = (scope.n_frames() as usize).min(out.len());
|
||||||
|
for frame in &mut out[0..n_frames] {
|
||||||
frame.clear();
|
frame.clear();
|
||||||
}
|
}
|
||||||
if reset {
|
if reset {
|
||||||
|
|
|
||||||
|
|
@ -6,20 +6,6 @@ provide!(f32: |self: Sampler| {});
|
||||||
provide!(u7: |self: Sampler| {});
|
provide!(u7: |self: Sampler| {});
|
||||||
provide!(usize: |self: Sampler| {});
|
provide!(usize: |self: Sampler| {});
|
||||||
|
|
||||||
//handle!(TuiIn: |self: Sampler, input|SamplerCommand::execute_with_state(self, input.event()));
|
|
||||||
//input_to_command!(SamplerCommand: |state: Sampler, input: Event|match state.mode{
|
|
||||||
//Some(SamplerMode::Import(..)) => Self::Import(
|
|
||||||
//FileBrowserCommand::input_to_command(state, input)?
|
|
||||||
//),
|
|
||||||
//_ => match input {
|
|
||||||
//// load sample
|
|
||||||
//kpat!(Shift-Char('L')) => Self::Import(FileBrowserCommand::Begin),
|
|
||||||
//kpat!(KeyCode::Up) => Self::Select(state.note_pos().overflowing_add(1).0.min(127)),
|
|
||||||
//kpat!(KeyCode::Down) => Self::Select(state.note_pos().overflowing_sub(1).0.min(127)),
|
|
||||||
//_ => return None
|
|
||||||
//}
|
|
||||||
//});
|
|
||||||
|
|
||||||
defcom! { |self, state: Sampler|
|
defcom! { |self, state: Sampler|
|
||||||
|
|
||||||
SamplerCommand {
|
SamplerCommand {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,11 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
|
impl Sampler {
|
||||||
|
pub fn view_grid (&self) -> impl Content<TuiOut> {
|
||||||
|
"sampler grid view"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
content!(TuiOut: |self: Sampler| {
|
content!(TuiOut: |self: Sampler| {
|
||||||
let keys_width = 5;
|
let keys_width = 5;
|
||||||
let keys = move||"";//SamplerKeys(self);
|
let keys = move||"";//SamplerKeys(self);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue