You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Provide a Host API? (A path towards supporting alt-backends like ASIO, Windows Exclusive Mode, PulseAudio, Jack) #204
PortAudio (a C library with similar goals to CPAL) provide what they call a Host API for choosing between different audio APIs that might exist on a single system.
Any operating system may have any number of Host APIs to the system's audio devices. E.g. on Linux this might include Alsa, Jack and PulseAudio. In the case of Windows, perhaps Asio, Shared and Exclusive hosts could be included. In the case of macOS and iOS, CoreAudio would likey be the only host in most cases.
I imagine general use might look something like this:
let host = cpal::default_host();let device = host.default_output_device().unwrap();// etc
Selecting a specific host might look something like this:
let host = cpal::hosts().find(|host| host.name().contains("jack")).expect("cannot find jack audio backend");let device = host.default_input_device().unwrap();// etc
This way a low-latency application could attempt to select low-latency supporting hosts with something like this:
It's looking like my current project may need support for ASIO soon. @tomaka it would be great to get some feedback from you on this API as I'd like to go ahead and begin implementing it soon (along with the ASIO backend) if you agree it sounds like a decent approach?
OK, I've been reflecting a lot on this over the past year and a half since opening this issue and I'm convinced that providing some sort of Hosts API is the correct approach for CPAL.
The "host" is supposed to be cpal because cpal is supposed to be as low-level as possible.
I totally agree that CPAL should be as low-level as possible, however I don't think it is possible for CPAL to be "the" host (singular) unless two conditions are met:
There is only one, clear, standard host API (for interfacing with devices, spawning streams, etc) for each platform.
Users do not need the ability to switch between multiple hosts at run-time.
Unfortunately, neither of these are the case, especially in the pro-audio community, e.g. VST, DAW, Multimedia workstation, etc, developers. On Windows, the default WDM API lacks support for many popular audio workstations and audio devices. E.g. in a recent commercial installation with @freesig we had to add ASIO support (#221) just to interface with Dante in a manner that allowed for more than 2 channels. It is also common for DAWs and other multimedia workstations to allow for selecting between multiple available hosts on the system in order to ensure users can access their hardware devices and achieve the desired latency that they require. Again, this is especially the case on Windows (ASIO, WDM) and Linux (ALSA, Pulse, Jack, who knows). Bitwig and Reaper come to mind as examples I use regularly on Linux, though I'm sure there are many more examples on both platforms.
Thoughts on the API
While this would be a breaking change, the changes should be trivial. Rather than enumerating and selecting devices via a global function, the user instead retrieves devices via a host instance.
The host instance would take care of ensuring the API is initialised and de-initialised correclty via RAII (ASIO for example needs an initialisation and termination process).
Perhaps a Host trait could be used to:
Ensure API consistency across the different hosts and
Allow for the user to select between different Hosts at runtime.
Host / Device Exclusivity?
In most cases, a host API requires exclusive access to the device(s) with which it has established streams, etc. Should we restrict the API to only allow for one host instance at any point in time? Or perhaps we should try to provide a more fine-grained API that works on a per-device basis (e.g. allowing host "foo" to connect to device "A" while host "bar" connects to device "B")? I guess the final option is to not enfoce this API-wise, and instead document the behaviour?
I'd like to get around to addressing this issue within the next week or two - I'll continue to add thoughts related to the design and progress here.
the user instead retrieves devices via a host instance.
I think this is good.
A few thoughts:
WASAPI is a host, Shared and Exclusive is not. They're API options, and also stream options.
I think host should be selected with concrete types, not string filtering. I currently don't have a big picture of how this would fit into API, but as we may need to set backend specific options, it should be type safe.
I guess the final option is to not enforce this API-wise, and instead document the behavior?
Activity
mitchmindtree commentedon Feb 13, 2018
It's looking like my current project may need support for ASIO soon. @tomaka it would be great to get some feedback from you on this API as I'd like to go ahead and begin implementing it soon (along with the ASIO backend) if you agree it sounds like a decent approach?
tomaka commentedon Feb 13, 2018
I'm really not a fan of this. The "host" is supposed to be cpal because cpal is supposed to be as low-level as possible.
However I'm ok with adding platform-specific methods that allow choosing a backend, similar to what winit/glutin do.
mitchmindtree commentedon Feb 13, 2018
OK I see where you're coming from, I'll refer to winit's approach when attempting to implement this.
mitchmindtree commentedon Jun 5, 2019
OK, I've been reflecting a lot on this over the past year and a half since opening this issue and I'm convinced that providing some sort of Hosts API is the correct approach for CPAL.
I totally agree that CPAL should be as low-level as possible, however I don't think it is possible for CPAL to be "the" host (singular) unless two conditions are met:
Unfortunately, neither of these are the case, especially in the pro-audio community, e.g. VST, DAW, Multimedia workstation, etc, developers. On Windows, the default WDM API lacks support for many popular audio workstations and audio devices. E.g. in a recent commercial installation with @freesig we had to add ASIO support (#221) just to interface with Dante in a manner that allowed for more than 2 channels. It is also common for DAWs and other multimedia workstations to allow for selecting between multiple available hosts on the system in order to ensure users can access their hardware devices and achieve the desired latency that they require. Again, this is especially the case on Windows (ASIO, WDM) and Linux (ALSA, Pulse, Jack, who knows). Bitwig and Reaper come to mind as examples I use regularly on Linux, though I'm sure there are many more examples on both platforms.
Thoughts on the API
While this would be a breaking change, the changes should be trivial. Rather than enumerating and selecting devices via a global function, the user instead retrieves devices via a host instance.
The host instance would take care of ensuring the API is initialised and de-initialised correclty via RAII (ASIO for example needs an initialisation and termination process).
Perhaps a
Hosttrait could be used to:Hosts at runtime.Host / Device Exclusivity?
In most cases, a host API requires exclusive access to the device(s) with which it has established streams, etc. Should we restrict the API to only allow for one host instance at any point in time? Or perhaps we should try to provide a more fine-grained API that works on a per-device basis (e.g. allowing host "foo" to connect to device "A" while host "bar" connects to device "B")? I guess the final option is to not enfoce this API-wise, and instead document the behaviour?
I'd like to get around to addressing this issue within the next week or two - I'll continue to add thoughts related to the design and progress here.
ishitatsuyuki commentedon Jun 6, 2019
I think this is good.
A few thoughts:
WASAPIis a host,SharedandExclusiveis not. They're API options, and also stream options.Agreed.
mitchmindtree commentedon Jun 6, 2019
Yes agreed, not sure what I was thinking here exactly in my OP.
Yes this sounds good to me!
[WIP] Introduce a `Host` API
[WIP] Introduce a `Host` API
[WIP] Introduce a `Host` API
mitchmindtree commentedon Jun 28, 2019
Closed by #289.