shady_audio/
util.rs

1use cpal::traits::{DeviceTrait, HostTrait};
2
3type Devices = std::iter::Filter<cpal::Devices, for<'a> fn(&'a cpal::Device) -> bool>;
4
5/// A little helper enum to set the type of a device.
6#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Hash)]
7pub enum DeviceType {
8    /// Input audio devices
9    Input,
10    /// Output audio devices
11    Output,
12}
13
14/// Returns the given output/input device with the given name.
15/// You can retrieve a list of available names by using the [`get_device_names`] function.
16///
17/// Returns `Err` if there's a problem retrieving an output/input device.
18/// Returns `Ok(None)` if retrieveing the output/input devices worked find but it couldn't find a device with the given name.
19pub fn get_device<S: AsRef<str>>(
20    name: S,
21    device_type: DeviceType,
22) -> Result<Option<cpal::Device>, cpal::DevicesError> {
23    let mut devices = get_devices(device_type)?;
24
25    Ok(devices.find(|d| {
26        d.name()
27            .map(|d_name| d_name.as_str() == name.as_ref())
28            .unwrap_or(false)
29    }))
30}
31
32/// Returns the default device of he given device type (if available).
33pub fn get_default_device(device_type: DeviceType) -> Option<cpal::Device> {
34    let host = cpal::default_host();
35
36    match device_type {
37        DeviceType::Input => host.default_input_device(),
38        DeviceType::Output => host.default_output_device(),
39    }
40}
41
42fn get_devices(device_type: DeviceType) -> Result<Devices, cpal::DevicesError> {
43    let host = cpal::default_host();
44
45    match device_type {
46        DeviceType::Input => host.input_devices(),
47        DeviceType::Output => host.output_devices(),
48    }
49}
50
51/// Returns a list of device names which you can use for [`get_device`].
52/// Retunrs `Err` if there's a problem retrieving an output/input device.
53pub fn get_device_names(device_type: DeviceType) -> Result<Vec<String>, cpal::DevicesError> {
54    let devices = get_devices(device_type)?;
55
56    Ok(devices.filter_map(|d| d.name().ok()).collect())
57}