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.

enumerate.rs · 102 lines · 3.7 KBRust Blame HistoryRaw
Lift freeq's AV media plane out of sleek 90f8b89 nandi 19d ago1//! Enumerates all available audio hosts, devices, and their supported configurations.
2//!
3//! This example demonstrates:
4//! - Querying available audio hosts on the system
5//! - Enumerating all audio devices for each host
6//! - Retrieving device IDs for persistent identification
7//! - Getting device descriptions with metadata
8//! - Listing supported input and output stream configurations
9//!
10//! Run with: `cargo run --example enumerate`
11
12extern crate anyhow;
13extern crate cpal;
14
15use cpal::traits::{DeviceTrait, HostTrait};
16
17fn main() -> Result<(), anyhow::Error> {
18 // To print raw ALSA errors to stderr during enumeration, comment out the line below:
19 #[cfg(target_os = "linux")]
20 let _silence_alsa_errors = alsa::Output::local_error_handler()?;
21
22 println!("Supported hosts:\n {:?}", cpal::ALL_HOSTS);
23 let available_hosts = cpal::available_hosts();
24 println!("Available hosts:\n {available_hosts:?}");
25
26 for host_id in available_hosts {
27 println!("{}", host_id.name());
28 let host = cpal::host_from_id(host_id)?;
29
30 let default_in = host
31 .default_input_device()
32 .map(|dev| dev.id().unwrap())
33 .map(|id| id.to_string());
34 let default_out = host
35 .default_output_device()
36 .map(|dev| dev.id().unwrap())
37 .map(|id| id.to_string());
38 println!(" Default Input Device:\n {default_in:?}");
39 println!(" Default Output Device:\n {default_out:?}");
40
41 let devices = host.devices()?;
42 println!(" Devices: ");
43 for (device_index, device) in devices.enumerate() {
44 let id = device
45 .id()
46 .map_or("Unknown ID".to_string(), |id| id.to_string());
47 if let Ok(desc) = device.description() {
48 println!(" {}. {id} ({})", device_index + 1, desc);
49 } else {
50 println!(" {}. {id}", device_index + 1);
51 }
52
53 // Input configs
54 if let Ok(conf) = device.default_input_config() {
55 println!(" Default input stream config:\n {conf:?}");
56 }
57 let input_configs = match device.supported_input_configs() {
58 Ok(f) => f.collect(),
59 Err(e) => {
60 println!(" Error getting supported input configs: {e:?}");
61 Vec::new()
62 }
63 };
64 if !input_configs.is_empty() {
65 println!(" All supported input stream configs:");
66 for (config_index, config) in input_configs.into_iter().enumerate() {
67 println!(
68 " {}.{}. {:?}",
69 device_index + 1,
70 config_index + 1,
71 config
72 );
73 }
74 }
75
76 // Output configs
77 if let Ok(conf) = device.default_output_config() {
78 println!(" Default output stream config:\n {conf:?}");
79 }
80 let output_configs = match device.supported_output_configs() {
81 Ok(f) => f.collect(),
82 Err(e) => {
83 println!(" Error getting supported output configs: {e:?}");
84 Vec::new()
85 }
86 };
87 if !output_configs.is_empty() {
88 println!(" All supported output stream configs:");
89 for (config_index, config) in output_configs.into_iter().enumerate() {
90 println!(
91 " {}.{}. {:?}",
92 device_index + 1,
93 config_index + 1,
94 config
95 );
96 }
97 }
98 }
99 }
100
101 Ok(())
102}