diff --git a/BREAKING_CHANGES.md b/BREAKING_CHANGES.md index b417fb1f..54c143bb 100644 --- a/BREAKING_CHANGES.md +++ b/BREAKING_CHANGES.md @@ -12,6 +12,8 @@ code then it will not be listed here. renamed to `Plugin::DEFAULT_INPUT_CHANNELS` and `Plugin::DEFAULT_OUTPUT_CHANNELS` respectively to avoid confusion as these constants only affect the main input and output. +- Standalones now use the plugin's default input and output channel counts + instead of always defaulting to two inputs and two outputs. ## [2022-07-18] diff --git a/src/wrapper/standalone.rs b/src/wrapper/standalone.rs index 187b1595..b6d68ba2 100644 --- a/src/wrapper/standalone.rs +++ b/src/wrapper/standalone.rs @@ -77,7 +77,7 @@ pub fn nih_export_standalone_with_args { nih_log!("Could not initialize JACK, falling back to the dummy audio backend"); - run_wrapper::(backend::Dummy::new(config.clone()), config) + run_wrapper::(backend::Dummy::new::

(config.clone()), config) } }, config::BackendType::Jack => match backend::Jack::new::

(config.clone()) { @@ -88,7 +88,7 @@ pub fn nih_export_standalone_with_args { - run_wrapper::(backend::Dummy::new(config.clone()), config) + run_wrapper::(backend::Dummy::new::

(config.clone()), config) } } } @@ -114,12 +114,13 @@ fn run_wrapper(backend: B, config: WrapperConfig) -> bool fn print_error(error: WrapperError, config: &WrapperConfig) { match error { - WrapperError::IncompatibleConfig => { + WrapperError::IncompatibleConfig { + input_channels, + output_channels, + } => { nih_error!( - "The plugin does not support the {} channel input and {} channel output \ - configuration", - config.input_channels, - config.output_channels + "The plugin does not support the {input_channels} channel input and \ + {output_channels} channel output configuration", ); } WrapperError::InitializationFailed => { diff --git a/src/wrapper/standalone/backend/dummy.rs b/src/wrapper/standalone/backend/dummy.rs index ec8ddd23..b59767ad 100644 --- a/src/wrapper/standalone/backend/dummy.rs +++ b/src/wrapper/standalone/backend/dummy.rs @@ -5,12 +5,14 @@ use super::Backend; use crate::buffer::Buffer; use crate::context::Transport; use crate::midi::NoteEvent; +use crate::plugin::{AuxiliaryIOConfig, BusConfig, Plugin}; /// 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 /// useful for testing plugin GUIs. pub struct Dummy { config: WrapperConfig, + bus_config: BusConfig, } impl Backend for Dummy { @@ -27,7 +29,7 @@ impl Backend for Dummy { let mut channels = vec![ vec![0.0f32; self.config.period_size as usize]; - self.config.output_channels as usize + self.bus_config.num_output_channels as usize ]; let mut buffer = Buffer::default(); unsafe { @@ -71,7 +73,16 @@ impl Backend for Dummy { } impl Dummy { - pub fn new(config: WrapperConfig) -> Self { - Self { config } + pub fn new(config: WrapperConfig) -> Self { + Self { + bus_config: BusConfig { + num_input_channels: config.input_channels.unwrap_or(P::DEFAULT_INPUT_CHANNELS), + num_output_channels: config.output_channels.unwrap_or(P::DEFAULT_OUTPUT_CHANNELS), + // TODO: Support these in the standalone + aux_input_busses: AuxiliaryIOConfig::default(), + aux_output_busses: AuxiliaryIOConfig::default(), + }, + config, + } } } diff --git a/src/wrapper/standalone/backend/jack.rs b/src/wrapper/standalone/backend/jack.rs index bdd9ab2b..55817648 100644 --- a/src/wrapper/standalone/backend/jack.rs +++ b/src/wrapper/standalone/backend/jack.rs @@ -188,7 +188,8 @@ impl Jack { } let mut inputs = Vec::new(); - for port_no in 1..config.input_channels + 1 { + let num_input_channels = config.input_channels.unwrap_or(P::DEFAULT_INPUT_CHANNELS); + for port_no in 1..num_input_channels + 1 { inputs.push(client.register_port(&format!("input_{port_no}"), AudioIn)?); } @@ -196,7 +197,8 @@ impl Jack { // no. So the connections are made just after activating the client in the `run()` function // above. let mut outputs = Vec::new(); - for port_no in 1..config.output_channels + 1 { + let num_output_channels = config.output_channels.unwrap_or(P::DEFAULT_OUTPUT_CHANNELS); + for port_no in 1..num_output_channels + 1 { outputs.push(client.register_port(&format!("output_{port_no}"), AudioOut)?); } diff --git a/src/wrapper/standalone/config.rs b/src/wrapper/standalone/config.rs index e64565dc..60851203 100644 --- a/src/wrapper/standalone/config.rs +++ b/src/wrapper/standalone/config.rs @@ -11,12 +11,15 @@ pub struct WrapperConfig { #[clap(value_parser, short = 'b', long, default_value = "auto")] pub backend: BackendType, + // These will default to the plugin's default input and output channel count. We could set the + // default value here to match those, but that would require a custom Args+FromArgMatches + // implementation and access to the `Plugin` type. /// The number of input channels. - #[clap(value_parser, short = 'i', long, default_value = "2")] - pub input_channels: u32, + #[clap(value_parser, short = 'i', long)] + pub input_channels: Option, /// The number of output channels. - #[clap(value_parser, short = 'o', long, default_value = "2")] - pub output_channels: u32, + #[clap(value_parser, short = 'o', long)] + pub output_channels: Option, /// The audio backend's sample rate. /// /// This setting is ignored when using the JACK backend. diff --git a/src/wrapper/standalone/wrapper.rs b/src/wrapper/standalone/wrapper.rs index f80c3814..d68f6b62 100644 --- a/src/wrapper/standalone/wrapper.rs +++ b/src/wrapper/standalone/wrapper.rs @@ -75,7 +75,10 @@ pub struct Wrapper { #[derive(Debug, Clone, Copy)] pub enum WrapperError { /// The plugin does not accept the IO configuration from the config. - IncompatibleConfig, + IncompatibleConfig { + input_channels: u32, + output_channels: u32, + }, /// The plugin returned `false` during initialization. InitializationFailed, } @@ -174,8 +177,8 @@ impl Wrapper { editor, bus_config: BusConfig { - num_input_channels: config.input_channels, - num_output_channels: config.output_channels, + num_input_channels: config.input_channels.unwrap_or(P::DEFAULT_INPUT_CHANNELS), + num_output_channels: config.output_channels.unwrap_or(P::DEFAULT_OUTPUT_CHANNELS), // TODO: Expose additional sidechain IO in the JACK backend aux_input_busses: AuxiliaryIOConfig::default(), aux_output_busses: AuxiliaryIOConfig::default(), @@ -199,7 +202,10 @@ impl Wrapper { { let mut plugin = wrapper.plugin.write(); if !plugin.accepts_bus_config(&wrapper.bus_config) { - return Err(WrapperError::IncompatibleConfig); + return Err(WrapperError::IncompatibleConfig { + input_channels: wrapper.bus_config.num_input_channels, + output_channels: wrapper.bus_config.num_output_channels, + }); } // Befure initializing the plugin, make sure all smoothers are set the the default values