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"
version = "0.0.0"
dependencies = [
"anyhow",
"assert_no_alloc",
"atomic_float",
"atomic_refcell",

View file

@ -47,7 +47,7 @@ assert_process_allocs = ["dep:assert_no_alloc"]
# Enables an export target for standalone binaries through the
# `nih_export_standalone()` function. Disabled by default, as this requires
# 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
# 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
@ -83,6 +83,7 @@ widestring = "1.0.0-beta.1"
assert_no_alloc = { version = "1.1", optional = true }
# Used for the `standalone` feature
anyhow = { version = "1.0", optional = true }
# NOTE: OpenGL support is not needed here, but rust-analyzer gets confused when
# 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 }

View file

@ -3,6 +3,7 @@
use clap::{FromArgMatches, IntoApp};
use self::backend::Backend;
use self::config::WrapperConfig;
use self::wrapper::{Wrapper, WrapperError};
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());
nih_log!(
"Audio and MIDI IO has not yet been implemented in the standalone targets. So if you're \
not hearing anything, then that's correct!"
);
match config.backend {
config::BackendType::Auto => match backend::Jack::new(config.clone()) {
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
// command line option to override this behavior.
let backend = backend::Dummy::new(config.clone());
fn run_wrapper<P: Plugin, B: Backend>(backend: B, config: WrapperConfig) -> bool {
let wrapper = match Wrapper::<P, _>::new(backend, config.clone()) {
Ok(wrapper) => wrapper,
Err(err) => {

View file

@ -1,3 +1,4 @@
use anyhow::Result;
use std::time::{Duration, Instant};
use crate::buffer::Buffer;
@ -15,10 +16,10 @@ pub trait Backend: 'static + Send + Sync {
fn run(&mut self, cb: impl FnMut(&mut Buffer) -> bool);
}
// /// Uses JACK audio and MIDI.
// pub struct Jack {
// // TODO
// }
/// Uses JACK audio and MIDI.
pub struct Jack {
config: WrapperConfig,
}
/// 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
@ -27,12 +28,11 @@ pub struct Dummy {
config: WrapperConfig,
}
// TODO: Add a JACK backend
// impl Backend for Jack {
// fn run(&mut self, cb: impl FnMut(&mut Buffer) -> bool) {
// todo!()
// }
// }
impl Backend for Jack {
fn run(&mut self, cb: impl FnMut(&mut Buffer) -> bool) {
todo!()
}
}
impl Backend for Dummy {
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 {
pub fn new(config: WrapperConfig) -> Self {
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.
Auto,
/// Use JACK for audio and MIDI.
Jack,
/// Does not playback or receive any audio or MIDI.
Dummmy,
}