1
0
Fork 0

Add boilerplate for an actual JACK implementation

This commit is contained in:
Robbert van der Helm 2022-06-14 17:19:09 +02:00
parent e2099ec16c
commit 191d5383bd
5 changed files with 50 additions and 8 deletions

27
Cargo.lock generated
View file

@ -1772,6 +1772,32 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
[[package]]
name = "jack"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce722655a29b13bb98ec7e8ba9dc65d670b9b37c7b1c09775c7f7516811c5a36"
dependencies = [
"bitflags",
"jack-sys",
"lazy_static",
"libc",
"log",
]
[[package]]
name = "jack-sys"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9d70559ff166d148ccb750ddd77702af760718f3a752c731add168c22c16a9f"
dependencies = [
"bitflags",
"lazy_static",
"libc",
"libloading",
"pkg-config",
]
[[package]] [[package]]
name = "jpeg-decoder" name = "jpeg-decoder"
version = "0.1.22" version = "0.1.22"
@ -2106,6 +2132,7 @@ dependencies = [
"clap", "clap",
"clap-sys", "clap-sys",
"crossbeam", "crossbeam",
"jack",
"lazy_static", "lazy_static",
"libc", "libc",
"log", "log",

View file

@ -47,7 +47,7 @@ assert_process_allocs = ["dep:assert_no_alloc"]
# Enables an export target for standalone binaries through the # Enables an export target for standalone binaries through the
# `nih_export_standalone()` function. Disabled by default, as this requires # `nih_export_standalone()` function. Disabled by default, as this requires
# building additional dependencies for audio and MIDI handling. # building additional dependencies for audio and MIDI handling.
standalone = ["dep:anyhow", "dep:baseview", "dep:clap"] standalone = ["dep:anyhow", "dep:baseview", "dep:clap", "dep:jack"]
# Enables the `nih_export_vst3!()` macro. Enabled by default. This feature # Enables the `nih_export_vst3!()` macro. Enabled by default. This feature
# exists mostly for GPL-compliance reasons, since even if you don't use the VST3 # exists mostly for GPL-compliance reasons, since even if you don't use the VST3
# wrapper you might otherwise still include a couple (unused) symbols from the # wrapper you might otherwise still include a couple (unused) symbols from the
@ -89,6 +89,7 @@ anyhow = { version = "1.0", optional = true }
baseview = { git = "https://github.com/robbert-vdh/baseview.git", branch = "feature/resize", features = ["opengl"], optional = true } baseview = { git = "https://github.com/robbert-vdh/baseview.git", branch = "feature/resize", features = ["opengl"], optional = true }
# All the claps! # All the claps!
clap = { version = "3.2", features = ["derive"], optional = true } clap = { version = "3.2", features = ["derive"], optional = true }
jack = { version = "0.10.0", optional = true }
# Used for the `vst3` feature # Used for the `vst3` feature
vst3-sys = { git = "https://github.com/robbert-vdh/vst3-sys.git", branch = "fix/note-off-event", optional = true } vst3-sys = { git = "https://github.com/robbert-vdh/vst3-sys.git", branch = "fix/note-off-event", optional = true }

View file

@ -70,14 +70,14 @@ pub fn nih_export_standalone_with_args<P: Plugin, Args: IntoIterator<Item = Stri
.unwrap_or_else(|err| err.exit()); .unwrap_or_else(|err| err.exit());
match config.backend { match config.backend {
config::BackendType::Auto => match backend::Jack::new(config.clone()) { config::BackendType::Auto => match backend::Jack::new(P::NAME, config.clone()) {
Ok(backend) => run_wrapper::<P, _>(backend, config), Ok(backend) => run_wrapper::<P, _>(backend, config),
Err(_) => { Err(_) => {
nih_log!("Could not initialize JACK, falling back to the dummy audio backend"); nih_log!("Could not initialize JACK, falling back to the dummy audio backend");
run_wrapper::<P, _>(backend::Dummy::new(config.clone()), config) run_wrapper::<P, _>(backend::Dummy::new(config.clone()), config)
} }
}, },
config::BackendType::Jack => match backend::Jack::new(config.clone()) { config::BackendType::Jack => match backend::Jack::new(P::NAME, config.clone()) {
Ok(backend) => run_wrapper::<P, _>(backend, config), Ok(backend) => run_wrapper::<P, _>(backend, config),
Err(err) => { Err(err) => {
nih_error!("Could not initialize the JACK backend: {:#}", err); nih_error!("Could not initialize the JACK backend: {:#}", err);

View file

@ -1,4 +1,4 @@
use anyhow::Result; use anyhow::{Context, Result};
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use crate::buffer::Buffer; use crate::buffer::Buffer;
@ -19,6 +19,7 @@ pub trait Backend: 'static + Send + Sync {
/// Uses JACK audio and MIDI. /// Uses JACK audio and MIDI.
pub struct Jack { pub struct Jack {
config: WrapperConfig, config: WrapperConfig,
client: jack::Client,
} }
/// This backend doesn't input or output any audio or MIDI. It only exists so the standalone /// This backend doesn't input or output any audio or MIDI. It only exists so the standalone
@ -30,6 +31,7 @@ pub struct Dummy {
impl Backend for Jack { impl Backend for Jack {
fn run(&mut self, cb: impl FnMut(&mut Buffer) -> bool) { fn run(&mut self, cb: impl FnMut(&mut Buffer) -> bool) {
// TODO: Create an async client and do The Thing (tm)
todo!() todo!()
} }
} }
@ -75,10 +77,18 @@ impl Backend for Dummy {
impl Jack { impl Jack {
/// Initialize the JACK backend. Returns an error if this failed for whatever reason. /// Initialize the JACK backend. Returns an error if this failed for whatever reason.
pub fn new(config: WrapperConfig) -> Result<Self> { pub fn new(name: &str, config: WrapperConfig) -> Result<Self> {
// TODO: Actually implement the JACK backend let (client, status) = jack::Client::new(name, jack::ClientOptions::NO_START_SERVER)
anyhow::bail!("Not yet implemented") .context("Error while initializing the JACK client")?;
// Ok(Self { config }) if !status.is_empty() {
anyhow::bail!("The JACK server returned an error: {status:?}");
}
// TODO: Register ports
// TODO: Connect output
// TODO: Command line argument to connect the inputs?
Ok(Self { config, client })
} }
} }

View file

@ -18,9 +18,13 @@ pub struct WrapperConfig {
#[clap(value_parser, short = 'o', long, default_value = "2")] #[clap(value_parser, short = 'o', long, default_value = "2")]
pub output_channels: u32, pub output_channels: u32,
/// The audio backend's sample rate. /// The audio backend's sample rate.
///
/// This setting is ignored when using the JACK backend.
#[clap(value_parser, short = 'r', long, default_value = "44100")] #[clap(value_parser, short = 'r', long, default_value = "44100")]
pub sample_rate: f32, pub sample_rate: f32,
/// The audio backend's period size. /// The audio backend's period size.
///
/// This setting is ignored when using the JACK backend.
#[clap(value_parser, short = 'p', long, default_value = "512")] #[clap(value_parser, short = 'p', long, default_value = "512")]
pub period_size: u32, pub period_size: u32,