1
0
Fork 0

Add a (not yet functional) standalone exporter

This commit is contained in:
Robbert van der Helm 2022-04-22 17:00:59 +02:00
parent bee82bdefb
commit f3db4a9ed0
9 changed files with 70 additions and 4 deletions

View file

@ -61,7 +61,7 @@ jobs:
command: build command: build
# Don't use --all-features as that will enable a whole bunch of # Don't use --all-features as that will enable a whole bunch of
# conflicting iced features # conflicting iced features
args: --workspace --features "simd" args: --workspace --features "simd,standalone"
- name: Run the tests - name: Run the tests
uses: actions-rs/cargo@v1 uses: actions-rs/cargo@v1
with: with:

View file

@ -35,13 +35,18 @@ members = [
[features] [features]
default = ["vst3"] default = ["vst3"]
# Enabling this feature will cause the plugin to terminate when allocations # Enabling this feature will cause the plugin to terminate when allocations
# occur in the processing function while compiling in debug mode. Keep in mind # occur in the processing function while compiling in debug mode. Keep in mind
# that most panic handlers will also allocate, so temporarily disabling this # that most panic handlers will also allocate, so temporarily disabling this
# feature may be necessary when debugging panics in DSP code. # feature may be necessary when debugging panics in DSP code.
assert_process_allocs = ["dep:assert_no_alloc"] assert_process_allocs = ["dep:assert_no_alloc"]
# Enables the `nih_export_vst3()` macro. Enabled by default. This feature exists # Enables an export target for standalone binaries through the
# mostly for GPL-compliance reasons, since even if you don't use the VST3 # `nih_export_standalone()` function. Disabled by default, as this requires
# building additional dependencies for audio and MIDI handling.
standalone = []
# 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 # wrapper you might otherwise still include a couple (unused) symbols from the
# `vst3-sys` create. # `vst3-sys` create.
vst3 = ["dep:vst3-sys"] vst3 = ["dep:vst3-sys"]

View file

@ -54,6 +54,8 @@ for download links.
- Supports both VST3 and [CLAP](https://github.com/free-audio/clap) by simply - Supports both VST3 and [CLAP](https://github.com/free-audio/clap) by simply
adding the corresponding `nih_export_<api>!(Foo)` macro to your plugin's adding the corresponding `nih_export_<api>!(Foo)` macro to your plugin's
library. library.
- Standalone binaries can be made by calling `nih_export_standalone(Foo)` from
your `main()` function.
- Declarative parameter handling without any boilerplate. - Declarative parameter handling without any boilerplate.
- Define parameters for your plugin by adding `FloatParam`, `IntParam`, - Define parameters for your plugin by adding `FloatParam`, `IntParam`,
`BoolParam`, and `EnumParam<T>` fields to your parameter struct, assign `BoolParam`, and `EnumParam<T>` fields to your parameter struct, assign

View file

@ -175,6 +175,8 @@ pub fn bundle(package: &str, args: &[String]) -> Result<()> {
} }
} }
// TODO: Add support for binary targets. This would simply copy/reflink the binary to the
// `bundled` directory to make it easier to ship all versions of a plugin.
let compilation_target = compilation_target(cross_compile_target.as_deref())?; let compilation_target = compilation_target(cross_compile_target.as_deref())?;
let lib_path = target_base(cross_compile_target.as_deref())? let lib_path = target_base(cross_compile_target.as_deref())?
.join(if is_release_build { "release" } else { "debug" }) .join(if is_release_build { "release" } else { "debug" })

View file

@ -22,7 +22,6 @@ use crate::param::internals::Params;
/// - Multiple output busses /// - Multiple output busses
/// - Special handling for offline processing /// - Special handling for offline processing
/// - MIDI SysEx and MIDI2 for CLAP, note expressions and MIDI1 are already supported /// - MIDI SysEx and MIDI2 for CLAP, note expressions and MIDI1 are already supported
/// - An export target for a standalone application
#[allow(unused_variables)] #[allow(unused_variables)]
pub trait Plugin: Default + Send + Sync + 'static { pub trait Plugin: Default + Send + Sync + 'static {
const NAME: &'static str; const NAME: &'static str;

View file

@ -9,6 +9,8 @@ pub use crate::nih_trace;
#[cfg(feature = "vst3")] #[cfg(feature = "vst3")]
pub use crate::nih_export_vst3; pub use crate::nih_export_vst3;
#[cfg(feature = "standalone")]
pub use crate::wrapper::standalone::{nih_export_standalone, nih_export_standalone_with_args};
pub use crate::formatters; pub use crate::formatters;
pub use crate::util; pub use crate::util;

View file

@ -5,6 +5,8 @@ pub mod clap;
pub mod state; pub mod state;
pub(crate) mod util; pub(crate) mod util;
#[cfg(feature = "standalone")]
pub mod standalone;
#[cfg(feature = "vst3")] #[cfg(feature = "vst3")]
pub mod vst3; pub mod vst3;

35
src/wrapper/standalone.rs Normal file
View file

@ -0,0 +1,35 @@
//! A standalone plugin target that directly connects to the system's audio and MIDI ports instead
//! of relying on a plugin host. This is mostly useful for quickly testing GUI changes.
use self::wrapper::Wrapper;
use crate::plugin::Plugin;
mod wrapper;
/// Open an NIH-plug plugin as a standalone application. If the plugin has an editor, this will open
/// the editor and block until the editor is closed. Otherwise this will block until SIGINT is
/// received. This is mainly useful for quickly testing plugin GUIs. You should call this function
/// from a `main()` function.
///
/// By default this will connect to the 'default' audio and MIDI ports. Use the command line options
/// to change this. `--help` lists all available options.
///
/// # TODO
///
/// The aforementioned command line options have not yet been implemented.
//
// TODO: Actually implement command line flags for changing the IO configuration
// TODO: Add a way to set the IO configuration at runtime, for instance through the plugin's GUI
pub fn nih_export_standalone<P: Plugin>() {
nih_export_standalone_with_args::<P, _>(std::env::args())
}
pub fn nih_export_standalone_with_args<P: Plugin, Args: IntoIterator<Item = String>>(args: Args) {
// TODO: Do something with the arguments
Wrapper::<P>::new();
// TODO: Open the editor if available, do IO things
// TODO: If the plugin has an editor, block until the editor is closed. Otherwise block
// indefinitely or until SIGINT (how do signal handlers work in Rust?)
}

View file

@ -0,0 +1,19 @@
use parking_lot::RwLock;
use crate::plugin::Plugin;
pub struct Wrapper<P: Plugin> {
/// The wrapped plugin instance.
plugin: RwLock<P>,
}
impl<P: Plugin> Wrapper<P> {
/// Instantiate a new instance of the standalone wrapper.
//
// TODO: This should take some arguments for the audio and MIDI IO.
pub fn new() -> Self {
Wrapper {
plugin: RwLock::new(P::default()),
}
}
}