-
Notifications
You must be signed in to change notification settings - Fork 359
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
PipeWire support #554
Comments
The PipeWire developer is very responsive and working hard on PipeWire every day. If anyone is interested in working on this for cpal, I recommend getting in touch with him through PipeWire's issue tracker and/or #pipewire on Freenode. |
I'm running Arch + pipewire{,-jack,-pulse} and the jack example works here. What distro do you use?
|
Oh, actually I made a mistake; the above one is probably using PipeWire's ALSA integration. When testing JACK you should run with |
When I run with pipewire-jack it doesn't crash but doesn't make sound either. Strange. |
Seems that we have the same regex problem as PortAudio. Fix incoming. |
Hopefully it doesn't take 3 days to figure out how to find and replace a string in Rust like it did for me in C 😆 |
I recommend reading the PipeWire wiki. There is a lot of good information there. |
Hardcoding using the PortAudio's JACK implementation is quite quirky. Normally JACK applications create all their ports which any application communicating with the server can connect to arbitrarily. But PortAudio's abstractions flip that relationship upside down so PortAudio creates a port when the application asks to start a stream; all of the PortAudio application's ports are not available for other applications to connect to until the PortAudio application opens the stream. Does cpal's API have the same problem? |
As usual, our development effort is limited and the JACK backend is somewhat unfinished. We do care about making the abstractions not leaky, though. We register a port when you create a Line 37 in 5cfa090
|
As long as the application can create JACK/PipeWire ports for other applications or the session manager to connect to without the cpal application necessarily using all of them, I think it can work. There may need to be a mechanism for signaling the cpal application when another application or hardware device has connected to/disconnected from the cpal application's port, but I'm not familiar enough with any of these APIs to be sure about that. That may be related to hotplug support (#373). |
I have identified at least one good reason for a new PipeWire backend rather than relying on PipeWIre's reimplementation of the JACK API. From the PipeWire wiki:
This means that a CPAL application using PipeWire could request a small buffer size for low latency. When the application goes idle, it could call Stream::pause and yield control of the buffer size back to PipeWire. This would allow keeping a low latency application open in the background, pausing it, then watching a YouTube video in Firefox without having to close any applications or mess with reconfiguring anything. If I force a JACK application using the PipeWire JACK reimplementation to use a small buffer size with the PIPEWIRE_LATENCY environment variable, YouTube videos in Firefox have glitchy audio while the other application remains running. JACK has an API somewhat like this with int jack_deactivate (jack_client_t * client), but this does not fit with CPAL's abstractions. To use this, CPAL would need to track the state of each Device's streams and call Related discussion on the PipeWire issue tracker: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/722 |
@ishitatsuyuki if you or anyone else works on a new PipeWire backend for CPAL, I would be happy to help test it. I am afraid writing it myself would be above my skill level though. |
It kinda sounds like you have the most domain expertise here. Why not have a go? |
I think that would be a bit ambitious for a first Rust project. |
FWIW, here is SDL's PipeWire backend: libsdl-org/SDL#4094 |
This would be great for Whisperfish! |
Any updates on this? |
As far as I have tested, it seems the JACK backend (+pw-jack) works fine for low-latency use cases on PipeWire. If you have any specific thing missing that requires directly integrating with PipeWire, then please let me know with a comment. |
I've been looking at developing a PW backend, but one major problem I see is the main loop. A PipeWire application requires a main loop object to be created. An application calls the run method, which never returns (it can be terminated but you do it through sources). This would be a major problem with CPALand anything consuming it since it would never allow anything to run beyond the PW main loop. I'm guessingother audio backendsdo this, but I can't seem to find any way of stepping through the loop without using sources (e.g. timers). Thoughts about getting around this? |
I don't really know, but can you run that loop on another thread? It's common to create additional helper threads in cpal backends. |
@ishitatsuyuki Yep, that's exactly what the PipeWire documentationstates:
I'll look at doing that -- I didn't think of that lol. |
With RustAudio/rust-jack#154 I confirm that the cpal examples work with PipeWire's implementation of JACK. The
|
#624 fixes the build using Pipewire for the jack feature. |
I'm started working on a PipeWire host here: https://github.com/m00nwtchr/cpal/tree/pipewire-host Any help/thoughts would be appreciated. I think I'm fairly far along, but I can't find any way aside from the PipeWire Stream api to actually write/read data, and I'm not sure if my node creation code is correct. |
Cool! Could you make a draft pull request? |
The pw_filter API does not have Rust bindings yet. This is in progress: https://gitlab.freedesktop.org/pipewire/pipewire-rs/-/merge_requests/112 |
Is https://docs.pipewire.org/page_streams.html
Also, opened the draft PR: #651 |
If you're creating pw_nodes manually then I don't think you strictly need pw_filter, but my understanding is that using pw_filter would be easier to implement. |
PipeWire will soon be replacing both JACK and PulseAudio on Linux starting with Fedora 34 which will be released in a few weeks. Arch currently has packages that make it easy to switch to PipeWire. I am unclear about Ubuntu's plans and just asked them about that.
PipeWire reimplements the JACK and PulseAudio APIs. Currently the PipeWire developer is not recommending to use the new PipeWire API if applications already work well with PipeWire via JACK or PulseAudio. I am not familiar enough with cpal to know, but there might be some benefits to using the PipeWire API instead of using PipeWire via the JACK API.
PipeWire upstream already provides Rust bindings.
I have attempted to test cpal's JACK backend with PipeWire but have not gotten it to work. The
pw-uninstalled.sh
script sets theLD_LIBRARY_PATH
environment variable so PipeWire's reimplementation of libjack is loaded before JACK's original library. I know Rust links statically to other Rust libraries but I am unclear how Rust links to dynamic C libraries. Maybe theLD_LIBRARY_PATH
trick does not work with Rust?Related discussions regarding PipeWire and PortAudio:
https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/130
PortAudio/portaudio#425
The text was updated successfully, but these errors were encountered: