diff --git a/Cargo.lock b/Cargo.lock index 363e1b28..1206d341 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -185,7 +185,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -461,6 +461,36 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_enum" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "object" version = "0.35.0" @@ -511,6 +541,16 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + [[package]] name = "proc-macro2" version = "1.0.81" @@ -619,7 +659,7 @@ checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -674,7 +714,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2ff9eaf853dec4c8802325d8b6d3dffa86cc707fd7a1a4cdbf416e13b061787a" dependencies = [ "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -708,7 +748,18 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn", + "syn 2.0.60", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", ] [[package]] @@ -735,6 +786,7 @@ dependencies = [ "midly", "ratatui", "toml", + "vst", ] [[package]] @@ -746,7 +798,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit", + "toml_edit 0.22.14", ] [[package]] @@ -758,6 +810,17 @@ dependencies = [ "serde", ] +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow 0.5.40", +] + [[package]] name = "toml_edit" version = "0.22.14" @@ -768,7 +831,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.6.13", ] [[package]] @@ -811,6 +874,20 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "vst" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caf1ddbb85e53de6c1534f97340b065ca127678dcc31f88a33b93e54a5ac38dc" +dependencies = [ + "bitflags 1.3.2", + "libc", + "libloading", + "log", + "num-traits", + "num_enum", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -978,6 +1055,15 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + [[package]] name = "winnow" version = "0.6.13" @@ -1004,5 +1090,5 @@ checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.60", ] diff --git a/Cargo.toml b/Cargo.toml index 632886bf..b23f5818 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,3 +12,6 @@ microxdg = "0.1.2" toml = "0.8.12" better-panic = "0.3.0" midly = "0.5" + +vst = "0.4.0" +#vst3 = "0.1.0" diff --git a/src/device/chain.rs b/src/device/chain.rs index 46ad0e8a..295157de 100644 --- a/src/device/chain.rs +++ b/src/device/chain.rs @@ -2,14 +2,16 @@ use crate::prelude::*; pub struct Chain { name: String, - devices: Vec> + devices: Vec>, + focused: usize, } impl Chain { pub fn new (name: &str, devices: Vec>) -> Result, Box> { Ok(DynamicDevice::new(render, handle, process, Self { name: name.into(), - devices + devices, + focused: 0 })) } } @@ -28,18 +30,17 @@ pub fn render (state: &Chain, buf: &mut Buffer, area: Rect) buf.set_string(area.x + area.width - 1, y, "│", Style::default().black()); buf.set_string(area.x + 2, y, "Input...", Style::default().dim()); let mut x = 0u16; - y = y + 1; for device in state.devices.iter() { let result = device.render(buf, Rect { x: area.x, - y: area.y + y, + y, width: area.width, - height: area.height.saturating_sub(y) + height: 21//area.height.saturating_sub(y) })?; - //buf.set_string(area.x, y, format!("{y}---TOP---+{h}"), Style::default().red()); + //let result = Rect { x: 0, y: 0, width: result.width, height: 21 }; x = x.max(result.width); y = y + result.height; - y = y + 1; + //y = y + 1; buf.set_string(area.x, y, "│", Style::default().black()); buf.set_string(area.x + area.width - 1, y, "│", Style::default().black()); buf.set_string(area.x + 2, y, " Patch in ┐ │ └ Patch out", Style::default().dim()); @@ -48,7 +49,12 @@ pub fn render (state: &Chain, buf: &mut Buffer, area: Rect) //buf.set_string(area.x + area.width - 1, area.y + 1, "│", Style::default().black()); //buf.set_string(area.x + 2, y, "Patch...", Style::default().dim()); } - Ok(Rect { x: area.x, y: area.y, width: x, height: y }) + Ok(draw_box(buf, Rect { + x: area.x, + y: area.y, + width: area.width, + height: y - area.y, + })) } pub fn handle (_: &mut Chain, _: &AppEvent) -> Usually { diff --git a/src/device/plugin.rs b/src/device/plugin.rs index 9dd81f7e..71d30efc 100644 --- a/src/device/plugin.rs +++ b/src/device/plugin.rs @@ -1,17 +1,28 @@ use crate::prelude::*; pub struct Plugin { - name: String + name: String, + plugin: Option<::vst::host::PluginInstance> } impl Plugin { pub fn new (name: &str) -> Result, Box> { - Ok(DynamicDevice::new(render, handle, process, Self { - name: name.into() - })) + let device = DynamicDevice::new(render, handle, process, Self { + name: name.into(), + plugin: None, + }); + let mut loader = ::vst::host::PluginLoader::load( + &std::path::Path::new("/nix/store/ij3sz7nqg5l7v2dygdvzy3w6cj62bd6r-helm-0.9.0/lib/lxvst/helm.so"), + device.state.clone() + )?; + let plugin = loader.instance()?; + device.state.lock().unwrap().plugin = Some(plugin); + Ok(device) } } +impl ::vst::host::Host for Plugin {} + pub fn process (_: &mut Plugin, _: &Client, _: &ProcessScope) -> Control { Control::Continue } diff --git a/src/device/sequencer.rs b/src/device/sequencer.rs index 5b8acb5e..63b3f64c 100644 --- a/src/device/sequencer.rs +++ b/src/device/sequencer.rs @@ -4,47 +4,47 @@ use ratatui::style::Stylize; type Sequence = std::collections::BTreeMap>; pub struct Sequencer { - name: String, + name: String, /// JACK transport handle. - transport: ::jack::Transport, + transport: ::jack::Transport, /// Holds info about tempo - timebase: Arc, + timebase: Arc, /// Sequencer resolution, e.g. 16 steps per beat. - resolution: usize, + resolution: usize, /// Steps in sequence, e.g. 64 16ths = 4 beat loop. - steps: usize, + steps: usize, /// JACK MIDI input port that will be created. - input_port: Port, + input_port: Port, /// Port name patterns to connect to. - input_connect: Vec, + input_connect: Vec, /// Play input through output. - monitoring: bool, + monitoring: bool, /// Red keys on piano roll. - notes_on: Vec, + notes_on: Vec, /// Write input to sequence. - recording: bool, + recording: bool, /// Map: tick -> MIDI events at tick - sequence: Sequence, + sequence: Sequence, /// Don't delete when recording. - overdub: bool, + overdub: bool, /// Play sequence to output. - playing: bool, + playing: bool, /// JACK MIDI output port that will be created. - output_port: Port, + output_port: Port, /// Port name patterns to connect to. - output_connect: Vec, + output_connect: Vec, /// Display mode - mode: SequencerView, + mode: SequencerView, /// Range of notes to display - note_axis: (u16, u16), + note_axis: (u16, u16), /// Position of cursor within note range - note_cursor: u16, + note_cursor: u16, /// Range of time steps to display - time_axis: (u16, u16), + time_axis: (u16, u16), /// Position of cursor within time range - time_cursor: u16, + time_cursor: u16, } #[derive(Debug, Clone)] diff --git a/src/layout.rs b/src/layout.rs index 17fb506e..2362878e 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -31,12 +31,12 @@ impl Device for Rows { true }, Event::Key(KeyEvent { code: KeyCode::Enter, .. }) => { - self.focused = false; + self.focused = true; self.items[self.focus].handle(&AppEvent::Focus)?; true }, Event::Key(KeyEvent { code: KeyCode::Esc, .. }) => { - self.focused = true; + self.focused = false; self.items[self.focus].handle(&AppEvent::Blur)?; true }, diff --git a/src/main.rs b/src/main.rs index 5fe2cc3f..10d744b8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -26,7 +26,10 @@ fn main () -> Result<(), Box> { crate::device::run(Rows::new(false, vec![ Box::new(transport), Box::new(Columns::new(false, vec![ - Box::new(Sequencer::new("Melody#000", &timebase)?), + Box::new(Chain::new("Chain#0000", vec![ + Box::new(Sequencer::new("Melody#000", &timebase)?), + Box::new(Plugin::new("Plugin#000")?), + ])?), Box::new(Sequencer::new("Melody#001", &timebase)?), Box::new(Sequencer::new("Rhythm#000", &timebase)?), ])),