Skip to content

Dynamically load JACK. #162

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 23 commits into from
Feb 6, 2022
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ env:
jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v2
Expand All @@ -21,8 +20,22 @@ jobs:
- name: Start dummy JACK server
run: jackd -r -ddummy -r44100 -p1024 &
- name: Lint
run: cargo clippy --all-targets --all-features -- -D clippy::all
run: |
cargo clippy --all-targets -- -D clippy::all
cargo clippy --all-targets --features dlopen -- -D clippy::all
cargo clippy --all-targets --features metadata -- -D clippy::all
cargo clippy --all-targets --features dlopen,metadata -- -D clippy::all
- name: Build
run: cargo build --verbose
run: |
cargo build --verbose
cargo build --verbose --features dlopen
cargo build --verbose --features metadata
cargo build --verbose --features dlopen,metadata
- name: Run Tests
run: RUST_TEST_THREADS=1 cargo test --verbose
- name: Run Tests with dlopen
run: RUST_TEST_THREADS=1 cargo test --features dlopen --verbose
- name: Run Tests with metadata
run: RUST_TEST_THREADS=1 cargo test --features metadata --verbose
- name: Run Tests with dlopen and metadata
run: RUST_TEST_THREADS=1 cargo test --features dlopen,metadata --verbose
8 changes: 6 additions & 2 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
# Changelog

## HEAD
- Updated dependencies to latest as of 2021/11/17.
## 0.9.0

- Jack library can be loaded dynamically from libjack.so.0 or libjack.dll.
- Updated dependencies to latest as of 2022/02/05.

## 0.8.2

- `MidiIter` is now `Sync`.

## 0.8.1

- `AsyncClient` and `Client` are `Sync`.

## 0.8.0
Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ license = "MIT"
name = "jack"
readme = "README.md"
repository = "https://github.com/RustAudio/rust-jack"
version = "0.8.4"
version = "0.9.0"

[dependencies]
bitflags = "1"
Expand All @@ -23,4 +23,5 @@ crossbeam-channel = "0.5"

[features]
default = []
dlopen = ["jack-sys/dlopen"]
metadata = []
2 changes: 1 addition & 1 deletion jack-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0"
links = "jack"
name = "jack-sys"
repository = "https://github.com/RustAudio/rust-jack/tree/main/jack-sys"
version = "0.3.0"
version = "0.3.2"

[dependencies]
dlib = "0.5"
Expand Down
1 change: 1 addition & 0 deletions jack-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ fn main() {
// Refer to https://github.com/RustAudio/rust-jack/issues/142 for details.
// Do not unwrap this because linking might still work if pkg-config is
// not installed, for example on Windows.
#[cfg(not(feature = "dlopen"))]
let _ = pkg_config::probe_library("jack");
}
241 changes: 133 additions & 108 deletions jack-sys/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
#![allow(non_camel_case_types, non_upper_case_globals)]
#![allow(non_camel_case_types, non_upper_case_globals, non_snake_case)]

use dlib::external_library;
use lazy_static::lazy_static;

pub const JACK_LIB: &'static str =
if cfg!(target_family = "windows") {
if cfg!(target_arch = "x86") {
"libjack.dll"
} else {
"libjack64.dll"
}
} else if cfg!(target_vendor = "apple") {
"libjack.0.dylib"
} else {
"libjack.so.0"
};

/// JACK port type for 8 bit raw midi
pub static RAW_MIDI_TYPE: &str = "8 bit raw midi";

Expand Down Expand Up @@ -512,6 +525,101 @@ external_library!(
jack_info_callback: Option<unsafe extern "C" fn(*const ::libc::c_char) -> ()>,
);

