nandi/jolt-nativepublic Fork 0
cfd3e3677bed92e80cfe447469a249cfdc0b1401
Commits
Clone
git clone https://git.rickub.com/nandi/jolt-native.git
git clone ssh://git@rickub.com/nandi/jolt-native.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

mod.rs · 950 lines · 31.6 KBRust Blame HistoryRaw
Lift freeq's AV media plane out of sleek 90f8b89 nandi 19d ago1//! Platform-specific items.
2//!
3//! This module also contains the implementation of the platform's dynamically dispatched [`Host`]
4//! type and its associated [`Device`], [`Stream`] and other associated types. These
5//! types are useful in the case that users require switching between audio host APIs at runtime.
6
7#[doc(inline)]
8pub use self::platform_impl::*;
9
10#[cfg(feature = "custom")]
11pub use crate::host::custom::{Device as CustomDevice, Host as CustomHost, Stream as CustomStream};
12
13/// A macro to assist with implementing a platform's dynamically dispatched [`Host`] type.
14///
15/// These dynamically dispatched types are necessary to allow for users to switch between hosts at
16/// runtime.
17///
18/// For example the invocation `impl_platform_host(Wasapi wasapi "WASAPI", Asio asio "ASIO")`,
19/// this macro should expand to:
20///
21// This sample code block is marked as text because it's not a valid test,
22// it's just illustrative. (see rust issue #96573)
23/// ```text
24/// pub enum HostId {
25/// Wasapi,
26/// Asio,
27/// }
28///
29/// pub enum Host {
30/// Wasapi(crate::host::wasapi::Host),
31/// Asio(crate::host::asio::Host),
32/// }
33/// ```
34///
35/// And so on for Device, Devices, Host, Stream, SupportedInputConfigs,
36/// SupportedOutputConfigs and all their necessary trait implementations.
37///
38macro_rules! impl_platform_host {
39 ($($(#[cfg($feat: meta)])? $HostVariant:ident => $Host:ty),* $(,)?) => {
40 /// All hosts supported by CPAL on this platform.
41 pub const ALL_HOSTS: &'static [HostId] = &[
42 $(
43 $(#[cfg($feat)])?
44 HostId::$HostVariant,
45 )*
46 ];
47
48 /// The platform's dynamically dispatched `Host` type.
49 ///
50 /// An instance of this `Host` type may represent one of the `Host`s available
51 /// on the platform.
52 ///
53 /// Use this type if you require switching between available hosts at runtime.
54 ///
55 /// This type may be constructed via the [`host_from_id`] function. [`HostId`]s may
56 /// be acquired via the [`ALL_HOSTS`] const, and the [`available_hosts`] function.
57 pub struct Host(HostInner);
58
59 /// The `Device` implementation associated with the platform's dynamically dispatched
60 /// [`Host`] type.
61 #[derive(Clone)]
62 pub struct Device(DeviceInner);
63
64 /// The `Devices` iterator associated with the platform's dynamically dispatched [`Host`]
65 /// type.
66 pub struct Devices(DevicesInner);
67
68 /// The `Stream` implementation associated with the platform's dynamically dispatched
69 /// [`Host`] type.
70 #[must_use = "If the stream is not stored it will not play."]
71 pub struct Stream(StreamInner);
72
73 /// The `SupportedInputConfigs` iterator associated with the platform's dynamically
74 /// dispatched [`Host`] type.
75 #[derive(Clone)]
76 pub struct SupportedInputConfigs(SupportedInputConfigsInner);
77
78 /// The `SupportedOutputConfigs` iterator associated with the platform's dynamically
79 /// dispatched [`Host`] type.
80 #[derive(Clone)]
81 pub struct SupportedOutputConfigs(SupportedOutputConfigsInner);
82
83 /// Unique identifier for available hosts on the platform.
84 ///
85 /// Only the hosts supported by the current platform are available as enum variants.
86 /// For cross-platform code that needs to handle hosts from other platforms,
87 /// use the string representation via [`std::fmt::Display`]/[`std::str::FromStr`].
88 ///
89 /// # Available Host Strings
90 ///
91 /// For cross-platform matching, these host strings are available:
92 ///
93 /// - `"aaudio"` - Android Audio
94 /// - `"alsa"` - Advanced Linux Sound Architecture
95 /// - `"asio"` - ASIO
96 /// - `"coreaudio"` - CoreAudio
97 /// - `"custom"` - Custom host (requires `custom` feature)
98 /// - `"emscripten"` - Emscripten
99 /// - `"jack"` - JACK Audio Connection Kit
100 /// - `"null"` - Null host
101 /// - `"wasapi"` - Windows Audio Session API
102 /// - `"webaudio"` - Web Audio API
103 /// - `"audioworklet"` - Audio Worklet
104 ///
105 /// # Cross-Platform Example
106 ///
107 /// ```
108 /// use cpal::HostId;
109 /// use std::str::FromStr;
110 ///
111 /// fn handle_host_string(host_string: &str) {
112 /// // String matching works on all platforms
113 /// match host_string {
114 /// "alsa" => println!("ALSA host"),
115 /// "coreaudio" => println!("CoreAudio host"),
116 /// "jack" => println!("JACK host"),
117 /// "wasapi" => println!("WASAPI host"),
118 /// "asio" => println!("ASIO host"),
119 /// "aaudio" => println!("AAudio host"),
120 /// _ => println!("Other host"),
121 /// }
122 ///
123 /// // Parse host string (may fail if host is not available on this platform)
124 /// if let Ok(host_id) = HostId::from_str(host_string) {
125 /// println!("Successfully parsed: {}", host_id);
126 /// }
127 /// }
128 /// ```
129 #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
130 pub enum HostId {
131 $(
132 $(#[cfg($feat)])?
133 $(#[cfg_attr(docsrs, doc(cfg($feat)))])?
134 $HostVariant,
135 )*
136 }
137
138 /// Contains a platform specific [`Device`] implementation.
139 #[derive(Clone)]
140 #[allow(clippy::large_enum_variant)]
141 pub enum DeviceInner {
142 $(
143 $(#[cfg($feat)])?
144 $HostVariant(<$Host as crate::traits::HostTrait>::Device),
145 )*
146 }
147
148 /// Contains a platform specific [`Devices`] implementation.
149 pub enum DevicesInner {
150 $(
151 $(#[cfg($feat)])?
152 $HostVariant(<$Host as crate::traits::HostTrait>::Devices),
153 )*
154 }
155
156 /// Contains a platform specific [`Host`] implementation.
157 pub enum HostInner {
158 $(
159 $(#[cfg($feat)])?
160 $HostVariant($Host),
161 )*
162 }
163
164 /// Contains a platform specific [`Stream`] implementation.
165 pub enum StreamInner {
166 $(
167 $(#[cfg($feat)])?
168 $HostVariant(<<$Host as crate::traits::HostTrait>::Device as crate::traits::DeviceTrait>::Stream),
169 )*
170 }
171
172 #[derive(Clone)]
173 enum SupportedInputConfigsInner {
174 $(
175 $(#[cfg($feat)])?
176 $HostVariant(<<$Host as crate::traits::HostTrait>::Device as crate::traits::DeviceTrait>::SupportedInputConfigs),
177 )*
178 }
179
180 #[derive(Clone)]
181 enum SupportedOutputConfigsInner {
182 $(
183 $(#[cfg($feat)])?
184 $HostVariant(<<$Host as crate::traits::HostTrait>::Device as crate::traits::DeviceTrait>::SupportedOutputConfigs),
185 )*
186 }
187
188 impl HostId {
189 pub fn name(&self) -> &'static str {
190 match self {
191 $(
192 $(#[cfg($feat)])?
193 HostId::$HostVariant => stringify!($HostVariant),
194 )*
195 }
196 }
197 }
198
199 impl std::fmt::Display for HostId {
200 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
201 write!(f, "{}", self.name().to_lowercase())
202 }
203 }
204
205 impl std::str::FromStr for HostId {
206 type Err = crate::HostUnavailable;
207
208 fn from_str(s: &str) -> Result<Self, Self::Err> {
209 $(
210 $(#[cfg($feat)])?
211 if stringify!($HostVariant).eq_ignore_ascii_case(s) {
212 return Ok(HostId::$HostVariant);
213 }
214 )*
215 Err(crate::HostUnavailable)
216 }
217 }
218
219 impl Devices {
220 /// Returns a reference to the underlying platform specific implementation of this
221 /// `Devices`.
222 pub fn as_inner(&self) -> &DevicesInner {
223 &self.0
224 }
225
226 /// Returns a mutable reference to the underlying platform specific implementation of
227 /// this `Devices`.
228 pub fn as_inner_mut(&mut self) -> &mut DevicesInner {
229 &mut self.0
230 }
231
232 /// Returns the underlying platform specific implementation of this `Devices`.
233 pub fn into_inner(self) -> DevicesInner {
234 self.0
235 }
236 }
237
238 impl Device {
239 /// Returns a reference to the underlying platform specific implementation of this
240 /// `Device`.
241 pub fn as_inner(&self) -> &DeviceInner {
242 &self.0
243 }
244
245 /// Returns a mutable reference to the underlying platform specific implementation of
246 /// this `Device`.
247 pub fn as_inner_mut(&mut self) -> &mut DeviceInner {
248 &mut self.0
249 }
250
251 /// Returns the underlying platform specific implementation of this `Device`.
252 pub fn into_inner(self) -> DeviceInner {
253 self.0
254 }
255 }
256
257 impl Host {
258 /// The unique identifier associated with this `Host`.
259 pub fn id(&self) -> HostId {
260 match self.0 {
261 $(
262 $(#[cfg($feat)])?
263 HostInner::$HostVariant(_) => HostId::$HostVariant,
264 )*
265 }
266 }
267
268 /// Returns a reference to the underlying platform specific implementation of this
269 /// `Host`.
270 pub fn as_inner(&self) -> &HostInner {
271 &self.0
272 }
273
274 /// Returns a mutable reference to the underlying platform specific implementation of
275 /// this `Host`.
276 pub fn as_inner_mut(&mut self) -> &mut HostInner {
277 &mut self.0
278 }
279
280 /// Returns the underlying platform specific implementation of this `Host`.
281 pub fn into_inner(self) -> HostInner {
282 self.0
283 }
284 }
285
286 impl Stream {
287 /// Returns a reference to the underlying platform specific implementation of this
288 /// `Stream`.
289 pub fn as_inner(&self) -> &StreamInner {
290 &self.0
291 }
292
293 /// Returns a mutable reference to the underlying platform specific implementation of
294 /// this `Stream`.
295 pub fn as_inner_mut(&mut self) -> &mut StreamInner {
296 &mut self.0
297 }
298
299 /// Returns the underlying platform specific implementation of this `Stream`.
300 pub fn into_inner(self) -> StreamInner {
301 self.0
302 }
303 }
304
305 impl Iterator for Devices {
306 type Item = Device;
307
308 fn next(&mut self) -> Option<Self::Item> {
309 match self.0 {
310 $(
311 $(#[cfg($feat)])?
312 DevicesInner::$HostVariant(ref mut d) => {
313 d.next().map(DeviceInner::$HostVariant).map(Device::from)
314 }
315 )*
316 }
317 }
318
319 fn size_hint(&self) -> (usize, Option<usize>) {
320 match self.0 {
321 $(
322 $(#[cfg($feat)])?
323 DevicesInner::$HostVariant(ref d) => d.size_hint(),
324 )*
325 }
326 }
327 }
328
329 impl Iterator for SupportedInputConfigs {
330 type Item = crate::SupportedStreamConfigRange;
331
332 fn next(&mut self) -> Option<Self::Item> {
333 match self.0 {
334 $(
335 $(#[cfg($feat)])?
336 SupportedInputConfigsInner::$HostVariant(ref mut s) => s.next(),
337 )*
338 }
339 }
340
341 fn size_hint(&self) -> (usize, Option<usize>) {
342 match self.0 {
343 $(
344 $(#[cfg($feat)])?
345 SupportedInputConfigsInner::$HostVariant(ref d) => d.size_hint(),
346 )*
347 }
348 }
349 }
350
351 impl Iterator for SupportedOutputConfigs {
352 type Item = crate::SupportedStreamConfigRange;
353
354 fn next(&mut self) -> Option<Self::Item> {
355 match self.0 {
356 $(
357 $(#[cfg($feat)])?
358 SupportedOutputConfigsInner::$HostVariant(ref mut s) => s.next(),
359 )*
360 }
361 }
362
363 fn size_hint(&self) -> (usize, Option<usize>) {
364 match self.0 {
365 $(
366 $(#[cfg($feat)])?
367 SupportedOutputConfigsInner::$HostVariant(ref d) => d.size_hint(),
368 )*
369 }
370 }
371 }
372
373 impl crate::traits::DeviceTrait for Device {
374 type SupportedInputConfigs = SupportedInputConfigs;
375 type SupportedOutputConfigs = SupportedOutputConfigs;
376 type Stream = Stream;
377
378 #[allow(deprecated)]
379 fn name(&self) -> Result<String, crate::DeviceNameError> {
380 match self.0 {
381 $(
382 $(#[cfg($feat)])?
383 DeviceInner::$HostVariant(ref d) => d.name(),
384 )*
385 }
386 }
387
388 fn description(&self) -> Result<crate::DeviceDescription, crate::DeviceNameError> {
389 match self.0 {
390 $(
391 $(#[cfg($feat)])?
392 DeviceInner::$HostVariant(ref d) => d.description(),
393 )*
394 }
395 }
396
397 fn id(&self) -> Result<crate::DeviceId, crate::DeviceIdError> {
398 match self.0 {
399 $(
400 $(#[cfg($feat)])?
401 DeviceInner::$HostVariant(ref d) => d.id(),
402 )*
403 }
404 }
405
406 fn supports_input(&self) -> bool {
407 match self.0 {
408 $(
409 $(#[cfg($feat)])?
410 DeviceInner::$HostVariant(ref d) => d.supports_input(),
411 )*
412 }
413 }
414
415 fn supports_output(&self) -> bool {
416 match self.0 {
417 $(
418 $(#[cfg($feat)])?
419 DeviceInner::$HostVariant(ref d) => d.supports_output(),
420 )*
421 }
422 }
423
424 fn supported_input_configs(&self) -> Result<Self::SupportedInputConfigs, crate::SupportedStreamConfigsError> {
425 match self.0 {
426 $(
427 $(#[cfg($feat)])?
428 DeviceInner::$HostVariant(ref d) => {
429 d.supported_input_configs()
430 .map(SupportedInputConfigsInner::$HostVariant)
431 .map(SupportedInputConfigs)
432 }
433 )*
434 }
435 }
436
437 fn supported_output_configs(&self) -> Result<Self::SupportedOutputConfigs, crate::SupportedStreamConfigsError> {
438 match self.0 {
439 $(
440 $(#[cfg($feat)])?
441 DeviceInner::$HostVariant(ref d) => {
442 d.supported_output_configs()
443 .map(SupportedOutputConfigsInner::$HostVariant)
444 .map(SupportedOutputConfigs)
445 }
446 )*
447 }
448 }
449
450 fn default_input_config(&self) -> Result<crate::SupportedStreamConfig, crate::DefaultStreamConfigError> {
451 match self.0 {
452 $(
453 $(#[cfg($feat)])?
454 DeviceInner::$HostVariant(ref d) => d.default_input_config(),
455 )*
456 }
457 }
458
459 fn default_output_config(&self) -> Result<crate::SupportedStreamConfig, crate::DefaultStreamConfigError> {
460 match self.0 {
461 $(
462 $(#[cfg($feat)])?
463 DeviceInner::$HostVariant(ref d) => d.default_output_config(),
464 )*
465 }
466 }
467
468 fn build_input_stream_raw<D, E>(
469 &self,
470 config: crate::StreamConfig,
471 sample_format: crate::SampleFormat,
472 data_callback: D,
473 error_callback: E,
474 timeout: Option<std::time::Duration>,
475 ) -> Result<Self::Stream, crate::BuildStreamError>
476 where
477 D: FnMut(&crate::Data, &crate::InputCallbackInfo) + Send + 'static,
478 E: FnMut(crate::StreamError) + Send + 'static,
479 {
480 match self.0 {
481 $(
482 $(#[cfg($feat)])?
483 DeviceInner::$HostVariant(ref d) => d
484 .build_input_stream_raw(
485 config,
486 sample_format,
487 data_callback,
488 error_callback,
489 timeout,
490 )
491 .map(StreamInner::$HostVariant)
492 .map(Stream::from),
493 )*
494 }
495 }
496
497 fn build_output_stream_raw<D, E>(
498 &self,
499 config: crate::StreamConfig,
500 sample_format: crate::SampleFormat,
501 data_callback: D,
502 error_callback: E,
503 timeout: Option<std::time::Duration>,
504 ) -> Result<Self::Stream, crate::BuildStreamError>
505 where
506 D: FnMut(&mut crate::Data, &crate::OutputCallbackInfo) + Send + 'static,
507 E: FnMut(crate::StreamError) + Send + 'static,
508 {
509 match self.0 {
510 $(
511 $(#[cfg($feat)])?
512 DeviceInner::$HostVariant(ref d) => d
513 .build_output_stream_raw(
514 config,
515 sample_format,
516 data_callback,
517 error_callback,
518 timeout,
519 )
520 .map(StreamInner::$HostVariant)
521 .map(Stream::from),
522 )*
523 }
524 }
525 }
526
527 impl crate::traits::HostTrait for Host {
528 type Devices = Devices;
529 type Device = Device;
530
531 fn is_available() -> bool {
532 $(
533 $(#[cfg($feat)])?
534 if <$Host>::is_available() { return true; }
535 )*
536 false
537 }
538
539 fn devices(&self) -> Result<Self::Devices, crate::DevicesError> {
540 match self.0 {
541 $(
542 $(#[cfg($feat)])?
543 HostInner::$HostVariant(ref h) => {
544 h.devices().map(DevicesInner::$HostVariant).map(Devices::from)
545 }
546 )*
547 }
548 }
549
550 fn device_by_id(&self, id: &crate::DeviceId) -> Option<Self::Device> {
551 match self.0 {
552 $(
553 $(#[cfg($feat)])?
554 HostInner::$HostVariant(ref h) => {
555 h.device_by_id(id).map(DeviceInner::$HostVariant).map(Device::from)
556 }
557 )*
558 }
559 }
560
561 fn default_input_device(&self) -> Option<Self::Device> {
562 match self.0 {
563 $(
564 $(#[cfg($feat)])?
565 HostInner::$HostVariant(ref h) => {
566 h.default_input_device().map(DeviceInner::$HostVariant).map(Device::from)
567 }
568 )*
569 }
570 }
571
572 fn default_output_device(&self) -> Option<Self::Device> {
573 match self.0 {
574 $(
575 $(#[cfg($feat)])?
576 HostInner::$HostVariant(ref h) => {
577 h.default_output_device().map(DeviceInner::$HostVariant).map(Device::from)
578 }
579 )*
580 }
581 }
582 }
583
584 impl crate::traits::StreamTrait for Stream {
585 fn play(&self) -> Result<(), crate::PlayStreamError> {
586 match self.0 {
587 $(
588 $(#[cfg($feat)])?
589 StreamInner::$HostVariant(ref s) => {
590 s.play()
591 }
592 )*
593 }
594 }
595
596 fn pause(&self) -> Result<(), crate::PauseStreamError> {
597 match self.0 {
598 $(
599 $(#[cfg($feat)])?
600 StreamInner::$HostVariant(ref s) => {
601 s.pause()
602 }
603 )*
604 }
605 }
606
607 fn buffer_size(&self) -> Option<crate::FrameCount> {
608 match self.0 {
609 $(
610 $(#[cfg($feat)])?
611 StreamInner::$HostVariant(ref s) => {
612 s.buffer_size()
613 }
614 )*
615 }
616 }
617 }
618
619 impl From<DeviceInner> for Device {
620 fn from(d: DeviceInner) -> Self {
621 Device(d)
622 }
623 }
624
625 impl From<DevicesInner> for Devices {
626 fn from(d: DevicesInner) -> Self {
627 Devices(d)
628 }
629 }
630
631 impl From<HostInner> for Host {
632 fn from(h: HostInner) -> Self {
633 Host(h)
634 }
635 }
636
637 impl From<StreamInner> for Stream {
638 fn from(s: StreamInner) -> Self {
639 Stream(s)
640 }
641 }
642
643 $(
644 $(#[cfg($feat)])?
645 impl From<<$Host as crate::traits::HostTrait>::Device> for Device {
646 fn from(h: <$Host as crate::traits::HostTrait>::Device) -> Self {
647 DeviceInner::$HostVariant(h).into()
648 }
649 }
650
651 $(#[cfg($feat)])?
652 impl From<<$Host as crate::traits::HostTrait>::Devices> for Devices {
653 fn from(h: <$Host as crate::traits::HostTrait>::Devices) -> Self {
654 DevicesInner::$HostVariant(h).into()
655 }
656 }
657
658 $(#[cfg($feat)])?
659 impl From<$Host> for Host {
660 fn from(h: $Host) -> Self {
661 HostInner::$HostVariant(h).into()
662 }
663 }
664
665 $(#[cfg($feat)])?
666 impl From<<<$Host as crate::traits::HostTrait>::Device as crate::traits::DeviceTrait>::Stream> for Stream {
667 fn from(h: <<$Host as crate::traits::HostTrait>::Device as crate::traits::DeviceTrait>::Stream) -> Self {
668 StreamInner::$HostVariant(h).into()
669 }
670 }
671 )*
672
673 /// Produces a list of hosts that are currently available on the system.
674 pub fn available_hosts() -> Vec<HostId> {
675 let mut host_ids = vec![];
676 $(
677 $(#[cfg($feat)])?
678 if <$Host as crate::traits::HostTrait>::is_available() {
679 host_ids.push(HostId::$HostVariant);
680 }
681 )*
682 host_ids
683 }
684
685 /// Given a unique host identifier, initialise and produce the host if it is available.
686 pub fn host_from_id(id: HostId) -> Result<Host, crate::HostUnavailable> {
687 match id {
688 $(
689 $(#[cfg($feat)])?
690 HostId::$HostVariant => {
691 <$Host>::new()
692 .map(HostInner::$HostVariant)
693 .map(Host::from)
694 }
695 )*
696 }
697 }
698
699 impl Default for Host {
700 fn default() -> Host {
701 default_host()
702 }
703 }
704 };
705}
706
707#[cfg(any(
708 target_os = "linux",
709 target_os = "dragonfly",
710 target_os = "freebsd",
711 target_os = "netbsd"
712))]
713mod platform_impl {
714 #[cfg_attr(
715 docsrs,
716 doc(cfg(any(
717 target_os = "linux",
718 target_os = "dragonfly",
719 target_os = "freebsd",
720 target_os = "netbsd"
721 )))
722 )]
723 pub use crate::host::alsa::Host as AlsaHost;
724 #[cfg(feature = "jack")]
725 #[cfg_attr(
726 docsrs,
727 doc(cfg(all(
728 any(
729 target_os = "linux",
730 target_os = "dragonfly",
731 target_os = "freebsd",
732 target_os = "netbsd"
733 ),
734 feature = "jack"
735 )))
736 )]
737 pub use crate::host::jack::Host as JackHost;
738 #[cfg(feature = "pipewire")]
739 #[cfg_attr(
740 docsrs,
741 doc(cfg(all(
742 any(
743 target_os = "linux",
744 target_os = "dragonfly",
745 target_os = "freebsd",
746 target_os = "netbsd"
747 ),
748 feature = "pipewire"
749 )))
750 )]
751 pub use crate::host::pipewire::Host as PipeWireHost;
752 #[cfg(feature = "pulseaudio")]
753 #[cfg_attr(
754 docsrs,
755 doc(cfg(all(
756 any(
757 target_os = "linux",
758 target_os = "dragonfly",
759 target_os = "freebsd",
760 target_os = "netbsd"
761 ),
762 feature = "pulseaudio"
763 )))
764 )]
765 pub use crate::host::pulseaudio::Host as PulseAudioHost;
766 impl_platform_host!(
767 #[cfg(feature = "pipewire")] PipeWire => PipeWireHost,
768 #[cfg(feature = "pulseaudio")] PulseAudio => PulseAudioHost,
769 #[cfg(feature = "jack")] Jack => JackHost,
770 Alsa => AlsaHost,
771 #[cfg(feature = "custom")] Custom => super::CustomHost,
772 );
773
774 /// The default host for the current compilation target platform.
775 pub fn default_host() -> Host {
776 #[cfg(feature = "pipewire")]
777 if <PipeWireHost as crate::traits::HostTrait>::is_available() {
778 if let Ok(host) = PipeWireHost::new() {
779 return host.into();
780 }
781 }
782 #[cfg(feature = "pulseaudio")]
783 if <PulseAudioHost as crate::traits::HostTrait>::is_available() {
784 if let Ok(host) = PulseAudioHost::new() {
785 return host.into();
786 }
787 }
788 AlsaHost::new()
789 .expect("the default host should always be available")
790 .into()
791 }
792}
793
794#[cfg(any(target_os = "macos", target_os = "ios"))]
795mod platform_impl {
796 #[cfg_attr(docsrs, doc(cfg(any(target_os = "macos", target_os = "ios"))))]
797 pub use crate::host::coreaudio::Host as CoreAudioHost;
798 #[cfg(all(feature = "jack", target_os = "macos"))]
799 #[cfg_attr(docsrs, doc(cfg(all(feature = "jack", target_os = "macos"))))]
800 pub use crate::host::jack::Host as JackHost;
801
802 impl_platform_host!(
803 CoreAudio => CoreAudioHost,
804 #[cfg(all(feature = "jack", target_os = "macos"))] Jack => JackHost,
805 #[cfg(feature = "custom")] Custom => super::CustomHost
806 );
807
808 /// The default host for the current compilation target platform.
809 pub fn default_host() -> Host {
810 CoreAudioHost::new()
811 .expect("the default host should always be available")
812 .into()
813 }
814}
815
816#[cfg(target_os = "emscripten")]
817mod platform_impl {
818 #[cfg_attr(docsrs, doc(cfg(target_os = "emscripten")))]
819 pub use crate::host::emscripten::Host as EmscriptenHost;
820 impl_platform_host!(
821 Emscripten => EmscriptenHost,
822 #[cfg(feature = "custom")] Custom => super::CustomHost
823 );
824
825 /// The default host for the current compilation target platform.
826 pub fn default_host() -> Host {
827 EmscriptenHost::new()
828 .expect("the default host should always be available")
829 .into()
830 }
831}
832
833#[cfg(all(target_arch = "wasm32", feature = "wasm-bindgen"))]
834mod platform_impl {
835 #[cfg_attr(
836 docsrs,
837 doc(cfg(all(target_arch = "wasm32", feature = "wasm-bindgen")))
838 )]
839 pub use crate::host::webaudio::Host as WebAudioHost;
840
841 #[cfg(feature = "audioworklet")]
842 #[cfg_attr(
843 docsrs,
844 doc(cfg(all(
845 target_arch = "wasm32",
846 feature = "wasm-bindgen",
847 feature = "audioworklet"
848 )))
849 )]
850 pub use crate::host::audioworklet::Host as AudioWorkletHost;
851
852 impl_platform_host!(
853 WebAudio => WebAudioHost,
854 #[cfg(feature = "audioworklet")] AudioWorklet => AudioWorkletHost,
855 #[cfg(feature = "custom")] Custom => super::CustomHost
856 );
857
858 /// The default host for the current compilation target platform.
859 pub fn default_host() -> Host {
860 WebAudioHost::new()
861 .expect("the default host should always be available")
862 .into()
863 }
864}
865
866#[cfg(windows)]
867mod platform_impl {
868 #[cfg(feature = "asio")]
869 #[cfg_attr(docsrs, doc(cfg(all(windows, feature = "asio"))))]
870 pub use crate::host::asio::Host as AsioHost;
871 #[cfg(feature = "jack")]
872 #[cfg_attr(docsrs, doc(cfg(all(windows, feature = "jack"))))]
873 pub use crate::host::jack::Host as JackHost;
874 #[cfg_attr(docsrs, doc(cfg(windows)))]
875 pub use crate::host::wasapi::Host as WasapiHost;
876
877 impl_platform_host!(
878 #[cfg(feature = "asio")] Asio => AsioHost,
879 Wasapi => WasapiHost,
880 #[cfg(feature = "jack")] Jack => JackHost,
881 #[cfg(feature = "custom")] Custom => super::CustomHost,
882 );
883
884 /// The default host for the current compilation target platform.
885 pub fn default_host() -> Host {
886 WasapiHost::new()
887 .expect("the default host should always be available")
888 .into()
889 }
890}
891
892#[cfg(target_os = "android")]
893mod platform_impl {
894 #[cfg_attr(docsrs, doc(cfg(target_os = "android")))]
895 pub use crate::host::aaudio::Host as AAudioHost;
896 impl_platform_host!(
897 AAudio => AAudioHost,
898 #[cfg(feature = "custom")] Custom => super::CustomHost
899 );
900
901 /// The default host for the current compilation target platform.
902 pub fn default_host() -> Host {
903 AAudioHost::new()
904 .expect("the default host should always be available")
905 .into()
906 }
907}
908
909#[cfg(not(any(
910 windows,
911 target_os = "linux",
912 target_os = "dragonfly",
913 target_os = "freebsd",
914 target_os = "netbsd",
915 target_os = "macos",
916 target_os = "ios",
917 target_os = "emscripten",
918 target_os = "android",
919 all(target_arch = "wasm32", feature = "wasm-bindgen"),
920)))]
921mod platform_impl {
922 #[cfg_attr(
923 docsrs,
924 doc(cfg(not(any(
925 windows,
926 target_os = "linux",
927 target_os = "dragonfly",
928 target_os = "freebsd",
929 target_os = "netbsd",
930 target_os = "macos",
931 target_os = "ios",
932 target_os = "emscripten",
933 target_os = "android",
934 all(target_arch = "wasm32", feature = "wasm-bindgen")
935 ))))
936 )]
937 pub use crate::host::null::Host as NullHost;
938
939 impl_platform_host!(
940 Null => NullHost,
941 #[cfg(feature = "custom")] Custom => super::CustomHost,
942 );
943
944 /// The default host for the current compilation target platform.
945 pub fn default_host() -> Host {
946 NullHost::new()
947 .expect("the default host should always be available")
948 .into()
949 }
950}