-
Notifications
You must be signed in to change notification settings - Fork 362
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 jack #250
Comments
@derekdreery did you get a PR going? I obviously don't have merge access on this repo but am willing to help work on a fork that targets sound server API's. |
I haven't done any work on this yet. |
One important consideration yet to be settled upon is the way in which we allow for supporting multiple possible audio backends per platform (e.g. alsa, pulse or jack on linux, wdm or asio on windows, etc). Right now, CPAL assumes just one per backend per platform (WDM on windows, ALSA on linux, CoreAudio on macos). I posted some ideas regarding this at #204 which I still think might be a good direction, I'm hoping to get some time to flesh this out a little more in the near future. There's also an ASIO PR #221 which makes some adjustments to the module system to make this multiple-backend-per-platform support possible. Anyway, just wanted to mention this as something to keep in mind! |
The only reason to go below a sound server is IMO to be a sound server or an embedded device library. It's probably worth checking that perception before I get the idea to work on importing my work on PulseAudio. Is the best solution ultimately going to make an abstraction layer over devices and then an abstraction layer over sound servers where the two are independent? I expect the answer cannot be a clear yes or no because some platforms might not have one or the other. If it can't be either, it almost has to be both. |
This is an implementation of the API described at RustAudio#204. Please see that issue for more details on the motivation. ----- A **Host** provides access to the available audio devices on the system. Some platforms have more than one host available, e.g. wasapi/asio/dsound on windows, alsa/pulse/jack on linux and so on. As a result, some audio devices are only available on certain hosts, while others are only available on other hosts. Every platform supported by CPAL has at least one **DefaultHost** that is guaranteed to be available (alsa, wasapi and coreaudio). Currently, the default hosts are the only hosts supported by CPAL, however this will change as of landing RustAudio#221 (cc @freesig). These changes should also accommodate support for other hosts such as jack RustAudio#250 (cc @derekdreery) and pulseaudio (cc @knappador) RustAudio#259. This introduces a suite of traits allowing for both compile time and runtime dispatch of different hosts and their uniquely associated device and event loop types. A new private **host** module has been added containing the individual host implementations, each in their own submodule gated to the platforms on which they are available. A new **platform** module has been added containing platform-specific items, including a dynamically dispatched host type that allows for easily switching between hosts at runtime. The **ALL_HOSTS** slice contains a **HostId** for each host supported on the current platform. The **available_hosts** function produces a **HostId** for each host that is currently *available* on the platform. The **host_from_id** function allows for initialising a host from its associated ID, failing with a **HostUnavailable** error. The **default_host** function returns the default host and should never fail. Please see the examples for a demonstration of the change in usage. For the most part, things look the same at the surface level, however the role of device enumeration and creating the event loop have been moved from global functions to host methods. The enumerate.rs example has been updated to enumerate all devices for each host, not just the default. **TODO** - [x] Add the new **Host** API - [x] Update examples for the new API. - [x] ALSA host - [ ] WASAPI host - [ ] CoreAudio host - [ ] Emscripten host **Follow-up PR** - [ ] ASIO host RustAudio#221 cc @ishitatsuyuki more to review for you if you're interested, but it might be easier after RustAudio#288 lands and this gets rebased.
This is an implementation of the API described at RustAudio#204. Please see that issue for more details on the motivation. ----- A **Host** provides access to the available audio devices on the system. Some platforms have more than one host available, e.g. wasapi/asio/dsound on windows, alsa/pulse/jack on linux and so on. As a result, some audio devices are only available on certain hosts, while others are only available on other hosts. Every platform supported by CPAL has at least one **DefaultHost** that is guaranteed to be available (alsa, wasapi and coreaudio). Currently, the default hosts are the only hosts supported by CPAL, however this will change as of landing RustAudio#221 (cc @freesig). These changes should also accommodate support for other hosts such as jack RustAudio#250 (cc @derekdreery) and pulseaudio (cc @knappador) RustAudio#259. This introduces a suite of traits allowing for both compile time and runtime dispatch of different hosts and their uniquely associated device and event loop types. A new private **host** module has been added containing the individual host implementations, each in their own submodule gated to the platforms on which they are available. A new **platform** module has been added containing platform-specific items, including a dynamically dispatched host type that allows for easily switching between hosts at runtime. The **ALL_HOSTS** slice contains a **HostId** for each host supported on the current platform. The **available_hosts** function produces a **HostId** for each host that is currently *available* on the platform. The **host_from_id** function allows for initialising a host from its associated ID, failing with a **HostUnavailable** error. The **default_host** function returns the default host and should never fail. Please see the examples for a demonstration of the change in usage. For the most part, things look the same at the surface level, however the role of device enumeration and creating the event loop have been moved from global functions to host methods. The enumerate.rs example has been updated to enumerate all devices for each host, not just the default. **TODO** - [x] Add the new **Host** API - [x] Update examples for the new API. - [x] ALSA host - [ ] WASAPI host - [ ] CoreAudio host - [ ] Emscripten host **Follow-up PR** - [ ] ASIO host RustAudio#221 cc @ishitatsuyuki more to review for you if you're interested, but it might be easier after RustAudio#288 lands and this gets rebased.
This is an implementation of the API described at RustAudio#204. Please see that issue for more details on the motivation. ----- A **Host** provides access to the available audio devices on the system. Some platforms have more than one host available, e.g. wasapi/asio/dsound on windows, alsa/pulse/jack on linux and so on. As a result, some audio devices are only available on certain hosts, while others are only available on other hosts. Every platform supported by CPAL has at least one **DefaultHost** that is guaranteed to be available (alsa, wasapi and coreaudio). Currently, the default hosts are the only hosts supported by CPAL, however this will change as of landing RustAudio#221 (cc @freesig). These changes should also accommodate support for other hosts such as jack RustAudio#250 (cc @derekdreery) and pulseaudio (cc @knappador) RustAudio#259. This introduces a suite of traits allowing for both compile time and runtime dispatch of different hosts and their uniquely associated device and event loop types. A new private **host** module has been added containing the individual host implementations, each in their own submodule gated to the platforms on which they are available. A new **platform** module has been added containing platform-specific items, including a dynamically dispatched host type that allows for easily switching between hosts at runtime. The **ALL_HOSTS** slice contains a **HostId** for each host supported on the current platform. The **available_hosts** function produces a **HostId** for each host that is currently *available* on the platform. The **host_from_id** function allows for initialising a host from its associated ID, failing with a **HostUnavailable** error. The **default_host** function returns the default host and should never fail. Please see the examples for a demonstration of the change in usage. For the most part, things look the same at the surface level, however the role of device enumeration and creating the event loop have been moved from global functions to host methods. The enumerate.rs example has been updated to enumerate all devices for each host, not just the default. **TODO** - [x] Add the new **Host** API - [x] Update examples for the new API. - [x] ALSA host - [ ] WASAPI host - [ ] CoreAudio host - [ ] Emscripten host **Follow-up PR** - [ ] ASIO host RustAudio#221 cc @ishitatsuyuki more to review for you if you're interested, but it might be easier after RustAudio#288 lands and this gets rebased.
@derekdreery Jack works on osx and windows as well. |
I thought I'd have a look at integrating the Rust jack bindings over the weekend. Give me a shout if you have tips/tricks/WIPs/want to collaborate on this! |
@ErikNatanael awesome - I've got quite a lot of work on this weekend, but any questions you have post them here. :) |
Starting to get a grip on the different abstractions in CPAL and JACK and how they might fit together. One of the significant differences between JACK and most other Hosts/Devices is that a program can create an arbitrary number of JACK clients, each of which can have an arbitrary number of input and output ports (regardless of what sound card is used). This raises a number of questions (big and small), let me know if you have opinions or ideas!
|
Hey @ErikNatanael !
Yes CPAL still needs an abstraction for duplex streams. See this issue. I think for now we might need a unique client for both input and output, but once we land duplex stream support we can support this properly. We have a similar issue in both the CoreAudio and ASIO backends. It's still theoretically possible to avoid introducing latency between input and output by ensuring the input stream user callback is called first, but it's certainly not as nice a user experience as having a proper duplex stream API.
Yes this is another known issue with CPAL's API at the moment. The current setup is certainly not a scalable or long-term solution, however it's also tricky determining what the right API is for checking device capabilities when each platform is so different in this regard. See #368 and #203 . I think it makes sense to expose a set of common configurations for now. There's also a set of
Yes this sounds like a nice solution! Thanks so much for diving into this @ErikNatanael! |
Good to know this is a known issue. I'll add some info on how this work in JACK to that issue.
Nice, I'll do my best to ensure the input stream gets called first when I get there then.
Cool, I'll do that then. Yeah, it's tricky when the backends are so different! The sample rate is set when starting the jack server and not changed by the clients so that one won't change here at least.
Not a bother, though don't count your chickens before they hatch ;) |
I've run into a problem I can't quite figure out even from reading the other Host implementations: how to store the data callbacks in order to call them from the function called by JACK. The JACK library works like this: when activating a Client you provide it with something implementing the ProcessHandler trait which requires the method called by JACK each audio iteration (
Here it is: https://github.com/ErikNatanael/cpal/blob/jack-host/src/host/jack/stream.rs#L187 I'm generally confused about how the data callbacks get access to whatever data model the audio process needs so that probably doesn't help either :D I created a pull request to track progress here: #389 |
#389 was merged on Oct 1. Thanks @ErikNatanael ! And works for me... (Helps me obtain much lower latency - e.g. testing via the feedback.rs example, setting LATENCY_MS to 20.0 works fine, with my JACK configuration - 128 frames/period.) |
Closed via #389. Thanks again @ErikNatanael! |
Would you consider a PR for jack support (it would be behind a feature for linux)?
The text was updated successfully, but these errors were encountered: