(
settings: MicSettings,
samples: &Arc<Mutex<Vec<i16>>>,
stream_cursor: &Arc<Mutex<usize>>,
)
| 657 | } |
| 658 | |
| 659 | /// The default host plus every optional backend compiled in (ASIO via the |
| 660 | /// `mic-asio` feature, JACK via `mic-jack`). Without those features this is |
| 661 | /// exactly one host, so scan behavior matches the plain build. |
| 662 | #[cfg(not(target_arch = "wasm32"))] |
| 663 | fn input_hosts() -> Vec<(cpal::Host, bool)> { |
| 664 | let default = cpal::default_host(); |
| 665 | let default_id = default.id(); |
| 666 | let mut hosts = vec![(default, true)]; |
| 667 | for id in cpal::available_hosts() { |
| 668 | if id == default_id { |
| 669 | continue; |
| 670 | } |
| 671 | if let Ok(host) = cpal::host_from_id(id) { |
| 672 | hosts.push((host, false)); |
| 673 | } |
| 674 | } |
| 675 | hosts |
| 676 | } |
| 677 | |
| 678 | /// Selection name for a device: raw on the default host, `HOST: name` on an |
| 679 | /// optional backend so twin listings (WASAPI + ASIO see the same interface) |
| 680 | /// stay distinct and a cached pick reopens on the right backend. |
| 681 | #[cfg(not(target_arch = "wasm32"))] |
| 682 | fn host_device_name(host_name: &str, raw_name: &str, default_host: bool) -> String { |
| 683 | if default_host { |
| 684 | raw_name.to_string() |
| 685 | } else { |
| 686 | format!("{host_name}: {raw_name}") |
| 687 | } |
| 688 | } |
| 689 | |
| 690 | /// All input devices across every available host, default host first (its |
| 691 | /// default device leading), under the names selection and scan both use. |
| 692 | #[cfg(not(target_arch = "wasm32"))] |
| 693 | fn enumerate_inputs() -> Result<Vec<EnumeratedInput>, String> { |
| 694 | use cpal::traits::{DeviceTrait, HostTrait}; |
| 695 | |
| 696 | let mut out: Vec<EnumeratedInput> = Vec::new(); |
| 697 | let mut errors: Vec<String> = Vec::new(); |
| 698 | for (host, default_host) in input_hosts() { |
| 699 | let host_name = host.id().name(); |
| 700 | let default_name = if default_host { |
| 701 | host.default_input_device() |
| 702 | .and_then(|device| device.name().ok()) |
| 703 | } else { |
| 704 | None |
| 705 | }; |
| 706 | let found = match host.input_devices() { |
| 707 | Ok(devices) => devices.collect::<Vec<_>>(), |
| 708 | Err(err) => { |
| 709 | // Some backends refuse a full scan but still hand out the default. |
| 710 | if let Some(device) = host.default_input_device() { |
| 711 | vec![device] |
| 712 | } else { |
| 713 | errors.push(format!("{host_name}: {err}")); |
| 714 | continue; |
| 715 | } |
| 716 | } |
no test coverage detected