oh no, begin to implement sampling

This commit is contained in:
🪞👃🪞 2024-12-28 16:50:35 +01:00
parent bcdb5f51f5
commit 48f341ba2c
5 changed files with 78 additions and 53 deletions

View file

@ -60,6 +60,15 @@ arranger-release-ext:
groovebox:
reset
cargo run --bin tek_groovebox
groovebox-ext:
reset
cargo run --bin tek_groovebox -- -n tek \
-i "Midi-Bridge:nanoKEY Studio 1:(capture_0) nanoKEY Studio nanoKEY Studio _" \
-o "Midi-Bridge:Komplete Audio 6 0:(playback_0) Komplete Audio 6 MIDI 1" \
-l "Komplete Audio 6 Pro:capture_AUX1" \
-r "Komplete Audio 6 Pro:capture_AUX1" \
-L "Komplete Audio 6 Pro:playback_AUX1" \
-R "Komplete Audio 6 Pro:playback_AUX1"
groovebox-release:
reset
cargo run --release --bin tek_groovebox

View file

@ -60,7 +60,7 @@ render!(<Tui>|self:GrooveboxTui|{
let w = self.size.w();
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 = 24;
let sampler_w = 11;
Fill::wh(lay!([
&self.size,
Fill::wh(Align::s(Fixed::h(2, GrooveboxStatus::from(self)))),
@ -80,11 +80,17 @@ render!(<Tui>|self:GrooveboxTui|{
MidiEditStatus(&self.editor),
Tui::split_w(false, pool_w,
Tui::pull_y(1, Fill::h(Align::e(PoolView(&self.pool)))),
col!([
&format!("L/{:>+10.3}", self.sampler.input_meter[0]),
&format!("R/{:>+10.3}", self.sampler.input_meter[1]),
Fill::wh(&self.editor)
])
Tui::split_e(false, sampler_w, Fill::wh(col!([
&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)"))
}
})),
])), Fill::h(&self.editor))
)
),
]),
@ -126,6 +132,10 @@ input_to_command!(GrooveboxCommand: <Tui>|state: GrooveboxTui, input|match input
// 0: Enqueue phrase 0 (stop all)
key_pat!(Char('0')) => Enqueue(Some(state.pool.phrases()[0].clone())),
key_pat!(Shift-Char('R')) => Sampler(
SamplerCommand::Record(u7::from(state.editor.note_point() as u8))
),
// e: Toggle between editing currently playing or other phrase
key_pat!(Char('e')) => if let Some((_, Some(playing))) = state.player.play_phrase() {
let editing = state.editor.phrase().as_ref().map(|p|p.read().unwrap().clone());

View file

@ -8,10 +8,11 @@ pub enum SamplerCommand {
SelectNote(usize),
SelectField(usize),
SetName(String),
SetNote(u7, Arc<RwLock<Sample>>),
SetNote(u7, Option<Arc<RwLock<Sample>>>),
SetGain(f32),
NoteOn(u7, u7),
NoteOff(u7)
NoteOff(u7),
Record(u7),
}
input_to_command!(SamplerCommand: <Tui>|state: SamplerTui, input|match state.mode {
@ -62,5 +63,10 @@ command!(|self:SamplerCommand,state:SamplerTui|match self {
state.set_note_point(index);
Some(Self::SelectNote(old))
},
Self::Record(index) => {
let old = state.state.mapped.get(&index).cloned();
Some(Self::SetNote(index, old))
},
_ => todo!()
});

View file

@ -189,3 +189,48 @@ impl<N: Coordinate> Area<N> for [N;4] {
#[inline] fn w (&self) -> N { self[2] }
#[inline] fn h (&self) -> N { self[3] }
}
#[macro_export] macro_rules! col {
([$($expr:expr),* $(,)?]) => {
Stack::down(move|add|{ $(add(&$expr)?;)* Ok(()) })
};
(![$($expr:expr),* $(,)?]) => {
Stack::down(|add|{ $(add(&$expr)?;)* Ok(()) })
};
($expr:expr) => {
Stack::down($expr)
};
($pat:pat in $collection:expr => $item:expr) => {
Stack::down(move|add|{ for $pat in $collection { add(&$item)?; } Ok(()) })
};
}
#[macro_export] macro_rules! col_up {
([$($expr:expr),* $(,)?]) => {
Stack::up(move|add|{ $(add(&$expr)?;)* Ok(()) })
};
(![$($expr:expr),* $(,)?]) => {
Stack::up(|add|{ $(add(&$expr)?;)* Ok(()) })
};
($expr:expr) => {
Stack::up(expr)
};
($pat:pat in $collection:expr => $item:expr) => {
Stack::up(move |add|{ for $pat in $collection { add(&$item)?; } Ok(()) })
};
}
#[macro_export] macro_rules! row {
([$($expr:expr),* $(,)?]) => {
Stack::right(move|add|{ $(add(&$expr)?;)* Ok(()) })
};
(![$($expr:expr),* $(,)?]) => {
Stack::right(|add|{ $(add(&$expr)?;)* Ok(()) })
};
($expr:expr) => {
Stack::right($expr)
};
($pat:pat in $collection:expr => $item:expr) => {
Stack::right(move|add|{ for $pat in $collection { add(&$item)?; } Ok(()) })
};
}

View file

@ -1,51 +1,6 @@
use crate::*;
use Direction::*;
#[macro_export] macro_rules! col {
([$($expr:expr),* $(,)?]) => {
Stack::down(move|add|{ $(add(&$expr)?;)* Ok(()) })
};
(![$($expr:expr),* $(,)?]) => {
Stack::down(|add|{ $(add(&$expr)?;)* Ok(()) })
};
($expr:expr) => {
Stack::down($expr)
};
($pat:pat in $collection:expr => $item:expr) => {
Stack::down(move|add|{ for $pat in $collection { add(&$item)?; } Ok(()) })
};
}
#[macro_export] macro_rules! col_up {
([$($expr:expr),* $(,)?]) => {
Stack::up(move|add|{ $(add(&$expr)?;)* Ok(()) })
};
(![$($expr:expr),* $(,)?]) => {
Stack::up(|add|{ $(add(&$expr)?;)* Ok(()) })
};
($expr:expr) => {
Stack::up(expr)
};
($pat:pat in $collection:expr => $item:expr) => {
Stack::up(move |add|{ for $pat in $collection { add(&$item)?; } Ok(()) })
};
}
#[macro_export] macro_rules! row {
([$($expr:expr),* $(,)?]) => {
Stack::right(move|add|{ $(add(&$expr)?;)* Ok(()) })
};
(![$($expr:expr),* $(,)?]) => {
Stack::right(|add|{ $(add(&$expr)?;)* Ok(()) })
};
($expr:expr) => {
Stack::right($expr)
};
($pat:pat in $collection:expr => $item:expr) => {
Stack::right(move|add|{ for $pat in $collection { add(&$item)?; } Ok(()) })
};
}
pub struct Stack<
E: Engine,
F: Send + Sync + Fn(&mut dyn FnMut(&dyn Render<E>)->Usually<()>)->Usually<()>