mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
simplify sample mapping
This commit is contained in:
parent
48f341ba2c
commit
2feb21bd1f
4 changed files with 40 additions and 23 deletions
|
|
@ -61,6 +61,7 @@ render!(<Tui>|self:GrooveboxTui|{
|
|||
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 sampler_w = 11;
|
||||
let note_pt = self.editor.note_point();
|
||||
Fill::wh(lay!([
|
||||
&self.size,
|
||||
Fill::wh(Align::s(Fixed::h(2, GrooveboxStatus::from(self)))),
|
||||
|
|
@ -84,11 +85,14 @@ render!(<Tui>|self:GrooveboxTui|{
|
|||
&format!("L/{:>+9.3}", self.sampler.input_meter[0]),
|
||||
&format!("R/{:>+9.3}", self.sampler.input_meter[1]),
|
||||
Fill::wh(col!(note in (self.editor.note_lo().load(Relaxed)..=self.editor.note_hi()).rev() => {
|
||||
if self.sampler.mapped.contains_key(&u7::from(note as u8)) {
|
||||
todo!()
|
||||
} else {
|
||||
Tui::fg(TuiTheme::g(96), format!("{note:3} (none)"))
|
||||
}
|
||||
Tui::bg(
|
||||
if note == note_pt { TuiTheme::g(64) } else { Color::Reset },
|
||||
if let Some(sample) = &self.sampler.mapped[note] {
|
||||
todo!()
|
||||
} else {
|
||||
Tui::fg(TuiTheme::g(160), format!("{note:3} (none)"))
|
||||
}
|
||||
)
|
||||
})),
|
||||
])), Fill::h(&self.editor))
|
||||
)
|
||||
|
|
@ -188,6 +192,7 @@ command!(|self:GrooveboxCommand,state:GrooveboxTui|match self {
|
|||
}
|
||||
},
|
||||
Self::Clock(cmd) => cmd.execute(state)?.map(Clock),
|
||||
Self::Sampler(cmd) => cmd.execute(&mut state.sampler)?.map(Sampler),
|
||||
Self::Enqueue(phrase) => {
|
||||
state.player.enqueue_next(phrase.as_ref());
|
||||
None
|
||||
|
|
@ -195,7 +200,4 @@ command!(|self:GrooveboxCommand,state:GrooveboxTui|match self {
|
|||
Self::History(delta) => {
|
||||
todo!("undo/redo")
|
||||
},
|
||||
Self::Sampler(command) => {
|
||||
todo!("sampler")
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ pub(crate) use self::sample_import::*;
|
|||
pub struct Sampler {
|
||||
pub jack: Arc<RwLock<JackClient>>,
|
||||
pub name: String,
|
||||
pub mapped: BTreeMap<u7, Arc<RwLock<Sample>>>,
|
||||
pub mapped: [Option<Arc<RwLock<Sample>>>;128],
|
||||
pub unmapped: Vec<Arc<RwLock<Sample>>>,
|
||||
pub voices: Arc<RwLock<Vec<Voice>>>,
|
||||
pub midi_in: Port<MidiIn>,
|
||||
|
|
@ -63,7 +63,7 @@ impl Sampler {
|
|||
],
|
||||
jack: jack.clone(),
|
||||
name: name.into(),
|
||||
mapped: BTreeMap::new(),
|
||||
mapped: [const { None };128],
|
||||
unmapped: vec![],
|
||||
voices: Arc::new(RwLock::new(vec![])),
|
||||
buffer: vec![vec![0.0;16384];2],
|
||||
|
|
@ -86,9 +86,9 @@ pub struct SamplerTui {
|
|||
impl SamplerTui {
|
||||
/// Immutable reference to sample at cursor.
|
||||
pub fn sample (&self) -> Option<&Arc<RwLock<Sample>>> {
|
||||
for (i, sample) in self.state.mapped.values().enumerate() {
|
||||
for (i, sample) in self.state.mapped.iter().enumerate() {
|
||||
if i == self.cursor.0 {
|
||||
return Some(sample)
|
||||
return sample.as_ref()
|
||||
}
|
||||
}
|
||||
for (i, sample) in self.state.unmapped.iter().enumerate() {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ impl Sampler {
|
|||
if let LiveEvent::Midi {
|
||||
message: MidiMessage::NoteOn { ref key, ref vel }, ..
|
||||
} = LiveEvent::parse(bytes).unwrap() {
|
||||
if let Some(sample) = mapped.get(key) {
|
||||
if let Some(ref sample) = mapped[key.as_int() as usize] {
|
||||
voices.write().unwrap().push(Sample::play(sample, time as usize, vel));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +1,24 @@
|
|||
use crate::*;
|
||||
use KeyCode::Char;
|
||||
|
||||
handle!(<Tui>|self:SamplerTui,input|SamplerCommand::execute_with_state(self, input));
|
||||
handle!(<Tui>|self: SamplerTui, input|SamplerTuiCommand::execute_with_state(self, input));
|
||||
|
||||
pub enum SamplerCommand {
|
||||
pub enum SamplerTuiCommand {
|
||||
Import(FileBrowserCommand),
|
||||
SelectNote(usize),
|
||||
SelectField(usize),
|
||||
SetName(String),
|
||||
SetNote(u7, Option<Arc<RwLock<Sample>>>),
|
||||
Sample(SamplerCommand),
|
||||
}
|
||||
|
||||
pub enum SamplerCommand {
|
||||
Record(u7),
|
||||
SetSample(u7, Option<Arc<RwLock<Sample>>>),
|
||||
SetGain(f32),
|
||||
NoteOn(u7, u7),
|
||||
NoteOff(u7),
|
||||
Record(u7),
|
||||
}
|
||||
|
||||
input_to_command!(SamplerCommand: <Tui>|state: SamplerTui, input|match state.mode {
|
||||
input_to_command!(SamplerTuiCommand: <Tui>|state: SamplerTui, input|match state.mode {
|
||||
Some(SamplerMode::Import(..)) => Self::Import(
|
||||
FileBrowserCommand::input_to_command(state, input)?
|
||||
),
|
||||
|
|
@ -51,7 +54,8 @@ input_to_command!(SamplerCommand: <Tui>|state: SamplerTui, input|match state.mod
|
|||
//}
|
||||
//}
|
||||
});
|
||||
command!(|self:SamplerCommand,state:SamplerTui|match self {
|
||||
|
||||
command!(|self: SamplerTuiCommand, state: SamplerTui|match self {
|
||||
Self::Import(FileBrowserCommand::Begin) => {
|
||||
let voices = &state.state.voices;
|
||||
let sample = Arc::new(RwLock::new(Sample::new("", 0, 0, vec![])));
|
||||
|
|
@ -63,10 +67,21 @@ command!(|self:SamplerCommand,state:SamplerTui|match self {
|
|||
state.set_note_point(index);
|
||||
Some(Self::SelectNote(old))
|
||||
},
|
||||
Self::Sample(cmd) => cmd.execute(&mut state.state)?.map(Self::Sample),
|
||||
_ => todo!()
|
||||
});
|
||||
|
||||
command!(|self: SamplerCommand, state: Sampler|match self {
|
||||
Self::SetSample(index, sample) => {
|
||||
let i = index.as_int() as usize;
|
||||
let old = state.mapped[i].clone();
|
||||
state.mapped[i] = sample;
|
||||
Some(Self::SetSample(index, old))
|
||||
},
|
||||
Self::Record(index) => {
|
||||
let old = state.state.mapped.get(&index).cloned();
|
||||
|
||||
Some(Self::SetNote(index, old))
|
||||
let i = index.as_int() as usize;
|
||||
let old = state.mapped[i].clone();
|
||||
Some(Self::SetSample(index, old))
|
||||
},
|
||||
_ => todo!()
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue