# How Meetily Implements Platform-Specific Audio Device Discovery (Windows WASAPI, macOS ScreenCaptureKit, Linux ALSA/PulseAudio)

> Discover how Meetily achieves platform-specific audio device discovery using WASAPI, ScreenCaptureKit, and ALSA/PulseAudio. Learn about our unified interface for Tauri.

- Repository: [Zackriya Solutions/meetily](https://github.com/Zackriya-Solutions/meetily)
- Tags: internals
- Published: 2026-07-10

---

**Meetily abstracts audio device enumeration behind a conditional compilation layer that dispatches to WASAPI on Windows, ScreenCaptureKit/CoreAudio on macOS, and ALSA/PulseAudio on Linux, exposing a unified `Vec<AudioDevice>` interface to the Tauri frontend.**

Meetily's audio subsystem handles the complexity of cross-platform device enumeration through a Rust module located at `frontend/src-tauri/src/audio/devices`. The implementation leverages the **Cross-Platform Audio Library (CPAL)** as a foundation while incorporating platform-specific APIs to capture system audio and hardware inputs correctly. This architecture ensures that the desktop application can consistently discover microphones, speakers, and loopback devices across Windows, macOS, and Linux without platform-specific code polluting the UI layer.

## Architecture Overview

The public API entry point is `list_audio_devices()` defined 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 creates a **CPAL default host** and then dispatches to platform-specific helpers gated by `#[cfg(target_os = "...")]` attributes:

```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 vector of `AudioDevice` structs (defined in [`configuration.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/configuration.rs)), normalized with `DeviceType` classifications indicating whether the device is an input (microphone) or output (speaker/loopback) source.

## Windows WASAPI Implementation

The Windows implementation 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)** to enable loopback capture of system audio.

### WASAPI Host Initialization

The `configure_windows_audio` function attempts to instantiate a dedicated WASAPI host using `cpal::host_from_id(cpal::HostId::Wasapi)`. This host provides access to both input devices and output devices with loopback capabilities. The function iterates through available devices (lines 15-38), converting each CPAL device into an `AudioDevice` instance with appropriate `DeviceType` metadata.

### Fallback Strategy

If WASAPI initialization fails or yields no devices, the implementation falls back to the default CPAL host enumeration (lines 47-68). This ensures that even on systems with restricted audio drivers or deprecated WASAPI support, at minimum the system default input and output devices are available to the application.

## macOS ScreenCaptureKit and CoreAudio Implementation

On macOS, the 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) combines **CoreAudio** for hardware device enumeration with considerations for **ScreenCaptureKit** requirements.

### Input Device Enumeration

The `configure_macos_audio` function uses the standard CPAL host to enumerate input devices (microphones). This covers built-in microphones, wired headsets, and Bluetooth audio devices including AirPods.

### Output Filtering

Unlike Windows, macOS does not expose speaker outputs as recordable sources through standard audio APIs. The code explicitly filters out built-in speakers (lines 11-32) because they cannot capture system audio without ScreenCaptureKit integration. Bluetooth and external audio devices are preserved in the enumeration, allowing the application to distinguish between capture-capable hardware and non-capture outputs.

## Linux ALSA and PulseAudio Implementation

The Linux implementation 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) handles the fragmentation between **ALSA** (Advanced Linux Sound Architecture) and **PulseAudio** server configurations.

### Input Device Collection

The function first gathers all input devices using the default CPAL host, which typically interfaces with ALSA directly. This captures hardware microphones and line-in sources available to the kernel.

### Monitor Source Detection

To capture system audio (output), the code explicitly opens an ALSA-specific host using `cpal::host_from_id(cpal::HostId::Alsa)` and searches for **PulseAudio monitor sources** (lines 17-28). These virtual devices, named with "…monitor…" patterns, represent the audio streams being played to speakers. When detected, these are added to the device list with `DeviceType::Output`, enabling application audio recording alongside microphone input.

## Permission Handling Across Platforms

Some platforms require explicit user consent before accessing audio hardware. The `trigger_audio_permission` function (also in [`discovery.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/discovery.rs)) handles this by attempting to build a short-lived input stream. On macOS and Windows, this action triggers the operating system's permission dialog. The function returns a boolean indicating whether the user granted access, allowing the UI to gate device enumeration behind proper authorization.

## Deduplication and Unified Device List

After platform-specific collection completes, `list_audio_devices` performs a final deduplication pass using `host.devices()` (the generic CPAL enumeration). Any devices not captured by the platform-specific helpers are added to the final list and marked as output devices. This guarantees comprehensive device visibility even when specialized enumeration logic misses obscure or newly attached hardware.

## Summary

- **Entry Point**: The `list_audio_devices()` function in [`discovery.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/discovery.rs) provides a unified async interface for device enumeration.
- **Conditional Dispatch**: `#[cfg(target_os = "...")]` attributes route to `configure_windows_audio`, `configure_macos_audio`, or `configure_linux_audio` based on the compilation target.
- **Windows**: Uses WASAPI with automatic fallback to default CPAL hosts for maximum compatibility.
- **macOS**: Filters built-in speakers while preserving Bluetooth devices, acknowledging ScreenCaptureKit limitations.
- **Linux**: Explicitly detects PulseAudio monitor sources via ALSA hosts to enable system audio capture.
- **Permissions**: `trigger_audio_permission` prompts users for microphone access on restrictive platforms.
- **Data Model**: All platforms return standardized `AudioDevice` structs with `DeviceType` classification, decoupling the UI from OS-specific audio APIs.

## Frequently Asked Questions

### How does Meetily handle audio device discovery on Windows without WASAPI support?

If WASAPI initialization fails or returns no devices, the Windows implementation falls back to the default CPAL host enumeration. This ensures the application can still access standard input and output devices even on systems with restricted drivers or older Windows versions that lack full WASAPI support.

### Why does Meetily exclude built-in speakers on macOS but include them on Windows?

macOS built-in speakers cannot be captured as audio sources through CoreAudio without using ScreenCaptureKit, so the [`macos.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/macos.rs) implementation filters them out to prevent user confusion. Windows WASAPI provides loopback capture capabilities for all output devices, making speaker enumeration valuable for system audio recording.

### How does Meetily capture system audio on Linux distributions using PulseAudio?

The Linux implementation explicitly opens an ALSA host and searches for PulseAudio monitor sources—virtual devices named with "monitor" patterns that represent the audio stream being played to speakers. These are classified as `DeviceType::Output` and added to the device list alongside hardware microphones.

### What triggers the microphone permission dialog on macOS?

The `trigger_audio_permission` function attempts to build and briefly instantiate an input stream using CPAL. This action prompts macOS to display the standard microphone permission dialog if the user hasn't previously granted access, returning a boolean indicating the permission state.