Hello,
I have a tricky question. Let me know if there’s anything I can do to help explain etc.
I’m trying to make a fork of PortAudio that uses callback functions. You can see my progress here:
When I run the following code in test/runtests_local.jl
using PortAudio
PortAudioStream(input(), output()) do input_buffer, output_buffer, framecount, time_info, callback_flags, userdata
return paComplete
end
I get a segfault:
fish: “/home/brandon/julia-1.6.0/bin/j…” terminated by signal SIGSEGV (Address boundary error)
I think the problem is most likely confusion on my part about how @cfunction
works; this is the first time I’ve used it.
My code to wrap a Julia function as a PortAudio call-back function is below. I do a bit of conversion to allow users to access data rather than the underlying pointers.
function wrap_callback(callback, ::Type{UserData}, ::Type{Sample}) where {UserData, Sample}
@cfunction(
function (
input_buffer_pointer,
output_buffer_pointer,
framecount,
time_info_pointer,
status_flags,
user_data_pointer
)
PaStreamCallbackResult(callback(
unsafe_wrap(Array, input_buffer_pointer, 2),
unsafe_wrap(Array, output_buffer_pointer, 2),
framecount,
unsafe_pointer_to_objref(time_info_pointer),
StreamCallbackFlags(status_flags),
if user_data_pointer === C_NULL
nothing
else
unsafe_pointer_to_objref(user_data_pointer)
end
))
end,
PaStreamCallbackResult, # returns
(
Ptr{Sample}, # input buffer pointer
Ptr{Sample}, # output buffer pointer
Culong, # framecount
Ptr{PaStreamCallbackTimeInfo}, # time info pointer
PaStreamCallbackFlags, # status flags
Ptr{UserData}, # userdata pointer
)
)
end
The PortAudio docs on writing a callback function are here:
http://portaudio.com/docs/v19-doxydocs/writing_a_callback.html
They state:
Your callback function must return an int and accept the exact parameters specified in this typedef:
typedef int PaStreamCallback( const void *input,
void *output,
unsigned long frameCount,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData ) ;