Friends
I am doing some audio programming and I wish to develop a Jack audio client.
For my purposes my client has to be the Jack timebase master. The details and ins and outs of Jack are not the issue here, but the use of the FFI and callbacks into and from the C API.
The crate jack-sys
has the facilities I require, if I could work out how to use them.
I need to call the function: jack_sys::jack_set_timebase_callback
and pass it a callback function (it would be a function pointer if I were in C) and a bit of other data.
I cannot figure out how to do it.
This is what I have attempted:
With my callback function:
fn timebase_callback(
state: jack_sys::jack_transport_state_t,
nframes: jack_sys::jack_nframes_t,
pos: *mut jack_sys::jack_position_t,
new_pos: c_int,
arg: *mut c_void,
) {
println!(
"time_base_callback(.., {}, {:?}, {}, {:?});",
nframes, pos, new_pos, arg
);
}
Utilising it:
let (client, _status) =
jack::Client::new("rust_jack_trans", jack::ClientOptions::NO_START_SERVER).unwrap();
struct MyVoidPtr;
let mut my_ptr = MyVoidPtr;
let my_void_ptr: *mut c_void = &mut my_ptr as *mut _ as *mut c_void;
jack_sys::jack_set_timebase_callback(client.raw(), 1, Some(timebase_callback), my_void_ptr);
The definition of the callback is incorrect. The error (below in full) says it expects "C" fn and found "Rust fn. Ok. I would like to pass a pointer to my rust function. I clearly am not doing it correctly. How do I do it?
Also while I do not care much about the void pointer for the arguments, yet, the definition of of my_void_ptr
seems to be a magic incantation. How does it work?
error[E0308]: mismatched types
--> src/main.rs:111:64
|
111 | jack_sys::jack_set_timebase_callback(client.raw(), 1, Some(timebase_callback), my_void_ptr);
| ^^^^^^^^^^^^^^^^^ expected "C" fn, found "Rust" fn
|
= note: expected fn pointer `unsafe extern "C" fn(_, _, _, _, _)`
found fn item `fn(_, _, _, _, _) {timebase_callback}`