external_library!(
JackCtl,
"jack",
functions:
fn jackctl_setup_signals(::libc::c_uint) -> *mut jackctl_sigmask_t,
fn jackctl_wait_signals(*mut jackctl_sigmask_t) -> (),
fn jackctl_server_create(
::std::option::Option<
unsafe extern "C" fn(*const ::libc::c_char) -> u8,
>,
::std::option::Option<
unsafe extern "C" fn(*const ::libc::c_char) -> (),
>
) -> *mut jackctl_server_t,
fn jackctl_server_destroy(*mut jackctl_server_t) -> (),
fn jackctl_server_open(*mut jackctl_server_t, *mut jackctl_driver_t) -> u8,
fn jackctl_server_start(*mut jackctl_server_t) -> u8,
fn jackctl_server_stop(*mut jackctl_server_t) -> u8,
fn jackctl_server_close(*mut jackctl_server_t) -> u8,
fn jackctl_server_get_drivers_list(*mut jackctl_server_t) -> *const JSList,
fn jackctl_server_get_parameters(*mut jackctl_server_t) -> *const JSList,
fn jackctl_server_get_internals_list(*mut jackctl_server_t) -> *const JSList,
fn jackctl_server_load_internal(
*mut jackctl_server_t,
*mut jackctl_internal_t
) -> u8,
fn jackctl_server_unload_internal(
*mut jackctl_server_t,
*mut jackctl_internal_t
) -> u8,
fn jackctl_server_add_slave(
*mut jackctl_server_t,
*mut jackctl_driver_t
) -> u8,
fn jackctl_server_remove_slave(
*mut jackctl_server_t,
*mut jackctl_driver_t
) -> u8,
fn jackctl_server_switch_master(
*mut jackctl_server_t,
*mut jackctl_driver_t
) -> u8,
fn jackctl_driver_get_name( *mut jackctl_driver_t) -> *const ::libc::c_char,
fn jackctl_driver_get_type( *mut jackctl_driver_t) -> jackctl_driver_type_t,
fn jackctl_driver_get_parameters( *mut jackctl_driver_t) -> *const JSList,
fn jackctl_driver_params_parse(
*mut jackctl_driver_t,
::libc::c_int,
*mut *mut ::libc::c_char
) -> ::libc::c_int,
fn jackctl_internal_get_name(*mut jackctl_internal_t) -> *const ::libc::c_char,
fn jackctl_internal_get_parameters(*mut jackctl_internal_t) -> *const JSList,
fn jackctl_parameter_get_name(*mut jackctl_parameter_t)
-> *const ::libc::c_char,
fn jackctl_parameter_get_short_description(
*mut jackctl_parameter_t
) -> *const ::libc::c_char,
fn jackctl_parameter_get_long_description(
*mut jackctl_parameter_t
) -> *const ::libc::c_char,
fn jackctl_parameter_get_type(*mut jackctl_parameter_t) -> jackctl_param_type_t,
fn jackctl_parameter_get_id(*mut jackctl_parameter_t) -> ::libc::c_char,
fn jackctl_parameter_is_set(*mut jackctl_parameter_t) -> u8,
fn jackctl_parameter_reset(*mut jackctl_parameter_t) -> u8,
fn jackctl_parameter_get_value(
*mut jackctl_parameter_t
) -> Union_jackctl_parameter_value,
fn jackctl_parameter_set_value(
*mut jackctl_parameter_t,
*const Union_jackctl_parameter_value
) -> u8,
fn jackctl_parameter_get_default_value(
*mut jackctl_parameter_t
) -> Union_jackctl_parameter_value,
fn jackctl_parameter_has_range_constraint(*mut jackctl_parameter_t) -> u8,
fn jackctl_parameter_has_enum_constraint(*mut jackctl_parameter_t) -> u8,
fn jackctl_parameter_get_enum_constraints_count(*mut jackctl_parameter_t)
-> u32,
fn jackctl_parameter_get_enum_constraint_value(
*mut jackctl_parameter_t,
u32
) -> Union_jackctl_parameter_value,
fn jackctl_parameter_get_enum_constraint_description(
*mut jackctl_parameter_t,
u32
) -> *const ::libc::c_char,
fn jackctl_parameter_get_range_constraint(
*mut jackctl_parameter_t,
*mut Union_jackctl_parameter_value,
*mut Union_jackctl_parameter_value
) -> (),
fn jackctl_parameter_constraint_is_strict(*mut jackctl_parameter_t) -> u8,
fn jackctl_parameter_constraint_is_fake_value(*mut jackctl_parameter_t) -> u8,
);

