-
Notifications
You must be signed in to change notification settings - Fork 20
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
Support call-back functions? #56
Comments
I've been playing around with this on my fork of PortAudio here: https://github.com/bramtayl/PortAudio.jl I'm totally new at interfacing with C from Julia, and I get immediate segfaults as soon as I try anything:
I'll see what I can figure out about what went wrong, but if anyone has some tips that could be helpful. |
well, I'm pretty sure this won't be feasible. see https://discourse.julialang.org/t/cfunction-help/60263 for more info. |
Thanks for taking the time to document your efforts. It's very informative. |
OK - buckle up. So the main issue with using portaudio's callback interface is that the callback is called from a separate thread. In the pre-threading days Julia's runtime was not at all thread-safe, so for instance you might try to allocate memory in the callback at the same time as the main Julia thread, and everything would crash. Now that Julia has multithreading support I think they've made most of those functions threadsafe, but I think there's still some bookkeeping that's supposed to be done for each thread that Julia knows about, and it's still not kosher to have some other random thread running Julia code. Over time I've tried a couple different approaches to this. In the beginning I wrote the callback in Julia and was just very careful not to do anything that would allocate, and made sure everything was type-stable so there was no dynamic dispatch. This actually worked, but was very finicky. Often I'd make some seemingly-innocuous change and it would start segfaulting. So that's a brief history of portaudio interface attempts. :) |
Aha! I wonder if there would be a way to get the thread "bookkeeping" done correctly, especially now with multi-threading support? |
@Gnimuc was helping me here and might be interested |
The docs here seem helpful: https://docs.julialang.org/en/v1/manual/calling-c-and-fortran-code/#Thread-safety |
Interesting! The original post that gives rise to that doc is also portaudio-related: https://groups.google.com/g/julia-users/c/ztN-UgS9N8c/m/01bM77Vw6UgJ?pli=1 |
Should have known that @ssfrr was behind this! I can't understand documentation about |
In general the idea is that a task can So rather than processing data within the callback, you have a Julia task with a loop that processes some data, then waits on the condition, over and over. The condition is notified every time new data is available (every audio frame in this case). The notification happens in the callback. |
Right so then how would you pass inputs and outputs back and forth between the callback and the task? |
Yeah, that’s tricky. RingBuffers.jl has both a Julia interface and a C interface, so libportaudio called a callback written in C that exchanged data with the ring buffer and then notified the Julia task with an AsyncCondition. |
Julia now supports foreign threads. JuliaLang/julia#17573 |
Yeah I saw that too! I might try it out on nightly in a few days unless someone gets to it first! |
At least according to the PortAudio documentation, using a call-back function to access buffers seems like it would be more performant
The text was updated successfully, but these errors were encountered: