1
0
Fork 0

Add boilerplate for a JACK backend

This commit is contained in:
Robbert van der Helm 2022-06-14 16:27:35 +02:00
parent 99fdc8975f
commit 3d5f44764e
5 changed files with 46 additions and 18 deletions

1
Cargo.lock generated
View file

@ -2096,6 +2096,7 @@ dependencies = [
name = "nih_plug" name = "nih_plug"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"anyhow",
"assert_no_alloc", "assert_no_alloc",
"atomic_float", "atomic_float",
"atomic_refcell", "atomic_refcell",

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:baseview", "dep:clap"] standalone = ["dep:anyhow", "dep:baseview", "dep:clap"]
# 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
@ -83,6 +83,7 @@ widestring = "1.0.0-beta.1"
assert_no_alloc = { version = "1.1", optional = true } assert_no_alloc = { version = "1.1", optional = true }
# Used for the `standalone` feature # Used for the `standalone` feature
anyhow = { version = "1.0", optional = true }
# NOTE: OpenGL support is not needed here, but rust-analyzer gets confused when # NOTE: OpenGL support is not needed here, but rust-analyzer gets confused when
# some crates do use it and others don't # some crates do use it and others don't
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 }

View file

@ -3,6 +3,7 @@
use clap::{FromArgMatches, IntoApp}; use clap::{FromArgMatches, IntoApp};
use self::backend::Backend;
use self::config::WrapperConfig; use self::config::WrapperConfig;
use self::wrapper::{Wrapper, WrapperError}; use self::wrapper::{Wrapper, WrapperError};
use super::util::setup_logger; use super::util::setup_logger;
@ -68,14 +69,28 @@ 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());
nih_log!( match config.backend {
"Audio and MIDI IO has not yet been implemented in the standalone targets. So if you're \ config::BackendType::Auto => match backend::Jack::new(config.clone()) {
not hearing anything, then that's correct!" Ok(backend) => run_wrapper::<P, _>(backend, config),
); Err(_) => {
nih_log!("Could not initialize JACK, falling back to the dummy audio backend");
run_wrapper::<P, _>(backend::Dummy::new(config.clone()), config)
}
},
config::BackendType::Jack => match backend::Jack::new(config.clone()) {
Ok(backend) => run_wrapper::<P, _>(backend, config),
Err(err) => {
nih_log!("{:#}", err);
false
}
},
config::BackendType::Dummmy => {
run_wrapper::<P, _>(backend::Dummy::new(config.clone()), config)
}
}
}
// TODO: We should try JACK first, then CPAL, and then fall back to the dummy backend. With a fn run_wrapper<P: Plugin, B: Backend>(backend: B, config: WrapperConfig) -> bool {
// command line option to override this behavior.
let backend = backend::Dummy::new(config.clone());
let wrapper = match Wrapper::<P, _>::new(backend, config.clone()) { let wrapper = match Wrapper::<P, _>::new(backend, config.clone()) {
Ok(wrapper) => wrapper, Ok(wrapper) => wrapper,
Err(err) => { Err(err) => {

View file

@ -1,3 +1,4 @@
use anyhow::Result;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use crate::buffer::Buffer; use crate::buffer::Buffer;
@ -15,10 +16,10 @@ pub trait Backend: 'static + Send + Sync {
fn run(&mut self, cb: impl FnMut(&mut Buffer) -> bool); fn run(&mut self, cb: impl FnMut(&mut Buffer) -> bool);
} }
// /// Uses JACK audio and MIDI. /// Uses JACK audio and MIDI.
// pub struct Jack { pub struct Jack {
// // TODO config: WrapperConfig,
// } }
/// 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
/// application can continue to run even when there is no audio backend available. This can be /// application can continue to run even when there is no audio backend available. This can be
@ -27,12 +28,11 @@ pub struct Dummy {
config: WrapperConfig, config: WrapperConfig,
} }
// TODO: Add a JACK backend 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!()
// todo!() }
// } }
// }
impl Backend for Dummy { impl Backend for Dummy {
fn run(&mut self, mut cb: impl FnMut(&mut Buffer) -> bool) { fn run(&mut self, mut cb: impl FnMut(&mut Buffer) -> bool) {
@ -73,6 +73,15 @@ impl Backend for Dummy {
} }
} }
impl Jack {
/// Initialize the JACK backend. Returns an error if this failed for whatever reason.
pub fn new(config: WrapperConfig) -> Result<Self> {
// TODO: Actually implement the JACK backend
anyhow::bail!("Could not initialize JACK backend")
// Ok(Self { config })
}
}
impl Dummy { impl Dummy {
pub fn new(config: WrapperConfig) -> Self { pub fn new(config: WrapperConfig) -> Self {
Self { config } Self { config }

View file

@ -51,6 +51,8 @@ pub enum BackendType {
/// ///
/// This defaults to JACK if JACK is available, and falls back to the dummy backend if not. /// This defaults to JACK if JACK is available, and falls back to the dummy backend if not.
Auto, Auto,
/// Use JACK for audio and MIDI.
Jack,
/// Does not playback or receive any audio or MIDI. /// Does not playback or receive any audio or MIDI.
Dummmy, Dummmy,
} }