Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
Introduce a `Host` API #289
This is an implementation of the API described at #204. Please see that
A Host provides access to the available audio devices on the system.
This introduces a suite of traits allowing for both compile time and
A new private host module has been added containing the individual
A new platform module has been added containing platform-specific
The ALL_HOSTS slice contains a HostId for each host supported on
Please see the examples for a demonstration of the change in usage. For
cc @ishitatsuyuki more to review for you if you're interested.
This is an implementation of the API described at #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 #221 (cc @freesig). These changes should also accommodate support for other hosts such as jack #250 (cc @derekdreery) and pulseaudio (cc @knappador) #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 #221 cc @ishitatsuyuki more to review for you if you're interested, but it might be easier after #288 lands and this gets rebased.
ishitatsuyuki left a comment
This was a well-designed implementation! The review comments are mainly a few nits.
I’m slightly concerned regarding the big macro generating dynamic dispatch code, but well there is a use case for this and I can’t think a better way of implementation. So yeah, let’s go with this!
I'm excited by this. After it lands, I'd like to take a look at the alsa implementation to see if I can improve it. I think we cut some corners with regards to selection of parameters for the connection, with the consequence that we have panics and some valid configurations of audio hardware fail to work.
One thing: I think DefaultHost should be replaced in favor of the polymorphic version, therefore the defaults should be determined at runtime.
This is because on Linux the preferred audio API varies a lot, depending on the audio server installed (PulseAudio or Jack) or even drivers (some users may be using OSS).
Yes this is a good point, I've added a commit that makes this change.
This is quite a significant update for CPAL, including a number of breaking changes. Here is a list of the breaking changes along with links to where you can find more information: - A `Host` API has been introduced in RustAudio#289 along with a follow-up refactor in RustAudio#295. Please see the examples for a demonstration of how to update your code. The necessary changes should hopefully be minimal. If this has caused you any major difficulty please let us know in an issue! - An ASIO host has been introduced in RustAudio#292. This adds support for Steinberg's ASIO audio driver API on Windows. Please see the ASIO section of the README for more information on how to setup CPAL with ASIO support for your project. - The user callback API has been overhauled to emit `StreamEvent`s rather than buffers in order to support handling stream errors. RustAudio#288. - Error handling in general was overhauled in RustAudio#286. This meant taking advantage of the `failure` crate and adding support for backend-specific errors with custom messages. Many unnecessary `panic!`s have been removed, but a few remain that would indicate bugs in CPAL. In general, checking out the updated examples will be the easiest way to get a quick overview on how you can update your own code for these changes. The CHANGELOG.md has been updated to include these changes.