mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 04:06:45 +01:00
launch clips
This commit is contained in:
parent
8a2693c297
commit
a4061535b5
7 changed files with 117 additions and 28 deletions
|
|
@ -134,6 +134,18 @@ pub trait Render {
|
|||
fn render (&self, _b: &mut Buffer, _a: Rect) -> Usually<Rect> {
|
||||
Ok(Rect { x: 0, y: 0, width: 0, height: 0 })
|
||||
}
|
||||
fn min_width (&self) -> u16 {
|
||||
0
|
||||
}
|
||||
fn max_width (&self) -> u16 {
|
||||
u16::MAX
|
||||
}
|
||||
fn min_height (&self) -> u16 {
|
||||
0
|
||||
}
|
||||
fn max_height (&self) -> u16 {
|
||||
u16::MAX
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for Box<dyn Device> {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ enum PluginKind {
|
|||
LV2 {
|
||||
world: ::livi::World,
|
||||
features: Arc<::livi::Features>,
|
||||
portList: Vec<::livi::Port>,
|
||||
port_list: Vec<::livi::Port>,
|
||||
instance: ::livi::Instance,
|
||||
},
|
||||
VST2 {
|
||||
|
|
@ -105,7 +105,7 @@ impl Plugin {
|
|||
inputs.push(atom);
|
||||
}
|
||||
let mut outputs = vec![];
|
||||
for port in self.midi_outs.iter() {
|
||||
for _ in self.midi_outs.iter() {
|
||||
outputs.push(::livi::event::LV2AtomSequence::new(
|
||||
&features,
|
||||
scope.n_frames() as usize
|
||||
|
|
@ -171,12 +171,12 @@ pub fn render (state: &Plugin, buf: &mut Buffer, area: Rect)
|
|||
let Rect { x, y, height, .. } = area;
|
||||
let mut width = 40u16;
|
||||
match &state.plugin {
|
||||
Some(PluginKind::LV2 { portList, instance, .. }) => {
|
||||
Some(PluginKind::LV2 { port_list, instance, .. }) => {
|
||||
let start = state.selected.saturating_sub((height as usize / 2).saturating_sub(1));
|
||||
let end = start + height as usize - 2;
|
||||
//draw_box(buf, Rect { x, y, width, height });
|
||||
for i in start..end {
|
||||
if let Some(port) = portList.get(i) {
|
||||
if let Some(port) = port_list.get(i) {
|
||||
let value = if let Some(value) = instance.control_input(port.index) {
|
||||
value
|
||||
} else {
|
||||
|
|
@ -218,7 +218,7 @@ pub fn handle (s: &mut Plugin, event: &AppEvent) -> Usually<bool> {
|
|||
s.selected = s.selected - 1
|
||||
} else {
|
||||
s.selected = match &s.plugin {
|
||||
Some(PluginKind::LV2 { portList, .. }) => portList.len() - 1,
|
||||
Some(PluginKind::LV2 { port_list, .. }) => port_list.len() - 1,
|
||||
_ => 0
|
||||
}
|
||||
}
|
||||
|
|
@ -229,8 +229,8 @@ pub fn handle (s: &mut Plugin, event: &AppEvent) -> Usually<bool> {
|
|||
|s: &mut Plugin|{
|
||||
s.selected = s.selected + 1;
|
||||
match &s.plugin {
|
||||
Some(PluginKind::LV2 { portList, .. }) => {
|
||||
if s.selected >= portList.len() {
|
||||
Some(PluginKind::LV2 { port_list, .. }) => {
|
||||
if s.selected >= port_list.len() {
|
||||
s.selected = 0;
|
||||
}
|
||||
},
|
||||
|
|
@ -242,8 +242,8 @@ pub fn handle (s: &mut Plugin, event: &AppEvent) -> Usually<bool> {
|
|||
[Char(','), NONE, "decrement", "decrement value",
|
||||
|s: &mut Plugin|{
|
||||
match s.plugin.as_mut() {
|
||||
Some(PluginKind::LV2 { portList, ref mut instance, .. }) => {
|
||||
let index = portList[s.selected].index;
|
||||
Some(PluginKind::LV2 { port_list, ref mut instance, .. }) => {
|
||||
let index = port_list[s.selected].index;
|
||||
if let Some(value) = instance.control_input(index) {
|
||||
instance.set_control_input(index, value - 0.01);
|
||||
}
|
||||
|
|
@ -256,8 +256,8 @@ pub fn handle (s: &mut Plugin, event: &AppEvent) -> Usually<bool> {
|
|||
[Char('.'), NONE, "increment", "increment value",
|
||||
|s: &mut Plugin|{
|
||||
match s.plugin.as_mut() {
|
||||
Some(PluginKind::LV2 { portList, ref mut instance, .. }) => {
|
||||
let index = portList[s.selected].index;
|
||||
Some(PluginKind::LV2 { port_list, ref mut instance, .. }) => {
|
||||
let index = port_list[s.selected].index;
|
||||
if let Some(value) = instance.control_input(index) {
|
||||
instance.set_control_input(index, value + 0.01);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,15 +13,15 @@ pub fn plug (uri: &str) -> Usually<PluginKind> {
|
|||
break
|
||||
}
|
||||
let plugin = plugin.unwrap();
|
||||
let mut portList = vec![];
|
||||
let mut port_list = vec![];
|
||||
for port in plugin.ports() {
|
||||
portList.push(port);
|
||||
port_list.push(port);
|
||||
}
|
||||
Ok(PluginKind::LV2 {
|
||||
instance: unsafe {
|
||||
plugin.instantiate(features.clone(), 48000.0).expect("boop")
|
||||
},
|
||||
portList,
|
||||
port_list,
|
||||
features,
|
||||
world,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -12,4 +12,3 @@ fn set_vst_plugin (host: &Arc<Mutex<Plugin>>, path: &str) -> Usually<PluginKind>
|
|||
instance: loader.instance()?
|
||||
})
|
||||
}
|
||||
//"file:///nix/store/ij3sz7nqg5l7v2dygdvzy3w6cj62bd6r-helm-0.9.0/lib/lxvst/helm.so"
|
||||
|
|
|
|||
|
|
@ -152,9 +152,10 @@ impl PortList for Sampler {
|
|||
pub fn render (state: &Sampler, buf: &mut Buffer, Rect { x, y, height, .. }: Rect)
|
||||
-> Usually<Rect>
|
||||
{
|
||||
let width = 40;
|
||||
let style = Style::default().gray();
|
||||
format!(" {} ({})", state.name, state.voices.len()).blit(buf, x+1, y, Some(style.white().bold().not_dim()));
|
||||
let title = format!(" {} ({})", state.name, state.voices.len());
|
||||
title.blit(buf, x+1, y, Some(style.white().bold().not_dim()));
|
||||
let mut width = title.len() + 2;
|
||||
for (i, (note, sample)) in state.samples.iter().enumerate() {
|
||||
let style = if i == state.cursor.0 {
|
||||
Style::default().green()
|
||||
|
|
@ -169,12 +170,14 @@ pub fn render (state: &Sampler, buf: &mut Buffer, Rect { x, y, height, .. }: Rec
|
|||
if i as usize == state.cursor.0 {
|
||||
"⯈".blit(buf, x+1, y1, Some(style.bold()));
|
||||
}
|
||||
let label1 = format!("{note:3} {:10}", sample.name);
|
||||
let label2 = format!("{:>7} {:>7}", sample.start, sample.end);
|
||||
let label1 = format!("{note:3} {:8}", sample.name);
|
||||
let label2 = format!("{:>6} {:>6}", sample.start, sample.end);
|
||||
label1.blit(buf, x+2, y1, Some(style.bold()));
|
||||
label2.blit(buf, x+3+label1.len()as u16, y1, Some(style));
|
||||
width = width.max(label1.len() + label2.len() + 4);
|
||||
}
|
||||
Ok(Rect { x, y, width, height })
|
||||
let height = ((1 + state.samples.len()) as u16).min(height);
|
||||
Ok(Rect { x, y, width: width as u16, height })
|
||||
}
|
||||
|
||||
//fn render_table (
|
||||
|
|
@ -225,9 +228,10 @@ pub fn handle (state: &mut Sampler, event: &AppEvent) -> Usually<bool> {
|
|||
Ok(handle_keymap(state, event, KEYMAP)?)
|
||||
}
|
||||
pub const KEYMAP: &'static [KeyBinding<Sampler>] = keymap!(Sampler {
|
||||
[Up, NONE, "cursor_up", "move cursor up", cursor_up],
|
||||
[Down, NONE, "cursor_down", "move cursor down", cursor_down],
|
||||
[Enter, NONE, "select", "select item under cursor", select],
|
||||
[Up, NONE, "cursor_up", "move cursor up", cursor_up],
|
||||
[Down, NONE, "cursor_down", "move cursor down", cursor_down],
|
||||
[Char('t'), NONE, "trigger", "play current sample", trigger],
|
||||
[Enter, NONE, "select", "select item under cursor", select],
|
||||
});
|
||||
fn cursor_up (state: &mut Sampler) -> Usually<bool> {
|
||||
state.cursor.0 = if state.cursor.0 == 0 {
|
||||
|
|
@ -241,7 +245,7 @@ fn cursor_down (state: &mut Sampler) -> Usually<bool> {
|
|||
state.cursor.0 = (state.cursor.0 + 1) % state.samples.len();
|
||||
Ok(true)
|
||||
}
|
||||
fn select (state: &mut Sampler) -> Usually<bool> {
|
||||
fn trigger (state: &mut Sampler) -> Usually<bool> {
|
||||
for (i, sample) in state.samples.values().enumerate() {
|
||||
if i == state.cursor.0 {
|
||||
state.voices.push(sample.play(0))
|
||||
|
|
@ -249,3 +253,11 @@ fn select (state: &mut Sampler) -> Usually<bool> {
|
|||
}
|
||||
Ok(true)
|
||||
}
|
||||
fn select (state: &mut Sampler) -> Usually<bool> {
|
||||
for (i, sample) in state.samples.values().enumerate() {
|
||||
if i == state.cursor.0 {
|
||||
//state.voices.push(sample.play(0))
|
||||
}
|
||||
}
|
||||
Ok(true)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,12 +43,31 @@ pub const KEYMAP_TRACKS: &'static [KeyBinding<Launcher>] = keymap!(Launcher {
|
|||
[Char(','), NONE, "clip_prev", "set clip to last phrase", clip_prev],
|
||||
[Delete, CONTROL, "delete_track", "delete track", delete_track],
|
||||
[Char('d'), CONTROL, "duplicate", "duplicate scene or track", duplicate],
|
||||
[Enter, NONE, "clip_enter", "play or record clip or stop and advance", clip_enter],
|
||||
[Enter, NONE, "activate", "activate item at cursor", activate],
|
||||
});
|
||||
fn duplicate (_: &mut Launcher) -> Usually<bool> {
|
||||
Ok(true)
|
||||
}
|
||||
fn clip_enter (_: &mut Launcher) -> Usually<bool> {
|
||||
fn activate (state: &mut Launcher) -> Usually<bool> {
|
||||
if let (
|
||||
Some((scene_id, scene)),
|
||||
Some((track_id, track)),
|
||||
) = (state.scene(), state.track()) {
|
||||
// Launch clip
|
||||
if let Some(Some(phrase_id)) = scene.clips.get(track_id) {
|
||||
track.sequencer.state().sequence = *phrase_id;
|
||||
}
|
||||
} else if let Some((scene_id, scene)) = state.scene() {
|
||||
// Launch scene
|
||||
for (track_id, track) in state.tracks.iter().enumerate() {
|
||||
if let Some(Some(phrase_id)) = scene.clips.get(track_id) {
|
||||
track.sequencer.state().sequence = *phrase_id;
|
||||
}
|
||||
}
|
||||
} else if let Some((track_id, track)) = state.track() {
|
||||
// Rename track?
|
||||
}
|
||||
|
||||
//let track = state.active_track().unwrap();
|
||||
//let scene = state.active_scene();
|
||||
//if state.cursor.1 >= 2 {
|
||||
|
|
|
|||
51
src/main.rs
51
src/main.rs
|
|
@ -69,6 +69,9 @@ fn main () -> Result<(), Box<dyn Error>> {
|
|||
MidiMessage::NoteOn { key: 36.into(), vel: 100.into() },
|
||||
MidiMessage::NoteOn { key: 44.into(), vel: 100.into() },
|
||||
] ),
|
||||
play!(1 => [
|
||||
MidiMessage::NoteOn { key: 44.into(), vel: 100.into() },
|
||||
]),
|
||||
play!(2 => [
|
||||
MidiMessage::NoteOn { key: 44.into(), vel: 100.into() },
|
||||
]),
|
||||
|
|
@ -146,6 +149,50 @@ fn main () -> Result<(), Box<dyn Error>> {
|
|||
MidiMessage::NoteOff { key: 41.into(), vel: 100.into() },
|
||||
MidiMessage::NoteOn { key: 42.into(), vel: 100.into() },
|
||||
]),
|
||||
]))),
|
||||
Phrase::new("E E G Bb", ppq * 4, Some(BTreeMap::from([
|
||||
play!(2 => [
|
||||
MidiMessage::NoteOff { key: 42.into(), vel: 100.into() },
|
||||
MidiMessage::NoteOn { key: 36.into(), vel: 100.into() },
|
||||
]),
|
||||
play!(6 => [
|
||||
MidiMessage::NoteOff { key: 36.into(), vel: 100.into() },
|
||||
MidiMessage::NoteOn { key: 36.into(), vel: 100.into() },
|
||||
]),
|
||||
play!(10 => [
|
||||
MidiMessage::NoteOff { key: 36.into(), vel: 100.into() },
|
||||
MidiMessage::NoteOn { key: 39.into(), vel: 100.into() },
|
||||
]),
|
||||
play!(14 => [
|
||||
MidiMessage::NoteOff { key: 39.into(), vel: 100.into() },
|
||||
MidiMessage::NoteOn { key: 42.into(), vel: 100.into() },
|
||||
]),
|
||||
]))),
|
||||
Phrase::new("E E E E", ppq * 4, Some(BTreeMap::from([
|
||||
play!(0 => [
|
||||
MidiMessage::NoteOff { key: 36.into(), vel: 100.into() },
|
||||
]),
|
||||
play!(2 => [
|
||||
MidiMessage::NoteOn { key: 36.into(), vel: 100.into() },
|
||||
]),
|
||||
play!(4 => [
|
||||
MidiMessage::NoteOff { key: 36.into(), vel: 100.into() },
|
||||
]),
|
||||
play!(6 => [
|
||||
MidiMessage::NoteOn { key: 36.into(), vel: 100.into() },
|
||||
]),
|
||||
play!(8 => [
|
||||
MidiMessage::NoteOff { key: 36.into(), vel: 100.into() },
|
||||
]),
|
||||
play!(10 => [
|
||||
MidiMessage::NoteOn { key: 36.into(), vel: 100.into() },
|
||||
]),
|
||||
play!(12 => [
|
||||
MidiMessage::NoteOff { key: 36.into(), vel: 100.into() },
|
||||
]),
|
||||
play!(14 => [
|
||||
MidiMessage::NoteOn { key: 36.into(), vel: 100.into() },
|
||||
]),
|
||||
])))
|
||||
]))?,
|
||||
|
||||
|
|
@ -156,8 +203,8 @@ fn main () -> Result<(), Box<dyn Error>> {
|
|||
Some(vec![
|
||||
Scene::new(&"Scene 1", &[Some(0), None, None, None]),
|
||||
Scene::new(&"Scene 2", &[Some(0), Some(0), None, None]),
|
||||
Scene::new(&"Scene 3", &[Some(1), Some(0), None, None]),
|
||||
Scene::new(&"Scene 4", &[Some(2), Some(0), None, None]),
|
||||
Scene::new(&"Scene 3", &[Some(1), Some(1), None, None]),
|
||||
Scene::new(&"Scene 4", &[Some(2), Some(2), None, None]),
|
||||
//Scene::new(&"Scene#03", &[None, Some(0), None, None]),
|
||||
//Scene::new(&"Scene#04", &[None, None, None, None]),
|
||||
//Scene::new(&"Scene#05", &[None, None, None, None]),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue