-
Notifications
You must be signed in to change notification settings - Fork 333
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
User Callback API StreamEvent
Overhaul
#288
User Callback API StreamEvent
Overhaul
#288
Conversation
This adds the following types: - `StreamEvent` - `CloseStreamCause` - `StreamError` These allow for notifying the user of the following events: - A stream has been played. - A stream has been paused. - A stream has been closed due to user destroying stream. - A stream has been closed due to an error.
This commit significantly refactors the alsa backend's `EventLoop::run` implementation in order to allow for better error handling throughout the loop. This removes many cases that would previously `panic!` in favour of calling the user callback with the necessary error and removing the corrupt stream. Seeing as the method cannot return, a catch-all `panic!` still exists at the end of the method, however this refactor should make it much easier to remove this restriction in the future.
6db67df
to
806455a
Compare
Refactors much of the `EventLoop::run` implementation in order to make error handling a little easier.
806455a
to
3e3cf26
Compare
cc @ishitatsuyuki it would be great to get your thoughts on this too as it aims to address the other half of #268. My plan is to do the coreaudio backend tomorrow and then it should be ready to go. |
b76cf12
to
577301d
Compare
577301d
to
b2c1226
Compare
StreamEvent
OverhaulStreamEvent
Overhaul
OK I think this should be ready to go now. I'll leave this open for a bit longer for feedback. In the meantime, I'm going to start a branch addressing #204 based on this branch. |
I'm sorry I'm a bit late! Thanks for implementing this, but I'm not sure I agree with the need of play/pause events. First, the ability to inject events into the audio processing thread varies a lot between platforms, and this seems to introduce more problems. For example, the macOS implementation relies on the existence of Mutex to deliver such events, and this will not change even after the EventLoop refactor. And second, I'm not sure if exposing such events would be useful, as it's not something the low level API implements. Did you have some particular library in mind when making this? Given that waking up the audio thread with arbitrary events is not portable, I think we are left with two options:
Also a small note: device are often considered invalidated when it gets disconnected. It's a state where you cannot perform operations, but still need to destroy it as usual, therefore is not the same as close. |
Yes I think you're right, originally I thought it might be nice for users to have access to play/pause events in case they wanted to reset some state (like oscillator phases e.g.) but this is not really essential and not worth the burden added to CPAL. I'll remove the Play and Pause events.
I think I tend to agree with your comment from #268:
I'm leaning towards the first option, however I think the signature should probably be something like I think it's still important that
What are your thoughts? |
A follow up to [this comment](RustAudio#288 (comment)).
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.
8d9a3d4
to
c72bafd
Compare
OK, I've made the changes mentioned in my last comment - I'm going to land this as is for now, but if anyone has any feedback or input feel free to share here or open a follow-up PR! |
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 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.
Add new
StreamEvent
type - enables more flexible user callback API.This adds the following types:
StreamEvent
CloseStreamCause
StreamError
These allow for notifying the user of the following events:
TODO
StreamEvent
API to top level.StreamEvent
API.Closes #268.