mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 03:36:41 +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(),
|
||||
":sampler" =>
|
||||
().boxed(),//self.view_sampler(self.is_editing(), &self.editor).boxed(),
|
||||
":samples-grid" =>
|
||||
self.tracks[0].sampler(0).map(|s|s.view_grid()).boxed(),
|
||||
":status" =>
|
||||
self.view_status().boxed(),
|
||||
":pool" => self.pool.as_ref()
|
||||
|
|
|
|||
|
|
@ -1,10 +1 @@
|
|||
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 }
|
||||
}
|
||||
|
||||
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 {
|
||||
fn scenes (&self) -> &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_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 }
|
||||
|
||||
[dependencies]
|
||||
tek = { workspace = true }
|
||||
tek = { workspace = true }
|
||||
clap = { workspace = true }
|
||||
|
||||
[[bin]]
|
||||
|
|
|
|||
|
|
@ -128,19 +128,51 @@ impl Cli {
|
|||
keys_scene: SourceIter(include_str!("./edn/arranger_keys_scene.edn")),
|
||||
keys_mix: SourceIter(include_str!("./edn/arranger_keys_mix.edn")),
|
||||
tracks: match mode {
|
||||
Mode::Sequencer => vec![Track::default()],
|
||||
Mode::Groovebox | Mode::Sampler => vec![Track {
|
||||
devices: vec![
|
||||
Device::boxed(Sampler::new(
|
||||
jack,
|
||||
&"sampler",
|
||||
midi_froms.as_slice(),
|
||||
audio_froms,
|
||||
audio_tos
|
||||
)?)
|
||||
],
|
||||
..Track::default()
|
||||
}],
|
||||
|
||||
Mode::Sequencer => vec![
|
||||
Track {
|
||||
devices: vec![
|
||||
Device::Sequencer(
|
||||
MidiPlayer::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![]
|
||||
},
|
||||
scenes,
|
||||
|
|
|
|||
|
|
@ -20,7 +20,8 @@ pub trait MidiPlaybackApi: HasPlayClip + HasClock + HasMidiOuts {
|
|||
fn clear (
|
||||
&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();
|
||||
}
|
||||
if reset {
|
||||
|
|
|
|||
|
|
@ -6,20 +6,6 @@ provide!(f32: |self: Sampler| {});
|
|||
provide!(u7: |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|
|
||||
|
||||
SamplerCommand {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,11 @@
|
|||
use crate::*;
|
||||
|
||||
impl Sampler {
|
||||
pub fn view_grid (&self) -> impl Content<TuiOut> {
|
||||
"sampler grid view"
|
||||
}
|
||||
}
|
||||
|
||||
content!(TuiOut: |self: Sampler| {
|
||||
let keys_width = 5;
|
||||
let keys = move||"";//SamplerKeys(self);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue