# How Meetily Handles Audio Device Discovery: WASAPI, ScreenCaptureKit, and ALSA Implementation

> Discover how Meetily’s Rust abstraction layer unifies audio device discovery across Windows WASAPI, macOS ScreenCaptureKit, and Linux ALSA for seamless audio integration.

- Repository: [Zackriya Solutions/meetily](https://github.com/Zackriya-Solutions/meetily)
- Tags: deep-dive
- Published: 2026-07-06

---

**Meetily uses a Rust-based abstraction layer built on CPAL that routes platform-specific calls to dedicated modules for Windows WASAPI, macOS ScreenCaptureKit/CoreAudio, and Linux ALSA/PulseAudio, then deduplicates results into a unified device list.**

The open-source Meetily application (Zackriya-Solutions/meetily) implements a robust cross-platform audio discovery system in its Tauri backend. The architecture cleanly separates platform-specific enumeration logic while presenting a single, consistent API to the frontend.

## Architecture Overview

The entry point for all audio discovery is `list_audio_devices()` in [`frontend/src-tauri/src/audio/devices/discovery.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/devices/discovery.rs). This function uses **CPAL** (Cross-Platform Audio Library) to create a default host, then dispatches to platform-specific helpers gated by conditional compilation attributes.

The system uses `#[cfg(target_os = "...")]` to route execution at compile time:

```rust
#[cfg(target_os = "windows")] { platform::configure_windows_audio(&host)? }
#[cfg(target_os = "linux")]   { platform::configure_linux_audio(&host)? }
#[cfg(target_os = "macos")]   { platform::configure_macos_audio(&host)? }

```

Each platform module returns a collection of `AudioDevice` structs defined in [`frontend/src-tauri/src/audio/devices/configuration.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/devices/configuration.rs), ensuring type safety across the FFI boundary to the TypeScript frontend.

## Windows WASAPI Implementation

On Windows, the `configure_windows_audio` function in [`frontend/src-tauri/src/audio/devices/platform/windows.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/devices/platform/windows.rs) prioritizes WASAPI (Windows Audio Session API) for low-level hardware access.

### WASAPI Host Creation and Enumeration

The helper first attempts to instantiate a dedicated WASAPI host using `cpal::host_from_id(cpal::HostId::Wasapi)`. It then enumerates both output devices (including loopback capture) and input devices, mapping each to an `AudioDevice` instance with the appropriate `DeviceType` classification.

The implementation covers lines 15–38 in [`windows.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/windows.rs), where it iterates through device lists and extracts hardware identifiers.

### Fallback Strategy

If WASAPI initialization fails or yields no devices, the system falls back to the default CPAL host (lines 47–68). This ensures that even on restricted systems or when WASAPI is unavailable, at minimum the system default input and output devices remain discoverable.

## macOS ScreenCaptureKit and CoreAudio Integration

The macOS implementation in [`frontend/src-tauri/src/audio/devices/platform/macos.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/devices/platform/macos.rs) handles the complexities of Apple's audio ecosystem, including the separation between input (microphone) and output devices.

### Input Device Enumeration

For input devices, the system uses the standard CPAL host enumeration. This captures microphones and external audio interfaces recognized by CoreAudio.

### Output Filtering Logic

macOS output devices require special handling because built-in speakers cannot capture system audio. The code filters out devices identified as built-in speakers while preserving Bluetooth devices like AirPods (lines 11–32). This reflects macOS's security model where system audio capture requires either ScreenCaptureKit or specific loopback driver configurations.

## Linux ALSA and PulseAudio Support

Linux audio discovery in [`frontend/src-tauri/src/audio/devices/platform/linux.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/devices/platform/linux.rs) addresses the fragmented nature of Linux audio stacks by combining CPAL's default host with explicit ALSA host access.

### Input Device Collection

The function first gathers all input devices through the default host, capturing microphones and line-in sources managed by PulseAudio or PipeWire.

### Monitor Source Detection

To capture system audio, the implementation explicitly opens an ALSA host (`cpal::host_from_id(cpal::HostId::Alsa)`) and searches for PulseAudio monitor sources. These devices—typically named with "monitor" in their identifier—represent software loopback streams that allow recording of system output (lines 17–28).

This dual-host approach ensures compatibility across distributions using PulseAudio, PipeWire, or pure ALSA configurations.

## Device Deduplication and Unified API

After platform-specific collection, `list_audio_devices` performs a final pass over `host.devices()` (the generic CPAL enumeration). It adds any devices not captured by the platform-specific helpers, marking them as output devices. This deduplication step guarantees that virtual devices, specialized drivers, or unusual hardware configurations remain visible to the UI even if they bypass the platform optimizations.

## Handling Microphone Permissions

Some platforms require explicit user consent before enumerating audio devices. The `trigger_audio_permission` function (also in [`discovery.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/discovery.rs)) handles this by constructing a short-lived input stream. Attempting to play this stream triggers the operating system's permission dialog. The function returns a boolean indicating whether access was granted, allowing the frontend to request permission gracefully before full device enumeration.

```rust
// Example: Retrieve the list of available audio devices (async)
use meetily::frontend::src_tauri::audio::devices::discovery::list_audio_devices;

#[tokio::main]
async fn main() {
    match list_audio_devices().await {
        Ok(devices) => {
            for dev in devices {
                println!("{} ({:?})", dev.name, dev.device_type);
            }
        }
        Err(e) => eprintln!("Failed to enumerate devices: {:#}", e),
    }
}

```

```rust
// Example: Prompt the user for microphone permission (macOS/Windows)
use meetily::frontend::src_tauri::audio::devices::discovery::trigger_audio_permission;

fn request_permission() {
    match trigger_audio_permission() {
        Ok(true) => println!("Permission granted!"),
        Ok(false) => println!("Permission denied or unavailable."),
        Err(e) => eprintln!("Error while checking permission: {:#}", e),
    }
}

```

## Summary

- **Unified Entry Point**: The `list_audio_devices()` function in [`discovery.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/discovery.rs) provides a single async API for all platforms.
- **Conditional Compilation**: Rust's `#[cfg(target_os = "...")]` attributes route to platform-specific modules at compile time.
- **Windows**: Prefers WASAPI with automatic fallback to default CPAL host if enumeration fails.
- **macOS**: Uses CoreAudio for input while filtering built-in speakers from output; supports Bluetooth devices.
- **Linux**: Combines default host input enumeration with ALSA-specific monitor source detection for system audio capture.
- **Deduplication**: Final pass ensures no devices are missed by platform-specific logic.
- **Permissions**: `trigger_audio_permission` uses stream creation to prompt for microphone access on restrictive platforms.

## Frequently Asked Questions

### How does Meetily handle audio permissions on macOS?

Meetily calls `trigger_audio_permission`, which creates a temporary input stream. This action triggers the macOS system dialog requesting microphone access. The function returns `true` if permission is granted, allowing the application to proceed with full device enumeration. Without this permission, CoreAudio device lists may return empty or incomplete results.

### What happens if WASAPI fails on Windows?

If the WASAPI host initialization fails or returns no devices, the Windows module falls back to the default CPAL host. This ensures that at minimum, the system default input and output devices are available to the user, maintaining functionality even on restricted Windows environments or when audio drivers are misconfigured.

### Why does Meetily use ALSA specifically for monitor sources on Linux?

PulseAudio and PipeWire expose system audio capture through "monitor" sources that are technically ALSA devices. By explicitly instantiating an ALSA host (`cpal::HostId::Alsa`) alongside the default host, Meetily can access these monitor sources while still capturing standard input devices through the higher-level abstraction. This handles the Linux audio stack's separation between hardware and software audio streams.

### Can Meetily discover Bluetooth audio devices?

Yes. On macOS, the code explicitly allows Bluetooth devices like AirPods while filtering out built-in speakers. On Windows and Linux, Bluetooth devices that register as standard audio endpoints with the operating system appear in the device list through the standard CPAL enumeration, provided they are paired and active.