Skip to content

Commit

Permalink
Remove Sync requirement from ProcessHandler. (#121) (#127)
Browse files Browse the repository at this point in the history
  • Loading branch information
Windfisch authored Sep 5, 2020
1 parent 41fab12 commit 0b60934
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 17 deletions.
2 changes: 1 addition & 1 deletion src/client/async_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub struct AsyncClient<N, P> {
impl<N, P> AsyncClient<N, P>
where
N: 'static + Send + Sync + NotificationHandler,
P: 'static + Send + Sync + ProcessHandler,
P: 'static + Send + ProcessHandler,
{
/// Tell the JACK server that the program is ready to start processing audio. JACK will call the
/// methods specified by the `NotificationHandler` and `ProcessHandler` objects.
Expand Down
28 changes: 14 additions & 14 deletions src/client/callbacks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ pub trait ProcessHandler: Send {
unsafe extern "C" fn thread_init_callback<N, P>(data: *mut libc::c_void)
where
N: 'static + Send + Sync + NotificationHandler,
P: 'static + Send + Sync + ProcessHandler,
P: 'static + Send + ProcessHandler,
{
let ctx = CallbackContext::<N, P>::from_raw(data);
ctx.notification.thread_init(&ctx.client)
Expand All @@ -167,7 +167,7 @@ unsafe extern "C" fn shutdown<N, P>(
data: *mut libc::c_void,
) where
N: 'static + Send + Sync + NotificationHandler,
P: 'static + Send + Sync + ProcessHandler,
P: 'static + Send + ProcessHandler,
{
let ctx = CallbackContext::<N, P>::from_raw(data);
let cstr = ffi::CStr::from_ptr(reason);
Expand All @@ -184,7 +184,7 @@ unsafe extern "C" fn shutdown<N, P>(
unsafe extern "C" fn process<N, P>(n_frames: Frames, data: *mut libc::c_void) -> libc::c_int
where
N: 'static + Send + Sync + NotificationHandler,
P: 'static + Send + Sync + ProcessHandler,
P: 'static + Send + ProcessHandler,
{
let ctx = CallbackContext::<N, P>::from_raw(data);
let scope = ProcessScope::from_raw(n_frames, ctx.client.raw());
Expand All @@ -194,7 +194,7 @@ where
unsafe extern "C" fn freewheel<N, P>(starting: libc::c_int, data: *mut libc::c_void)
where
N: 'static + Send + Sync + NotificationHandler,
P: 'static + Send + Sync + ProcessHandler,
P: 'static + Send + ProcessHandler,
{
let ctx = CallbackContext::<N, P>::from_raw(data);
let is_starting = match starting {
Expand All @@ -207,7 +207,7 @@ where
unsafe extern "C" fn buffer_size<N, P>(n_frames: Frames, data: *mut libc::c_void) -> libc::c_int
where
N: 'static + Send + Sync + NotificationHandler,
P: 'static + Send + Sync + ProcessHandler,
P: 'static + Send + ProcessHandler,
{
let ctx = CallbackContext::<N, P>::from_raw(data);
ctx.notification.buffer_size(&ctx.client, n_frames).to_ffi()
Expand All @@ -216,7 +216,7 @@ where
unsafe extern "C" fn sample_rate<N, P>(n_frames: Frames, data: *mut libc::c_void) -> libc::c_int
where
N: 'static + Send + Sync + NotificationHandler,
P: 'static + Send + Sync + ProcessHandler,
P: 'static + Send + ProcessHandler,
{
let ctx = CallbackContext::<N, P>::from_raw(data);
ctx.notification.sample_rate(&ctx.client, n_frames).to_ffi()
Expand All @@ -228,7 +228,7 @@ unsafe extern "C" fn client_registration<N, P>(
data: *mut libc::c_void,
) where
N: 'static + Send + Sync + NotificationHandler,
P: 'static + Send + Sync + ProcessHandler,
P: 'static + Send + ProcessHandler,
{
let ctx = CallbackContext::<N, P>::from_raw(data);
let name = ffi::CStr::from_ptr(name).to_str().unwrap();
Expand All @@ -246,7 +246,7 @@ unsafe extern "C" fn port_registration<N, P>(
data: *mut libc::c_void,
) where
N: 'static + Send + Sync + NotificationHandler,
P: 'static + Send + Sync + ProcessHandler,
P: 'static + Send + ProcessHandler,
{
let ctx = CallbackContext::<N, P>::from_raw(data);
let register = match register {
Expand All @@ -266,7 +266,7 @@ unsafe extern "C" fn port_rename<N, P>(
) -> libc::c_int
where
N: 'static + Send + Sync + NotificationHandler,
P: 'static + Send + Sync + ProcessHandler,
P: 'static + Send + ProcessHandler,
{
let ctx = CallbackContext::<N, P>::from_raw(data);
let old_name = ffi::CStr::from_ptr(old_name).to_str().unwrap();
Expand All @@ -283,7 +283,7 @@ unsafe extern "C" fn port_connect<N, P>(
data: *mut libc::c_void,
) where
N: 'static + Send + Sync + NotificationHandler,
P: 'static + Send + Sync + ProcessHandler,
P: 'static + Send + ProcessHandler,
{
let ctx = CallbackContext::<N, P>::from_raw(data);
let are_connected = match connect {
Expand All @@ -297,7 +297,7 @@ unsafe extern "C" fn port_connect<N, P>(
unsafe extern "C" fn graph_order<N, P>(data: *mut libc::c_void) -> libc::c_int
where
N: 'static + Send + Sync + NotificationHandler,
P: 'static + Send + Sync + ProcessHandler,
P: 'static + Send + ProcessHandler,
{
let ctx = CallbackContext::<N, P>::from_raw(data);
ctx.notification.graph_reorder(&ctx.client).to_ffi()
Expand All @@ -306,7 +306,7 @@ where
unsafe extern "C" fn xrun<N, P>(data: *mut libc::c_void) -> libc::c_int
where
N: 'static + Send + Sync + NotificationHandler,
P: 'static + Send + Sync + ProcessHandler,
P: 'static + Send + ProcessHandler,
{
let ctx = CallbackContext::<N, P>::from_raw(data);
ctx.notification.xrun(&ctx.client).to_ffi()
Expand All @@ -315,7 +315,7 @@ where
unsafe extern "C" fn latency<N, P>(mode: j::jack_latency_callback_mode_t, data: *mut libc::c_void)
where
N: 'static + Send + Sync + NotificationHandler,
P: 'static + Send + Sync + ProcessHandler,
P: 'static + Send + ProcessHandler,
{
let ctx = CallbackContext::<N, P>::from_raw(data);
let mode = match mode {
Expand Down Expand Up @@ -354,7 +354,7 @@ pub struct CallbackContext<N, P> {
impl<N, P> CallbackContext<N, P>
where
N: 'static + Send + Sync + NotificationHandler,
P: 'static + Send + Sync + ProcessHandler,
P: 'static + Send + ProcessHandler,
{
pub unsafe fn from_raw<'a>(ptr: *mut libc::c_void) -> &'a mut CallbackContext<N, P> {
debug_assert!(!ptr.is_null());
Expand Down
2 changes: 1 addition & 1 deletion src/client/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ impl Client {
) -> Result<AsyncClient<N, P>, Error>
where
N: 'static + Send + Sync + NotificationHandler,
P: 'static + Send + Sync + ProcessHandler,
P: 'static + Send + ProcessHandler,
{
AsyncClient::new(self, notification_handler, process_handler)
}
Expand Down
9 changes: 9 additions & 0 deletions src/jack_enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ pub enum LatencyType {
Playback,
}

impl LatencyType {
pub fn to_ffi(self) -> libc::c_uint {
match self {
LatencyType::Playback => jack_sys::JackPlaybackLatency,
LatencyType::Capture => jack_sys::JackCaptureLatency,
}
}
}

/// Specify an option, either to continue processing, or to stop.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Control {
Expand Down
29 changes: 28 additions & 1 deletion src/port/port.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::marker::Sized;
use std::sync::Weak;
use std::{ffi, fmt, iter};

use crate::{Error, Frames, PortFlags};
use crate::{Error, Frames, LatencyType, PortFlags};

lazy_static! {
/// The maximum string length for port names.
Expand Down Expand Up @@ -273,6 +273,33 @@ impl<PS> Port<PS> {
j::jack_port_get_buffer(self.port_ptr, n_frames)
}

/// Set the minimum and maximum latencies defined by mode for port, in frames.
/// The `range` argument is a tuple of `(min, max)`.
///
/// See [Managing and determining latency](https://jackaudio.org/api/group__LatencyFunctions.html)
/// for a description of what the latency values mean and some best practices. This function should
/// **only** be used inside a latency callback.
#[inline(always)]
pub fn set_latency_range(&self, mode: LatencyType, range: (Frames, Frames)) {
let mut ffi_range = j::Struct__jack_latency_range {
min: range.0,
max: range.1,
};
unsafe { j::jack_port_set_latency_range(self.port_ptr, mode.to_ffi(), &mut ffi_range) };
}

/// Returns a tuple of the minimum and maximum latencies defined by mode for port, in frames.
///
/// See [Managing and determining latency](https://jackaudio.org/api/group__LatencyFunctions.html)
/// for a description of what the latency values mean and some best practices. This is normally
/// used in the LatencyCallback. and therefore safe to execute from callbacks.
#[inline(always)]
pub fn get_latency_range(&self, mode: LatencyType) -> (Frames, Frames) {
let mut ffi_range = j::Struct__jack_latency_range { min: 0, max: 0 };
unsafe { j::jack_port_get_latency_range(self.port_ptr, mode.to_ffi(), &mut ffi_range) };
return (ffi_range.min, ffi_range.max);
}

fn check_client_life(&self) -> Result<(), Error> {
self.client_life
.upgrade()
Expand Down

0 comments on commit 0b60934

Please sign in to comment.