[WIP] Introduce a `Host` API
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.
2019-06-23 15:49:48 +02:00
|
|
|
//! Platform-specific items.
|
|
|
|
//!
|
|
|
|
//! This module also contains the implementation of the platform's dynamically dispatched `Host`
|
|
|
|
//! type and its associated `EventLoop`, `Device`, `StreamId` and other associated types. These
|
|
|
|
//! types are useful in the case that users require switching between audio host APIs at runtime.
|
|
|
|
|
2019-06-24 22:49:18 +02:00
|
|
|
#[doc(inline)]
|
|
|
|
pub use self::platform_impl::*;
|
|
|
|
|
[WIP] Introduce a `Host` API
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.
2019-06-23 15:49:48 +02:00
|
|
|
// A macro to assist with implementing a platform's dynamically dispatched `Host` type.
|
|
|
|
//
|
|
|
|
// These dynamically dispatched types are necessary to allow for users to switch between hosts at
|
|
|
|
// runtime.
|
|
|
|
//
|
|
|
|
// For example the invocation `impl_platform_host(Wasapi wasapi, Asio asio)`, this macro should
|
|
|
|
// expand to:
|
|
|
|
//
|
|
|
|
// ```
|
|
|
|
// pub enum HostId {
|
|
|
|
// Wasapi,
|
|
|
|
// Asio,
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// pub enum Host {
|
|
|
|
// Wasapi(crate::host::wasapi::Host),
|
|
|
|
// Asio(crate::host::asio::Host),
|
|
|
|
// }
|
|
|
|
// ```
|
|
|
|
//
|
|
|
|
// And so on for Device, Devices, EventLoop, Host, StreamId, SupportedInputFormats,
|
|
|
|
// SupportedOutputFormats and all their necessary trait implementations.
|
|
|
|
// ```
|
|
|
|
macro_rules! impl_platform_host {
|
|
|
|
($($HostVariant:ident $host_mod:ident),*) => {
|
|
|
|
/// All hosts supported by CPAL on this platform.
|
|
|
|
pub const ALL_HOSTS: &'static [HostId] = &[
|
|
|
|
$(
|
|
|
|
HostId::$HostVariant,
|
|
|
|
)*
|
|
|
|
];
|
|
|
|
|
|
|
|
/// The platform's dynamically dispatched **Host** type.
|
|
|
|
///
|
|
|
|
/// An instance of this **Host** type may represent one of any of the **Host**s available
|
|
|
|
/// on the platform.
|
|
|
|
///
|
|
|
|
/// Use this type if you require switching between available hosts at runtime.
|
|
|
|
///
|
|
|
|
/// This type may be constructed via the **host_from_id** function. **HostId**s may
|
|
|
|
/// be acquired via the **ALL_HOSTS** const and the **available_hosts** function.
|
|
|
|
pub struct Host(HostInner);
|
|
|
|
|
|
|
|
/// The **Device** implementation associated with the platform's dynamically dispatched
|
|
|
|
/// **Host** type.
|
|
|
|
pub struct Device(DeviceInner);
|
|
|
|
|
|
|
|
/// The **Devices** iterator associated with the platform's dynamically dispatched **Host**
|
|
|
|
/// type.
|
|
|
|
pub struct Devices(DevicesInner);
|
|
|
|
|
|
|
|
/// The **EventLoop** implementation associated with the platform's dynamically dispatched
|
|
|
|
/// **Host** type.
|
|
|
|
pub struct EventLoop(EventLoopInner);
|
|
|
|
|
|
|
|
/// The **StreamId** implementation associated with the platform's dynamically dispatched
|
|
|
|
/// **Host** type.
|
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
|
|
pub struct StreamId(StreamIdInner);
|
|
|
|
|
|
|
|
/// The **SupportedInputFormats** iterator associated with the platform's dynamically
|
|
|
|
/// dispatched **Host** type.
|
|
|
|
pub struct SupportedInputFormats(SupportedInputFormatsInner);
|
|
|
|
|
|
|
|
/// The **SupportedOutputFormats** iterator associated with the platform's dynamically
|
|
|
|
/// dispatched **Host** type.
|
|
|
|
pub struct SupportedOutputFormats(SupportedOutputFormatsInner);
|
|
|
|
|
|
|
|
/// Unique identifier for available hosts on the platform.
|
|
|
|
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
|
|
|
|
pub enum HostId {
|
|
|
|
$(
|
|
|
|
$HostVariant,
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
|
|
|
|
enum DeviceInner {
|
|
|
|
$(
|
|
|
|
$HostVariant(crate::host::$host_mod::Device),
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
|
|
|
|
enum DevicesInner {
|
|
|
|
$(
|
|
|
|
$HostVariant(crate::host::$host_mod::Devices),
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
|
|
|
|
enum EventLoopInner {
|
|
|
|
$(
|
|
|
|
$HostVariant(crate::host::$host_mod::EventLoop),
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
|
|
|
|
enum HostInner {
|
|
|
|
$(
|
|
|
|
$HostVariant(crate::host::$host_mod::Host),
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
|
|
enum StreamIdInner {
|
|
|
|
$(
|
|
|
|
$HostVariant(crate::host::$host_mod::StreamId),
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
|
|
|
|
enum SupportedInputFormatsInner {
|
|
|
|
$(
|
|
|
|
$HostVariant(crate::host::$host_mod::SupportedInputFormats),
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
|
|
|
|
enum SupportedOutputFormatsInner {
|
|
|
|
$(
|
|
|
|
$HostVariant(crate::host::$host_mod::SupportedOutputFormats),
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Host {
|
|
|
|
/// The unique identifier associated with this host.
|
|
|
|
pub fn id(&self) -> HostId {
|
|
|
|
match self.0 {
|
|
|
|
$(
|
|
|
|
HostInner::$HostVariant(_) => HostId::$HostVariant,
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Iterator for Devices {
|
|
|
|
type Item = Device;
|
|
|
|
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
|
|
match self.0 {
|
|
|
|
$(
|
|
|
|
DevicesInner::$HostVariant(ref mut d) => {
|
|
|
|
d.next().map(DeviceInner::$HostVariant).map(Device)
|
|
|
|
}
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
|
|
match self.0 {
|
|
|
|
$(
|
|
|
|
DevicesInner::$HostVariant(ref d) => d.size_hint(),
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Iterator for SupportedInputFormats {
|
|
|
|
type Item = crate::SupportedFormat;
|
|
|
|
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
|
|
match self.0 {
|
|
|
|
$(
|
|
|
|
SupportedInputFormatsInner::$HostVariant(ref mut s) => s.next(),
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
|
|
match self.0 {
|
|
|
|
$(
|
|
|
|
SupportedInputFormatsInner::$HostVariant(ref d) => d.size_hint(),
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Iterator for SupportedOutputFormats {
|
|
|
|
type Item = crate::SupportedFormat;
|
|
|
|
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
|
|
match self.0 {
|
|
|
|
$(
|
|
|
|
SupportedOutputFormatsInner::$HostVariant(ref mut s) => s.next(),
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
|
|
match self.0 {
|
|
|
|
$(
|
|
|
|
SupportedOutputFormatsInner::$HostVariant(ref d) => d.size_hint(),
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-28 23:42:07 +02:00
|
|
|
impl crate::traits::DeviceTrait for Device {
|
[WIP] Introduce a `Host` API
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.
2019-06-23 15:49:48 +02:00
|
|
|
type SupportedInputFormats = SupportedInputFormats;
|
|
|
|
type SupportedOutputFormats = SupportedOutputFormats;
|
|
|
|
|
|
|
|
fn name(&self) -> Result<String, crate::DeviceNameError> {
|
|
|
|
match self.0 {
|
|
|
|
$(
|
|
|
|
DeviceInner::$HostVariant(ref d) => d.name(),
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn supported_input_formats(&self) -> Result<Self::SupportedInputFormats, crate::SupportedFormatsError> {
|
|
|
|
match self.0 {
|
|
|
|
$(
|
|
|
|
DeviceInner::$HostVariant(ref d) => {
|
|
|
|
d.supported_input_formats()
|
|
|
|
.map(SupportedInputFormatsInner::$HostVariant)
|
|
|
|
.map(SupportedInputFormats)
|
|
|
|
}
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn supported_output_formats(&self) -> Result<Self::SupportedOutputFormats, crate::SupportedFormatsError> {
|
|
|
|
match self.0 {
|
|
|
|
$(
|
|
|
|
DeviceInner::$HostVariant(ref d) => {
|
|
|
|
d.supported_output_formats()
|
|
|
|
.map(SupportedOutputFormatsInner::$HostVariant)
|
|
|
|
.map(SupportedOutputFormats)
|
|
|
|
}
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn default_input_format(&self) -> Result<crate::Format, crate::DefaultFormatError> {
|
|
|
|
match self.0 {
|
|
|
|
$(
|
|
|
|
DeviceInner::$HostVariant(ref d) => d.default_input_format(),
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn default_output_format(&self) -> Result<crate::Format, crate::DefaultFormatError> {
|
|
|
|
match self.0 {
|
|
|
|
$(
|
|
|
|
DeviceInner::$HostVariant(ref d) => d.default_output_format(),
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-28 23:42:07 +02:00
|
|
|
impl crate::traits::EventLoopTrait for EventLoop {
|
[WIP] Introduce a `Host` API
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.
2019-06-23 15:49:48 +02:00
|
|
|
type StreamId = StreamId;
|
|
|
|
type Device = Device;
|
|
|
|
|
|
|
|
fn build_input_stream(
|
|
|
|
&self,
|
|
|
|
device: &Self::Device,
|
|
|
|
format: &crate::Format,
|
|
|
|
) -> Result<Self::StreamId, crate::BuildStreamError> {
|
|
|
|
match (&self.0, &device.0) {
|
|
|
|
$(
|
|
|
|
(&EventLoopInner::$HostVariant(ref e), &DeviceInner::$HostVariant(ref d)) => {
|
|
|
|
e.build_input_stream(d, format)
|
|
|
|
.map(StreamIdInner::$HostVariant)
|
|
|
|
.map(StreamId)
|
|
|
|
}
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn build_output_stream(
|
|
|
|
&self,
|
|
|
|
device: &Self::Device,
|
|
|
|
format: &crate::Format,
|
|
|
|
) -> Result<Self::StreamId, crate::BuildStreamError> {
|
|
|
|
match (&self.0, &device.0) {
|
|
|
|
$(
|
|
|
|
(&EventLoopInner::$HostVariant(ref e), &DeviceInner::$HostVariant(ref d)) => {
|
|
|
|
e.build_output_stream(d, format)
|
|
|
|
.map(StreamIdInner::$HostVariant)
|
|
|
|
.map(StreamId)
|
|
|
|
}
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn play_stream(&self, stream: Self::StreamId) -> Result<(), crate::PlayStreamError> {
|
|
|
|
match (&self.0, stream.0) {
|
|
|
|
$(
|
2019-06-24 22:21:19 +02:00
|
|
|
(&EventLoopInner::$HostVariant(ref e), StreamIdInner::$HostVariant(ref s)) => {
|
|
|
|
e.play_stream(s.clone())
|
[WIP] Introduce a `Host` API
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.
2019-06-23 15:49:48 +02:00
|
|
|
}
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn pause_stream(&self, stream: Self::StreamId) -> Result<(), crate::PauseStreamError> {
|
|
|
|
match (&self.0, stream.0) {
|
|
|
|
$(
|
2019-06-24 22:21:19 +02:00
|
|
|
(&EventLoopInner::$HostVariant(ref e), StreamIdInner::$HostVariant(ref s)) => {
|
|
|
|
e.pause_stream(s.clone())
|
[WIP] Introduce a `Host` API
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.
2019-06-23 15:49:48 +02:00
|
|
|
}
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn destroy_stream(&self, stream: Self::StreamId) {
|
|
|
|
match (&self.0, stream.0) {
|
|
|
|
$(
|
2019-06-24 22:21:19 +02:00
|
|
|
(&EventLoopInner::$HostVariant(ref e), StreamIdInner::$HostVariant(ref s)) => {
|
|
|
|
e.destroy_stream(s.clone())
|
[WIP] Introduce a `Host` API
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.
2019-06-23 15:49:48 +02:00
|
|
|
}
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn run<F>(&self, mut callback: F) -> !
|
|
|
|
where
|
|
|
|
F: FnMut(Self::StreamId, crate::StreamDataResult) + Send
|
|
|
|
{
|
|
|
|
match self.0 {
|
|
|
|
$(
|
|
|
|
EventLoopInner::$HostVariant(ref e) => {
|
|
|
|
e.run(|id, result| {
|
|
|
|
let result = result;
|
|
|
|
callback(StreamId(StreamIdInner::$HostVariant(id)), result);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-28 23:42:07 +02:00
|
|
|
impl crate::traits::HostTrait for Host {
|
[WIP] Introduce a `Host` API
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.
2019-06-23 15:49:48 +02:00
|
|
|
type Devices = Devices;
|
|
|
|
type Device = Device;
|
|
|
|
type EventLoop = EventLoop;
|
|
|
|
|
|
|
|
fn is_available() -> bool {
|
|
|
|
$( crate::host::$host_mod::Host::is_available() ||)* false
|
|
|
|
}
|
|
|
|
|
|
|
|
fn devices(&self) -> Result<Self::Devices, crate::DevicesError> {
|
|
|
|
match self.0 {
|
|
|
|
$(
|
|
|
|
HostInner::$HostVariant(ref h) => {
|
|
|
|
h.devices().map(DevicesInner::$HostVariant).map(Devices)
|
|
|
|
}
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn default_input_device(&self) -> Option<Self::Device> {
|
|
|
|
match self.0 {
|
|
|
|
$(
|
|
|
|
HostInner::$HostVariant(ref h) => {
|
|
|
|
h.default_input_device().map(DeviceInner::$HostVariant).map(Device)
|
|
|
|
}
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn default_output_device(&self) -> Option<Self::Device> {
|
|
|
|
match self.0 {
|
|
|
|
$(
|
|
|
|
HostInner::$HostVariant(ref h) => {
|
|
|
|
h.default_output_device().map(DeviceInner::$HostVariant).map(Device)
|
|
|
|
}
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn event_loop(&self) -> Self::EventLoop {
|
|
|
|
match self.0 {
|
|
|
|
$(
|
|
|
|
HostInner::$HostVariant(ref h) => {
|
|
|
|
EventLoop(EventLoopInner::$HostVariant(h.event_loop()))
|
|
|
|
}
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-28 23:42:07 +02:00
|
|
|
impl crate::traits::StreamIdTrait for StreamId {}
|
[WIP] Introduce a `Host` API
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.
2019-06-23 15:49:48 +02:00
|
|
|
|
2019-06-25 16:54:50 +02:00
|
|
|
$(
|
|
|
|
impl From<crate::host::$host_mod::Device> for Device {
|
|
|
|
fn from(h: crate::host::$host_mod::Device) -> Self {
|
|
|
|
Device(DeviceInner::$HostVariant(h))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<crate::host::$host_mod::Devices> for Devices {
|
|
|
|
fn from(h: crate::host::$host_mod::Devices) -> Self {
|
|
|
|
Devices(DevicesInner::$HostVariant(h))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<crate::host::$host_mod::EventLoop> for EventLoop {
|
|
|
|
fn from(h: crate::host::$host_mod::EventLoop) -> Self {
|
|
|
|
EventLoop(EventLoopInner::$HostVariant(h))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<crate::host::$host_mod::Host> for Host {
|
|
|
|
fn from(h: crate::host::$host_mod::Host) -> Self {
|
|
|
|
Host(HostInner::$HostVariant(h))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<crate::host::$host_mod::StreamId> for StreamId {
|
|
|
|
fn from(h: crate::host::$host_mod::StreamId) -> Self {
|
|
|
|
StreamId(StreamIdInner::$HostVariant(h))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)*
|
|
|
|
|
[WIP] Introduce a `Host` API
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.
2019-06-23 15:49:48 +02:00
|
|
|
/// Produces a list of hosts that are currently available on the system.
|
|
|
|
pub fn available_hosts() -> Vec<HostId> {
|
|
|
|
let mut host_ids = vec![];
|
|
|
|
$(
|
2019-06-28 23:42:07 +02:00
|
|
|
if <crate::host::$host_mod::Host as crate::traits::HostTrait>::is_available() {
|
[WIP] Introduce a `Host` API
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.
2019-06-23 15:49:48 +02:00
|
|
|
host_ids.push(HostId::$HostVariant);
|
|
|
|
}
|
|
|
|
)*
|
|
|
|
host_ids
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Given a unique host identifier, initialise and produce the host if it is available.
|
|
|
|
pub fn host_from_id(id: HostId) -> Result<Host, crate::HostUnavailable> {
|
|
|
|
match id {
|
|
|
|
$(
|
|
|
|
HostId::$HostVariant => {
|
|
|
|
crate::host::$host_mod::Host::new()
|
|
|
|
.map(HostInner::$HostVariant)
|
|
|
|
.map(Host)
|
|
|
|
}
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: Add pulseaudio and jack here eventually.
|
|
|
|
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
|
2019-06-24 22:49:18 +02:00
|
|
|
mod platform_impl {
|
2019-06-25 16:54:50 +02:00
|
|
|
pub use crate::host::alsa::{
|
|
|
|
Device as AlsaDevice,
|
|
|
|
Devices as AlsaDevices,
|
|
|
|
EventLoop as AlsaEventLoop,
|
|
|
|
Host as AlsaHost,
|
|
|
|
StreamId as AlsaStreamId,
|
|
|
|
SupportedInputFormats as AlsaSupportedInputFormats,
|
|
|
|
SupportedOutputFormats as AlsaSupportedOutputFormats,
|
|
|
|
};
|
2019-06-24 22:49:18 +02:00
|
|
|
|
|
|
|
impl_platform_host!(Alsa alsa);
|
2019-06-25 16:54:50 +02:00
|
|
|
|
|
|
|
/// The default host for the current compilation target platform.
|
|
|
|
pub fn default_host() -> Host {
|
|
|
|
AlsaHost::new()
|
|
|
|
.expect("the default host should always be available")
|
|
|
|
.into()
|
|
|
|
}
|
2019-06-24 22:49:18 +02:00
|
|
|
}
|
|
|
|
|
[WIP] Introduce a `Host` API
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.
2019-06-23 15:49:48 +02:00
|
|
|
|
|
|
|
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
2019-06-24 22:49:18 +02:00
|
|
|
mod platform_impl {
|
2019-06-25 16:54:50 +02:00
|
|
|
pub use crate::host::coreaudio::{
|
|
|
|
Device as CoreAudioDevice,
|
|
|
|
Devices as CoreAudioDevices,
|
|
|
|
EventLoop as CoreAudioEventLoop,
|
|
|
|
Host as CoreAudioHost,
|
|
|
|
StreamId as CoreAudioStreamId,
|
|
|
|
SupportedInputFormats as CoreAudioSupportedInputFormats,
|
|
|
|
SupportedOutputFormats as CoreAudioSupportedOutputFormats,
|
|
|
|
};
|
2019-06-24 22:49:18 +02:00
|
|
|
|
|
|
|
impl_platform_host!(CoreAudio coreaudio);
|
2019-06-25 16:54:50 +02:00
|
|
|
|
|
|
|
/// The default host for the current compilation target platform.
|
|
|
|
pub fn default_host() -> Host {
|
|
|
|
CoreAudioHost::new()
|
|
|
|
.expect("the default host should always be available")
|
|
|
|
.into()
|
|
|
|
}
|
2019-06-24 22:49:18 +02:00
|
|
|
}
|
[WIP] Introduce a `Host` API
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.
2019-06-23 15:49:48 +02:00
|
|
|
|
|
|
|
#[cfg(target_os = "emscripten")]
|
2019-06-24 22:49:18 +02:00
|
|
|
mod platform_impl {
|
2019-06-25 16:54:50 +02:00
|
|
|
pub use crate::host::emscripten::{
|
|
|
|
Device as EmscriptenDevice,
|
|
|
|
Devices as EmscriptenDevices,
|
|
|
|
EventLoop as EmscriptenEventLoop,
|
|
|
|
Host as EmscriptenHost,
|
|
|
|
StreamId as EmscriptenStreamId,
|
|
|
|
SupportedInputFormats as EmscriptenSupportedInputFormats,
|
|
|
|
SupportedOutputFormats as EmscriptenSupportedOutputFormats,
|
|
|
|
};
|
[WIP] Introduce a `Host` API
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.
2019-06-23 15:49:48 +02:00
|
|
|
|
2019-06-24 22:49:18 +02:00
|
|
|
impl_platform_host!(Emscripten emscripten);
|
2019-06-25 16:54:50 +02:00
|
|
|
|
|
|
|
/// The default host for the current compilation target platform.
|
|
|
|
pub fn default_host() -> Host {
|
|
|
|
EmscriptenHost::new()
|
|
|
|
.expect("the default host should always be available")
|
|
|
|
.into()
|
|
|
|
}
|
2019-06-24 22:49:18 +02:00
|
|
|
}
|
[WIP] Introduce a `Host` API
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.
2019-06-23 15:49:48 +02:00
|
|
|
|
2019-06-24 22:49:18 +02:00
|
|
|
// TODO: Add `Asio asio` once #221 lands.
|
|
|
|
#[cfg(windows)]
|
|
|
|
mod platform_impl {
|
2019-06-25 16:54:50 +02:00
|
|
|
pub use crate::host::wasapi::{
|
|
|
|
Device as WasapiDevice,
|
|
|
|
Devices as WasapiDevices,
|
|
|
|
EventLoop as WasapiEventLoop,
|
|
|
|
Host as WasapiHost,
|
|
|
|
StreamId as WasapiStreamId,
|
|
|
|
SupportedInputFormats as WasapiSupportedInputFormats,
|
|
|
|
SupportedOutputFormats as WasapiSupportedOutputFormats,
|
|
|
|
};
|
[WIP] Introduce a `Host` API
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.
2019-06-23 15:49:48 +02:00
|
|
|
|
2019-06-24 22:49:18 +02:00
|
|
|
impl_platform_host!(Wasapi wasapi);
|
2019-06-25 16:54:50 +02:00
|
|
|
|
|
|
|
/// The default host for the current compilation target platform.
|
|
|
|
pub fn default_host() -> Host {
|
|
|
|
WasapiHost::new()
|
|
|
|
.expect("the default host should always be available")
|
|
|
|
.into()
|
|
|
|
}
|
2019-06-24 22:49:18 +02:00
|
|
|
}
|
[WIP] Introduce a `Host` API
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.
2019-06-23 15:49:48 +02:00
|
|
|
|
|
|
|
#[cfg(not(any(windows, target_os = "linux", target_os = "freebsd", target_os = "macos",
|
|
|
|
target_os = "ios", target_os = "emscripten")))]
|
2019-06-24 22:49:18 +02:00
|
|
|
mod platform_impl {
|
2019-06-25 16:54:50 +02:00
|
|
|
pub use crate::host::null::{
|
|
|
|
Device as NullDevice,
|
|
|
|
Devices as NullDevices,
|
|
|
|
EventLoop as NullEventLoop,
|
|
|
|
Host as NullHost,
|
|
|
|
StreamId as NullStreamId,
|
|
|
|
SupportedInputFormats as NullSupportedInputFormats,
|
|
|
|
SupportedOutputFormats as NullSupportedOutputFormats,
|
|
|
|
};
|
2019-06-24 22:49:18 +02:00
|
|
|
|
|
|
|
impl_platform_host!(Null null);
|
[WIP] Introduce a `Host` API
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.
2019-06-23 15:49:48 +02:00
|
|
|
|
2019-06-25 16:54:50 +02:00
|
|
|
/// The default host for the current compilation target platform.
|
|
|
|
pub fn default_host() -> Host {
|
|
|
|
NullHost::new()
|
|
|
|
.expect("the default host should always be available")
|
|
|
|
.into()
|
|
|
|
}
|
[WIP] Introduce a `Host` API
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.
2019-06-23 15:49:48 +02:00
|
|
|
}
|