1
0
Fork 0

Register JACK MIDI input and output ports

This commit is contained in:
Robbert van der Helm 2022-06-14 21:32:23 +02:00
parent c7f6aa15f8
commit 5cd4bb8de0
2 changed files with 31 additions and 6 deletions

View file

@ -70,7 +70,7 @@ 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());
match config.backend { match config.backend {
config::BackendType::Auto => match backend::Jack::new(P::NAME, config.clone()) { config::BackendType::Auto => match backend::Jack::new::<P>(config.clone()) {
Ok(backend) => { Ok(backend) => {
nih_log!("Using the JACK backend"); nih_log!("Using the JACK backend");
run_wrapper::<P, _>(backend, config) run_wrapper::<P, _>(backend, config)
@ -80,7 +80,7 @@ pub fn nih_export_standalone_with_args<P: Plugin, Args: IntoIterator<Item = Stri
run_wrapper::<P, _>(backend::Dummy::new(config.clone()), config) run_wrapper::<P, _>(backend::Dummy::new(config.clone()), config)
} }
}, },
config::BackendType::Jack => match backend::Jack::new(P::NAME, config.clone()) { config::BackendType::Jack => match backend::Jack::new::<P>(config.clone()) {
Ok(backend) => run_wrapper::<P, _>(backend, config), Ok(backend) => run_wrapper::<P, _>(backend, config),
Err(err) => { Err(err) => {
nih_error!("Could not initialize the JACK backend: {:#}", err); nih_error!("Could not initialize the JACK backend: {:#}", err);

View file

@ -3,11 +3,15 @@ use std::sync::Arc;
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use atomic_refcell::AtomicRefCell; use atomic_refcell::AtomicRefCell;
use crossbeam::channel; use crossbeam::channel;
use jack::{AudioIn, AudioOut, Client, ClientOptions, ClosureProcessHandler, Control, Port}; use jack::{
AudioIn, AudioOut, Client, ClientOptions, ClosureProcessHandler, Control, MidiIn, MidiOut, Port,
};
use super::super::config::WrapperConfig; use super::super::config::WrapperConfig;
use super::Backend; use super::Backend;
use crate::buffer::Buffer; use crate::buffer::Buffer;
use crate::midi::MidiConfig;
use crate::plugin::Plugin;
/// Uses JACK audio and MIDI. /// Uses JACK audio and MIDI.
pub struct Jack { pub struct Jack {
@ -17,6 +21,8 @@ pub struct Jack {
inputs: Arc<Vec<Port<AudioIn>>>, inputs: Arc<Vec<Port<AudioIn>>>,
outputs: Arc<AtomicRefCell<Vec<Port<AudioOut>>>>, outputs: Arc<AtomicRefCell<Vec<Port<AudioOut>>>>,
midi_input: Option<Arc<Port<MidiIn>>>,
midi_output: Option<Arc<AtomicRefCell<Port<MidiOut>>>>,
} }
/// A simple message to tell the audio thread to shut down, since the actual processing happens in /// A simple message to tell the audio thread to shut down, since the actual processing happens in
@ -100,9 +106,11 @@ impl Backend for Jack {
} }
impl Jack { impl Jack {
/// Initialize the JACK backend. Returns an error if this failed for whatever reason. /// Initialize the JACK backend. Returns an error if this failed for whatever reason. The plugin
pub fn new(name: &str, config: WrapperConfig) -> Result<Self> { /// generic argument is to get the name for the client, and to know whether or not the
let (client, status) = Client::new(name, ClientOptions::NO_START_SERVER) /// standalone should expose JACK MIDI ports.
pub fn new<P: Plugin>(config: WrapperConfig) -> Result<Self> {
let (client, status) = Client::new(P::NAME, ClientOptions::NO_START_SERVER)
.context("Error while initializing the JACK client")?; .context("Error while initializing the JACK client")?;
if !status.is_empty() { if !status.is_empty() {
anyhow::bail!("The JACK server returned an error: {status:?}"); anyhow::bail!("The JACK server returned an error: {status:?}");
@ -125,6 +133,21 @@ impl Jack {
outputs.push(port); outputs.push(port);
} }
// TODO: CLI arguments to connect the MIDI input and output ports
let midi_input = if P::MIDI_INPUT >= MidiConfig::Basic {
Some(Arc::new(client.register_port("midi_input", MidiIn)?))
} else {
None
};
let midi_output = if P::MIDI_OUTPUT >= MidiConfig::Basic {
Some(Arc::new(AtomicRefCell::new(
client.register_port("midi_output", MidiOut)?,
)))
} else {
None
};
// This option can either be set to a single port all inputs should be connected to, or a // This option can either be set to a single port all inputs should be connected to, or a
// comma separated list of ports // comma separated list of ports
if let Some(port_name) = config.connect_jack_inputs { if let Some(port_name) = config.connect_jack_inputs {
@ -150,6 +173,8 @@ impl Jack {
inputs: Arc::new(inputs), inputs: Arc::new(inputs),
outputs: Arc::new(AtomicRefCell::new(outputs)), outputs: Arc::new(AtomicRefCell::new(outputs)),
midi_input,
midi_output,
}) })
} }
} }