external_library!(
JackLib,
"jack",
Expand Down Expand Up @@ -553,13 +661,6 @@ external_library!(
*mut jack_client_t,
*mut jack_transport_info_t
) -> (),
fn jack_get_version(
*mut ::libc::c_int,
*mut ::libc::c_int,
*mut ::libc::c_int,
*mut ::libc::c_int
) -> (),
fn jack_get_version_string() -> *const ::libc::c_char,
fn jack_client_new( *const ::libc::c_char) -> *mut jack_client_t,
fn jack_client_close( *mut jack_client_t) -> ::libc::c_int,
fn jack_client_name_size() -> ::libc::c_int,
Expand All @@ -580,7 +681,6 @@ external_library!(
fn jack_internal_client_close( *const ::libc::c_char) -> (),
fn jack_activate( *mut jack_client_t) -> ::libc::c_int,
fn jack_deactivate( *mut jack_client_t) -> ::libc::c_int,
fn jack_get_client_pid( *const ::libc::c_char) -> ::libc::c_int,
// #[cfg(not(target_os = "windows"))]
// fn jack_client_thread_id( *mut jack_client_t) -> jack_native_thread_t,
fn jack_is_realtime( *mut jack_client_t) -> ::libc::c_int,
Expand Down Expand Up @@ -691,7 +791,6 @@ external_library!(
fn jack_port_short_name( *const jack_port_t) -> *const ::libc::c_char,
fn jack_port_flags( *const jack_port_t) -> ::libc::c_int,
fn jack_port_type( *const jack_port_t) -> *const ::libc::c_char,
fn jack_port_type_id( *const jack_port_t) -> jack_port_type_id_t,
fn jack_port_is_mine(
*const jack_client_t,
*const jack_port_t
Expand Down Expand Up @@ -859,95 +958,6 @@ external_library!(
*mut jack_client_t,
*const ::libc::c_char
) -> ::libc::c_int,
fn jackctl_setup_signals(::libc::c_uint) -> *mut jackctl_sigmask_t,
fn jackctl_wait_signals(*mut jackctl_sigmask_t) -> (),
fn jackctl_server_create(
::std::option::Option<
unsafe extern "C" fn(*const ::libc::c_char) -> u8,
>,
::std::option::Option<
unsafe extern "C" fn(*const ::libc::c_char) -> (),
>
) -> *mut jackctl_server_t,
fn jackctl_server_destroy(*mut jackctl_server_t) -> (),
fn jackctl_server_open(*mut jackctl_server_t, *mut jackctl_driver_t) -> u8,
fn jackctl_server_start(*mut jackctl_server_t) -> u8,
fn jackctl_server_stop(*mut jackctl_server_t) -> u8,
fn jackctl_server_close(*mut jackctl_server_t) -> u8,
fn jackctl_server_get_drivers_list(*mut jackctl_server_t) -> *const JSList,
fn jackctl_server_get_parameters(*mut jackctl_server_t) -> *const JSList,
fn jackctl_server_get_internals_list(*mut jackctl_server_t) -> *const JSList,
fn jackctl_server_load_internal(
*mut jackctl_server_t,
*mut jackctl_internal_t
) -> u8,
fn jackctl_server_unload_internal(
*mut jackctl_server_t,
*mut jackctl_internal_t
) -> u8,
fn jackctl_server_add_slave(
*mut jackctl_server_t,
*mut jackctl_driver_t
) -> u8,
fn jackctl_server_remove_slave(
*mut jackctl_server_t,
*mut jackctl_driver_t
) -> u8,
fn jackctl_server_switch_master(
*mut jackctl_server_t,
*mut jackctl_driver_t
) -> u8,
fn jackctl_driver_get_name( *mut jackctl_driver_t) -> *const ::libc::c_char,
fn jackctl_driver_get_type( *mut jackctl_driver_t) -> jackctl_driver_type_t,
fn jackctl_driver_get_parameters( *mut jackctl_driver_t) -> *const JSList,
fn jackctl_driver_params_parse(
*mut jackctl_driver_t,
::libc::c_int,
*mut *mut ::libc::c_char
) -> ::libc::c_int,
fn jackctl_internal_get_name(*mut jackctl_internal_t) -> *const ::libc::c_char,
fn jackctl_internal_get_parameters(*mut jackctl_internal_t) -> *const JSList,
fn jackctl_parameter_get_name(*mut jackctl_parameter_t)
-> *const ::libc::c_char,
fn jackctl_parameter_get_short_description(
*mut jackctl_parameter_t
) -> *const ::libc::c_char,
fn jackctl_parameter_get_long_description(
*mut jackctl_parameter_t
) -> *const ::libc::c_char,
fn jackctl_parameter_get_type(*mut jackctl_parameter_t) -> jackctl_param_type_t,
fn jackctl_parameter_get_id(*mut jackctl_parameter_t) -> ::libc::c_char,
fn jackctl_parameter_is_set(*mut jackctl_parameter_t) -> u8,
fn jackctl_parameter_reset(*mut jackctl_parameter_t) -> u8,
fn jackctl_parameter_get_value(
*mut jackctl_parameter_t
) -> Union_jackctl_parameter_value,
fn jackctl_parameter_set_value(
*mut jackctl_parameter_t,
*const Union_jackctl_parameter_value
) -> u8,
fn jackctl_parameter_get_default_value(
*mut jackctl_parameter_t
) -> Union_jackctl_parameter_value,
fn jackctl_parameter_has_range_constraint(*mut jackctl_parameter_t) -> u8,
fn jackctl_parameter_has_enum_constraint(*mut jackctl_parameter_t) -> u8,
fn jackctl_parameter_get_enum_constraints_count(*mut jackctl_parameter_t)
-> u32,
fn jackctl_parameter_get_enum_constraint_value(
*mut jackctl_parameter_t,
u32
) -> Union_jackctl_parameter_value,
fn jackctl_parameter_get_enum_constraint_description(
*mut jackctl_parameter_t,
u32
) -> *const ::libc::c_char,
fn jackctl_parameter_get_range_constraint(
*mut jackctl_parameter_t,
*mut Union_jackctl_parameter_value,
*mut Union_jackctl_parameter_value
) -> (),
fn jackctl_parameter_constraint_is_strict(*mut jackctl_parameter_t) -> u8,
fn jackctl_parameter_constraint_is_fake_value(*mut jackctl_parameter_t) -> u8,
// fn jack_error(format: *const ::libc::c_char, ...) -> (),
// fn jack_info(format: *const ::libc::c_char, ...) -> (),
// fn jack_log(format: *const ::libc::c_char, ...) -> (),
Expand Down Expand Up @@ -1011,7 +1021,6 @@ external_library!(
u32
) -> ::libc::c_int,
fn jack_midi_clear_buffer(*mut ::libc::c_void) -> (),
fn jack_midi_reset_buffer(*mut ::libc::c_void) -> (),
fn jack_midi_max_event_size(*mut ::libc::c_void) -> ::libc::size_t,
fn jack_midi_event_reserve(
*mut ::libc::c_void,
Expand Down Expand Up @@ -1049,7 +1058,6 @@ external_library!(
fn jack_ringbuffer_read_space( *const jack_ringbuffer_t) -> ::libc::size_t,
fn jack_ringbuffer_mlock( *mut jack_ringbuffer_t) -> ::libc::c_int,
fn jack_ringbuffer_reset( *mut jack_ringbuffer_t) -> (),
fn jack_ringbuffer_reset_size( *mut jack_ringbuffer_t, ::libc::size_t) -> (),
fn jack_ringbuffer_write(
*mut jack_ringbuffer_t,
*const ::libc::c_char,
Expand Down Expand Up @@ -1084,13 +1092,30 @@ external_library!(
fn jack_uuid_empty(jack_uuid_t) -> ::std::os::raw::c_int,
);

// Load optional functions:

#[cfg(windows)]
const jack_lib: &'static str = "libjack.dll";
#[cfg(feature = "dlopen")]
impl std::fmt::Debug for JackLib {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("JackLib").finish()
}
}

#[cfg(unix)]
const jack_lib: &'static str = "libjack.so\0";
// The following functions are not available in some JACK versions. Use with caution.
external_library!(
JackOptional,
"jack",
functions:
fn jack_get_version(
*mut ::libc::c_int,
*mut ::libc::c_int,
*mut ::libc::c_int,
*mut ::libc::c_int
) -> (),
fn jack_get_version_string() -> *const ::libc::c_char,
fn jack_get_client_pid( *const ::libc::c_char) -> ::libc::c_int,
fn jack_port_type_id( *const jack_port_t) -> jack_port_type_id_t,
fn jack_midi_reset_buffer(*mut ::libc::c_void) -> (),
fn jack_ringbuffer_reset_size( *mut jack_ringbuffer_t, ::libc::size_t) -> (),
);

type jack_get_cycle_times_t = unsafe extern "C" fn(
client: *const jack_client_t,
Expand All @@ -1102,7 +1127,7 @@ type jack_get_cycle_times_t = unsafe extern "C" fn(

lazy_static! {
pub static ref jack_get_cycle_times: Option<jack_get_cycle_times_t> = {
unsafe { libloading::Library::new(jack_lib) }
unsafe { libloading::Library::new(JACK_LIB) }
.ok()
.and_then(|lib| unsafe {
lib.get::<jack_get_cycle_times_t>(b"jack_get_cycle_times\0")
Expand Down
Loading