-
Notifications
You must be signed in to change notification settings - Fork 62
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
Share PCM between multiple threads #33
Comments
So...this sounds like a case for my direct PCM API, which bypasses alsa-lib and talks directly to the kernel. That way I can guarantee that the structs are Send + Sync. Have you seen the direct::pcm module? |
(There is also a synth example to help you understand how direct::pcm works) |
Yes thanks for the suggestion, I hope to use the direct PCM API later when optimizing for performance and latency. Therefore alsa-lib readi/writei it is at least for now! I added unsafe impl Sync for PCM {} in src/pcm.rs with good results, for the audio-time rust port: https://github.com/supercurio/asrc-rs-research/blob/master/src/alsa_audio_time.rs Unfortunately, on the Odroid C2 multi-threaded access tends to introduce xruns. It's the same with alsa-lib pcm-multi-thread.c utility. On the Raspberry Pi also but to a much lesser extent, on my desktop machine there's xrun sometimes showing as well. Do you think there would be reasons for not adding |
When it comes to thread safety bugs, they usually don't show up immediately, but rather every half a year or so at a customer site. You have been warned.
You can use
Yes. For one, I use a Cell myself. :-) But that can be changed if necessary. More specifically, the "thread safety" of the snd_pcm_xxx APIs were a bit retrofitted in ways I'm not entirely comfortably with. It's not documented exactly what functions can be called in parallel with others. Better stay safe. |
Ohh I understand better now the synth example, where you only deal with the file descriptor instead of the PCM struct. And from this fd it is possible to call the direct rust implementation that's not built on top of alsa-lib but uses ioctl with the kernel.
True. I'm not sure how to interpret the doc's statement: "The function is thread-safe when built with the proper option." What does proper option mean?
I'll try that now, thanks :)
I'm still a beginner with Rust concurrency: do you mean that by Cell you have the intent of only one use at the time as the content of the cell is take away while in use? |
On the ODROID-C2 HDMI, Raspberry Pi3+ HDMI and USB audio: Error("driver memory mmap", UnsupportedOperation)' I might have to do without this multi-threaded approach then. |
Correct. Assuming the kernel is free from thread safety bugs, that is.
I believe it refers to this config option although it might not tell you much if you're not used to rebuilding C libraries. Long story short, should be enabled by default given a recent enough alsa-lib.
Explaining what a Cell is used for and why it's not Sync is a bit more than what I have time to explain here and now :-)
Really? HDMI drivers (especially for embedded stuff) may vary, but the standard USB audio driver does definitely support mmap. And it does not make sense for Raspberry Pi3 kernels to disable it. |
You can still protect the |
You're right, thread safety should be enabled in most setups, where alsa-lib is likely built with pthread support and thread safety is not explicitly disabled. Tho not all setups.
ODROID-C2 HDMI audioI does not support mmap, but The Pi HDMI and USB audio does indeed.
Yes I tried that too, however since readi and writei are blocking calls looped, they almost always hold the mutex loop which effectively makes the PCM single-threaded ;) For the use case described, experimentation showed that a multi-threaded approach is not suitable. The main reason observed is that sometimes, the pcm.status() calls happens at the same time as readi or writei which introduces a delay leading to Xruns. |
No idea. But even if it was, I'm not 100% certain that alsa-lib's notion of "thread safe" is the same as Rust's
I doubt it. It should be possible to get a better error message out of mmap. Let me see if I have time to fix that.
I mean like this (where
...here the waiting is done inside |
Out of curiousity, what kind of latency are you trying with (both unsuccessfully, and what you have to back down to, to make it work)? As a side track, you might be interested in a low-latency experiment I did some time ago: https://github.com/diwic/core-isolation |
Awesome, thanks for looking into the mmap error. And the polling approach you showed could get handy at some point as well :) There's some latency targets for MultiDSP, but I kinda made up some. |
I just pushed a commit that should help us understand why mmap fails, or at least give us a hint in the right direction. |
Closing due to inactivity. |
Hi @diwic !
I'd like to access PCMs from multiple threads (at least two) in order to:
In order to do that, there will be three threads.
Therefore, both capture and playback PCMs need to be shared with the status gathering thread, that'll periodically adjust an asynchronous resampler ratio.
In alsa-lib tests, the pcm-multi-thread.c example shows how it is possible in C.
It's simple, a single
static snd_pcm_t *pcm
is declared on top and all threads call methods on it.Would it be possible to do that with alsa-rs?
Right now, I get this error:
The text was updated successfully, but these errors were encountered: