Add boilerplate for a JACK backend
This commit is contained in:
parent
99fdc8975f
commit
3d5f44764e
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -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",
|
||||||
|
|
|
@ -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 }
|
||||||
|
|
|
@ -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) => {
|
||||||
|
|
|
@ -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 }
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue