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 · 111 lines · 2.8 KBRust Blame HistoryRaw
Lift freeq's AV media plane out of sleek 90f8b89 nandi 20d ago1//! WASAPI backend implementation.
2//!
3//! Default backend on Windows.
4
5#[allow(unused_imports)]
6pub use self::device::{
7 default_input_device, default_output_device, Device, Devices, SupportedInputConfigs,
8 SupportedOutputConfigs,
9};
10#[allow(unused_imports)]
11pub use self::stream::Stream;
12use crate::traits::HostTrait;
13use crate::BackendSpecificError;
14use crate::DevicesError;
15use std::io::Error as IoError;
16use windows::Win32::Media::Audio;
17
18mod device;
19mod stream;
20
21/// The WASAPI host, the default windows host type.
22///
23/// Note: If you use a WASAPI output device as an input device it will
24/// transparently enable loopback mode (see
25/// https://docs.microsoft.com/en-us/windows/win32/coreaudio/loopback-recording).
26#[derive(Debug)]
27pub struct Host;
28
29impl Host {
30 pub fn new() -> Result<Self, crate::HostUnavailable> {
31 Ok(Host)
32 }
33}
34
35impl HostTrait for Host {
36 type Devices = Devices;
37 type Device = Device;
38
39 fn is_available() -> bool {
40 // Assume WASAPI is always available on Windows.
41 true
42 }
43
44 fn devices(&self) -> Result<Self::Devices, DevicesError> {
45 Devices::new()
46 }
47
48 fn default_input_device(&self) -> Option<Self::Device> {
49 default_input_device()
50 }
51
52 fn default_output_device(&self) -> Option<Self::Device> {
53 default_output_device()
54 }
55}
56
57impl From<windows::core::Error> for BackendSpecificError {
58 fn from(error: windows::core::Error) -> Self {
59 BackendSpecificError {
60 description: format!("{}", IoError::from(error)),
61 }
62 }
63}
64
65trait ErrDeviceNotAvailable: From<BackendSpecificError> {
66 fn device_not_available() -> Self;
67}
68
69impl ErrDeviceNotAvailable for crate::BuildStreamError {
70 fn device_not_available() -> Self {
71 Self::DeviceNotAvailable
72 }
73}
74
75impl ErrDeviceNotAvailable for crate::SupportedStreamConfigsError {
76 fn device_not_available() -> Self {
77 Self::DeviceNotAvailable
78 }
79}
80
81impl ErrDeviceNotAvailable for crate::DefaultStreamConfigError {
82 fn device_not_available() -> Self {
83 Self::DeviceNotAvailable
84 }
85}
86
87impl ErrDeviceNotAvailable for crate::StreamError {
88 fn device_not_available() -> Self {
89 Self::DeviceNotAvailable
90 }
91}
92
93fn windows_err_to_cpal_err<E: ErrDeviceNotAvailable>(e: windows::core::Error) -> E {
94 windows_err_to_cpal_err_message::<E>(e, "")
95}
96
97fn windows_err_to_cpal_err_message<E: ErrDeviceNotAvailable>(
98 e: windows::core::Error,
99 message: &str,
100) -> E {
101 match e.code() {
102 Audio::AUDCLNT_E_DEVICE_INVALIDATED | Audio::AUDCLNT_E_DEVICE_IN_USE => {
103 E::device_not_available()
104 }
105 _ => {
106 let description = format!("{}{}", message, e);
107 let err = BackendSpecificError { description };
108 err.into()
109 }
110 }
111}