Use the plugin's default channels for standalones
This commit is contained in:
parent
1a706ea1c7
commit
a5c05b22fb
|
@ -12,6 +12,8 @@ code then it will not be listed here.
|
||||||
renamed to `Plugin::DEFAULT_INPUT_CHANNELS` and
|
renamed to `Plugin::DEFAULT_INPUT_CHANNELS` and
|
||||||
`Plugin::DEFAULT_OUTPUT_CHANNELS` respectively to avoid confusion as these
|
`Plugin::DEFAULT_OUTPUT_CHANNELS` respectively to avoid confusion as these
|
||||||
constants only affect the main input and output.
|
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]
|
## [2022-07-18]
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ pub fn nih_export_standalone_with_args<P: Plugin, Args: IntoIterator<Item = Stri
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
nih_log!("Could not initialize JACK, falling back to the dummy audio backend");
|
nih_log!("Could not initialize JACK, falling back to the dummy audio backend");
|
||||||
run_wrapper::<P, _>(backend::Dummy::new(config.clone()), config)
|
run_wrapper::<P, _>(backend::Dummy::new::<P>(config.clone()), config)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
config::BackendType::Jack => match backend::Jack::new::<P>(config.clone()) {
|
config::BackendType::Jack => match backend::Jack::new::<P>(config.clone()) {
|
||||||
|
@ -88,7 +88,7 @@ pub fn nih_export_standalone_with_args<P: Plugin, Args: IntoIterator<Item = Stri
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
config::BackendType::Dummy => {
|
config::BackendType::Dummy => {
|
||||||
run_wrapper::<P, _>(backend::Dummy::new(config.clone()), config)
|
run_wrapper::<P, _>(backend::Dummy::new::<P>(config.clone()), config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,12 +114,13 @@ fn run_wrapper<P: Plugin, B: Backend>(backend: B, config: WrapperConfig) -> bool
|
||||||
|
|
||||||
fn print_error(error: WrapperError, config: &WrapperConfig) {
|
fn print_error(error: WrapperError, config: &WrapperConfig) {
|
||||||
match error {
|
match error {
|
||||||
WrapperError::IncompatibleConfig => {
|
WrapperError::IncompatibleConfig {
|
||||||
|
input_channels,
|
||||||
|
output_channels,
|
||||||
|
} => {
|
||||||
nih_error!(
|
nih_error!(
|
||||||
"The plugin does not support the {} channel input and {} channel output \
|
"The plugin does not support the {input_channels} channel input and \
|
||||||
configuration",
|
{output_channels} channel output configuration",
|
||||||
config.input_channels,
|
|
||||||
config.output_channels
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
WrapperError::InitializationFailed => {
|
WrapperError::InitializationFailed => {
|
||||||
|
|
|
@ -5,12 +5,14 @@ use super::Backend;
|
||||||
use crate::buffer::Buffer;
|
use crate::buffer::Buffer;
|
||||||
use crate::context::Transport;
|
use crate::context::Transport;
|
||||||
use crate::midi::NoteEvent;
|
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
|
/// 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
|
||||||
/// useful for testing plugin GUIs.
|
/// useful for testing plugin GUIs.
|
||||||
pub struct Dummy {
|
pub struct Dummy {
|
||||||
config: WrapperConfig,
|
config: WrapperConfig,
|
||||||
|
bus_config: BusConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Backend for Dummy {
|
impl Backend for Dummy {
|
||||||
|
@ -27,7 +29,7 @@ impl Backend for Dummy {
|
||||||
|
|
||||||
let mut channels = vec![
|
let mut channels = vec![
|
||||||
vec![0.0f32; self.config.period_size as usize];
|
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();
|
let mut buffer = Buffer::default();
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -71,7 +73,16 @@ impl Backend for Dummy {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Dummy {
|
impl Dummy {
|
||||||
pub fn new(config: WrapperConfig) -> Self {
|
pub fn new<P: Plugin>(config: WrapperConfig) -> Self {
|
||||||
Self { config }
|
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,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,7 +188,8 @@ impl Jack {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut inputs = Vec::new();
|
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)?);
|
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
|
// no. So the connections are made just after activating the client in the `run()` function
|
||||||
// above.
|
// above.
|
||||||
let mut outputs = Vec::new();
|
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)?);
|
outputs.push(client.register_port(&format!("output_{port_no}"), AudioOut)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,12 +11,15 @@ pub struct WrapperConfig {
|
||||||
#[clap(value_parser, short = 'b', long, default_value = "auto")]
|
#[clap(value_parser, short = 'b', long, default_value = "auto")]
|
||||||
pub backend: BackendType,
|
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.
|
/// The number of input channels.
|
||||||
#[clap(value_parser, short = 'i', long, default_value = "2")]
|
#[clap(value_parser, short = 'i', long)]
|
||||||
pub input_channels: u32,
|
pub input_channels: Option<u32>,
|
||||||
/// The number of output channels.
|
/// The number of output channels.
|
||||||
#[clap(value_parser, short = 'o', long, default_value = "2")]
|
#[clap(value_parser, short = 'o', long)]
|
||||||
pub output_channels: u32,
|
pub output_channels: Option<u32>,
|
||||||
/// The audio backend's sample rate.
|
/// The audio backend's sample rate.
|
||||||
///
|
///
|
||||||
/// This setting is ignored when using the JACK backend.
|
/// This setting is ignored when using the JACK backend.
|
||||||
|
|
|
@ -75,7 +75,10 @@ pub struct Wrapper<P: Plugin, B: Backend> {
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum WrapperError {
|
pub enum WrapperError {
|
||||||
/// The plugin does not accept the IO configuration from the config.
|
/// 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.
|
/// The plugin returned `false` during initialization.
|
||||||
InitializationFailed,
|
InitializationFailed,
|
||||||
}
|
}
|
||||||
|
@ -174,8 +177,8 @@ impl<P: Plugin, B: Backend> Wrapper<P, B> {
|
||||||
editor,
|
editor,
|
||||||
|
|
||||||
bus_config: BusConfig {
|
bus_config: BusConfig {
|
||||||
num_input_channels: config.input_channels,
|
num_input_channels: config.input_channels.unwrap_or(P::DEFAULT_INPUT_CHANNELS),
|
||||||
num_output_channels: config.output_channels,
|
num_output_channels: config.output_channels.unwrap_or(P::DEFAULT_OUTPUT_CHANNELS),
|
||||||
// TODO: Expose additional sidechain IO in the JACK backend
|
// TODO: Expose additional sidechain IO in the JACK backend
|
||||||
aux_input_busses: AuxiliaryIOConfig::default(),
|
aux_input_busses: AuxiliaryIOConfig::default(),
|
||||||
aux_output_busses: AuxiliaryIOConfig::default(),
|
aux_output_busses: AuxiliaryIOConfig::default(),
|
||||||
|
@ -199,7 +202,10 @@ impl<P: Plugin, B: Backend> Wrapper<P, B> {
|
||||||
{
|
{
|
||||||
let mut plugin = wrapper.plugin.write();
|
let mut plugin = wrapper.plugin.write();
|
||||||
if !plugin.accepts_bus_config(&wrapper.bus_config) {
|
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
|
// Befure initializing the plugin, make sure all smoothers are set the the default values
|
||||||
|
|
Loading…
Reference in a new issue