mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 04:06:45 +01:00
use Command::delegate, extract SamplerStatus
This commit is contained in:
parent
92459b5f82
commit
42e2ef2a50
4 changed files with 58 additions and 68 deletions
|
|
@ -96,7 +96,7 @@ impl OutputStats {
|
||||||
format!("{:.0}Hz", rate)
|
format!("{:.0}Hz", rate)
|
||||||
},
|
},
|
||||||
buffer_size: format!("{chunk}"),
|
buffer_size: format!("{chunk}"),
|
||||||
latency: format!("{}", chunk as f64 / rate * 1000.),
|
latency: format!("{:.3}ms", chunk as f64 / rate * 1000.),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ render!(Tui: (self: Groovebox) => {
|
||||||
let w = self.size.w();
|
let w = self.size.w();
|
||||||
let phrase_w = if w > 60 { 20 } else if w > 40 { 15 } else { 10 };
|
let phrase_w = if w > 60 { 20 } else if w > 40 { 15 } else { 10 };
|
||||||
let pool_w = if self.pool.visible { phrase_w } else { 0 };
|
let pool_w = if self.pool.visible { phrase_w } else { 0 };
|
||||||
let sampler_w = if self.pool.visible { phrase_w } else { 0 };
|
let sampler_w = if self.pool.visible { phrase_w } else { 4 };
|
||||||
let sample_h = if self.pool.visible { 8 } else { 0 };
|
let sample_h = if self.pool.visible { 8 } else { 0 };
|
||||||
let note_pt = self.editor.note_point();
|
let note_pt = self.editor.note_point();
|
||||||
let color = self.player.play_phrase().as_ref()
|
let color = self.player.play_phrase().as_ref()
|
||||||
|
|
@ -120,35 +120,32 @@ render!(Tui: (self: Groovebox) => {
|
||||||
))),
|
))),
|
||||||
))),
|
))),
|
||||||
Bsp::n(
|
Bsp::n(
|
||||||
Bsp::s(
|
Bsp::a(
|
||||||
Fixed::y(1, self.sampler.mapped[note_pt].as_ref().map(|sample|format!(
|
Outer(Style::default().fg(TuiTheme::g(128))),
|
||||||
"Sample {}-{}",
|
Fill::x(Fixed::y(sample_h, if let Some((_, sample)) = &self.sampler.recording {
|
||||||
sample.read().unwrap().start,
|
SampleViewer(Some(sample.clone()))
|
||||||
sample.read().unwrap().end,
|
} else if let Some(sample) = &self.sampler.mapped[note_pt] {
|
||||||
))),
|
SampleViewer(Some(sample.clone()))
|
||||||
Bsp::a(
|
} else {
|
||||||
Outer(Style::default().fg(TuiTheme::g(128))),
|
SampleViewer(None)
|
||||||
Fill::x(Fixed::y(sample_h, if let Some((_, sample)) = &self.sampler.recording {
|
})),
|
||||||
SampleViewer(Some(sample.clone()))
|
|
||||||
} else if let Some(sample) = &self.sampler.mapped[note_pt] {
|
|
||||||
SampleViewer(Some(sample.clone()))
|
|
||||||
} else {
|
|
||||||
SampleViewer(None)
|
|
||||||
})),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
Bsp::w(
|
Bsp::n(
|
||||||
Fixed::x(pool_w, Align::e(Fill::y(PoolView(&self.pool)))),
|
Bsp::e(
|
||||||
Fill::xy(Bsp::e(
|
Fixed::y(1, SamplerStatus(&self.sampler, note_pt)),
|
||||||
Fixed::x(sampler_w, sampler),
|
MidiEditStatus(&self.editor),
|
||||||
Bsp::s(
|
),
|
||||||
selector,
|
Bsp::w(
|
||||||
Bsp::n(
|
Fixed::x(pool_w, Align::e(Fill::y(PoolView(&self.pool)))),
|
||||||
MidiEditStatus(&self.editor),
|
Fill::xy(Bsp::e(
|
||||||
&self.editor,
|
Fixed::x(sampler_w, sampler),
|
||||||
|
Bsp::s(
|
||||||
|
selector,
|
||||||
|
&self.editor,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
)
|
||||||
))
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
))
|
))
|
||||||
|
|
@ -215,39 +212,37 @@ input_to_command!(GrooveboxCommand: <Tui>|state: Groovebox, input|match input.ev
|
||||||
});
|
});
|
||||||
|
|
||||||
command!(|self: GrooveboxCommand, state: Groovebox|match self {
|
command!(|self: GrooveboxCommand, state: Groovebox|match self {
|
||||||
|
Self::History(delta) => {
|
||||||
|
todo!("undo/redo")
|
||||||
|
},
|
||||||
|
Self::Enqueue(phrase) => {
|
||||||
|
state.player.enqueue_next(phrase.as_ref());
|
||||||
|
None
|
||||||
|
},
|
||||||
Self::Pool(cmd) => {
|
Self::Pool(cmd) => {
|
||||||
let mut default = |cmd: PoolCommand|cmd
|
|
||||||
.execute(&mut state.pool)
|
|
||||||
.map(|x|x.map(Self::Pool));
|
|
||||||
match cmd {
|
match cmd {
|
||||||
// autoselect: automatically load selected phrase in editor
|
// autoselect: automatically load selected phrase in editor
|
||||||
PoolCommand::Select(_) => {
|
PoolCommand::Select(_) => {
|
||||||
let undo = default(cmd)?;
|
let undo = cmd.delegate(&mut state.pool, Self::Pool)?;
|
||||||
state.editor.set_phrase(Some(state.pool.phrase()));
|
state.editor.set_phrase(Some(state.pool.phrase()));
|
||||||
undo
|
undo
|
||||||
},
|
},
|
||||||
// update color in all places simultaneously
|
// update color in all places simultaneously
|
||||||
PoolCommand::Phrase(SetColor(index, _)) => {
|
PoolCommand::Phrase(SetColor(index, _)) => {
|
||||||
let undo = default(cmd)?;
|
let undo = cmd.delegate(&mut state.pool, Self::Pool)?;
|
||||||
state.editor.set_phrase(Some(state.pool.phrase()));
|
state.editor.set_phrase(Some(state.pool.phrase()));
|
||||||
undo
|
undo
|
||||||
},
|
},
|
||||||
_ => default(cmd)?
|
_ => cmd.delegate(&mut state.pool, Self::Pool)?
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Self::Editor(cmd) => {
|
Self::Editor(cmd) => {
|
||||||
let default = ||cmd.execute(&mut state.editor).map(|x|x.map(Self::Editor));
|
cmd.delegate(&mut state.editor, Self::Editor)?
|
||||||
match cmd {
|
|
||||||
_ => default()?
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
Self::Clock(cmd) => cmd.execute(state)?.map(Self::Clock),
|
Self::Clock(cmd) => {
|
||||||
Self::Sampler(cmd) => cmd.execute(&mut state.sampler)?.map(Self::Sampler),
|
cmd.delegate(state, Self::Clock)?
|
||||||
Self::Enqueue(phrase) => {
|
|
||||||
state.player.enqueue_next(phrase.as_ref());
|
|
||||||
None
|
|
||||||
},
|
},
|
||||||
Self::History(delta) => {
|
Self::Sampler(cmd) => {
|
||||||
todo!("undo/redo")
|
cmd.delegate(&mut state.sampler, Self::Sampler)?
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,11 @@
|
||||||
|
mod sample; pub use self::sample::*;
|
||||||
|
mod voice; pub use self::voice::*;
|
||||||
|
mod sampler_tui; pub use self::sampler_tui::*;
|
||||||
|
mod sampler_status; pub use self::sampler_status::*;
|
||||||
|
mod sample_import; pub use self::sample_import::*;
|
||||||
|
mod sample_list; pub use self::sample_list::*;
|
||||||
|
mod sample_viewer; pub use self::sample_viewer::*;
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use KeyCode::Char;
|
use KeyCode::Char;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
|
@ -13,28 +21,6 @@ use symphonia::{
|
||||||
default::get_codecs,
|
default::get_codecs,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod sample;
|
|
||||||
pub(crate) use self::sample::*;
|
|
||||||
pub use self::sample::Sample;
|
|
||||||
|
|
||||||
pub mod voice;
|
|
||||||
pub(crate) use self::voice::*;
|
|
||||||
pub use self::voice::Voice;
|
|
||||||
|
|
||||||
pub mod sampler_tui;
|
|
||||||
pub(crate) use self::sampler_tui::*;
|
|
||||||
pub use self::sampler_tui::SamplerTui;
|
|
||||||
|
|
||||||
pub mod sample_import;
|
|
||||||
pub(crate) use self::sample_import::*;
|
|
||||||
|
|
||||||
pub mod sample_list;
|
|
||||||
pub(crate) use self::sample_list::*;
|
|
||||||
pub use self::sample_list::SampleList;
|
|
||||||
|
|
||||||
pub mod sample_viewer;
|
|
||||||
pub(crate) use self::sample_viewer::*;
|
|
||||||
pub use self::sample_viewer::SampleViewer;
|
|
||||||
|
|
||||||
/// The sampler plugin plays sounds.
|
/// The sampler plugin plays sounds.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
|
||||||
9
src/sampler/sampler_status.rs
Normal file
9
src/sampler/sampler_status.rs
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
use crate::*;
|
||||||
|
|
||||||
|
pub struct SamplerStatus<'a>(pub &'a Sampler, pub usize);
|
||||||
|
|
||||||
|
render!(Tui: (self: SamplerStatus<'a>) => self.0.mapped[self.1].as_ref().map(|sample|format!(
|
||||||
|
"Sample {}-{}",
|
||||||
|
sample.read().unwrap().start,
|
||||||
|
sample.read().unwrap().end,
|
||||||
|
)).unwrap_or_else(||"No sample".to_string()));
|
||||||
Loading…
Add table
Add a link
Reference in a new issue