# How Meetily Manages Platform-Specific Audio Handling: WASAPI, ScreenCaptureKit, and ALSA Implementation

> Discover how Meetily's Rust cpal implementation handles platform-specific audio on Windows WASAPI, macOS ScreenCaptureKit, and Linux ALSA/PulseAudio, normalizing streams for unified processing.

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

---

**Meetily uses the Rust `cpal` crate to abstract OS audio APIs, selecting WASAPI for Windows, ScreenCaptureKit for macOS, and ALSA with PulseAudio monitors for Linux, then normalizes all streams to 48 kHz stereo F32 for processing.**

Meetily's cross-platform audio stack handles the complexities of modern operating systems through a unified abstraction layer. The application leverages the `cpal` crate to interface with platform-specific audio handling mechanisms across Windows, macOS, and Linux. This architecture allows the meeting assistant to capture both microphone input and system audio consistently regardless of the underlying host API.

## Windows WASAPI Implementation

On Windows, Meetily configures audio capture through the Windows Audio Session API (WASAPI). The implementation resides 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).

The `configure_windows_audio` function initializes a WASAPI host using `cpal::HostId::Wasapi`. It enumerates both input and output devices, falling back to the default host if WASAPI is unavailable. When resolving a specific device, `get_windows_device` searches for the device by name and selects a compatible `cpal::SupportedStreamConfig`. The selection priority follows this order:

- Stereo F32 format (preferred)
- Any F32 format
- First available configuration as fallback

This ensures optimal audio quality while maintaining compatibility across different hardware configurations.

## macOS ScreenCaptureKit Integration

macOS audio capture relies on Apple's ScreenCaptureKit framework for system audio capture. The implementation spans [`frontend/src-tauri/src/audio/stream.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/stream.rs) and [`frontend/src-tauri/src/audio/capture/backend_config.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/capture/backend_config.rs).

The `AudioCaptureBackend` enum defines `ScreenCaptureKit` as a variant, which maps to the `cpal::HostId::ScreenCaptureKit` host ID. When `AudioStream::new` receives `backend_type == AudioCaptureBackend::ScreenCaptureKit`, it creates a CPAL stream using the ScreenCaptureKit host. This backend captures the digital output stream directly, providing consistent sample rates and low latency for system audio.

ScreenCaptureKit captures the audio output without requiring kernel extensions or virtual audio drivers, making it the preferred method for macOS Ventura and later.

## Linux ALSA and PulseAudio Support

Linux audio handling combines ALSA at the system level with PulseAudio monitor sources for system audio capture. The platform-specific logic is implemented 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).

The `configure_linux_audio` function uses the default ALSA host to list input devices. It then specifically scans for PulseAudio monitor sources—devices containing "monitor" in their name—which represent system audio playback streams. These monitor sources are classified as `DeviceType::Output` and can be mixed with microphone audio.

This approach allows Meetily to capture system audio on Linux without requiring complex PulseAudio configuration, simply by detecting the virtual monitor devices that PulseAudio exposes through ALSA.

## Common Audio Pipeline Flow

After platform-specific device resolution, Meetily normalizes all audio streams through a common pipeline defined in [`frontend/src-tauri/src/audio/pipeline.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/pipeline.rs).

The flow follows these stages:

1. **Host selection** – `audio::devices::platform::configure_*` functions are invoked from `audio::devices::mod.rs` based on the detected operating system (Windows, macOS, or Linux).

2. **Device enumeration** – Each platform module constructs a `Vec<AudioDevice>` containing device names and `DeviceType` classifications (Input or Output).

3. **Device resolution** – When recording starts, platform-specific functions like `get_windows_device` locate the actual `cpal::Device` and negotiate a `SupportedStreamConfig`.

4. **Stream creation** – `audio::stream::AudioStream` instantiates the CPAL stream with the resolved configuration, feeding audio into the processing pipeline.

The pipeline mixes microphone and system audio streams, applies voice-activity detection (VAD), and forwards speech segments to the Whisper transcription engine. Platform-specific quirks—such as Windows loopback, macOS ScreenCaptureKit privileges, or Linux monitor sources—are handled upstream, allowing the pipeline to operate uniformly on 48 kHz, stereo F32 samples.

## Implementation Examples

### Enumerating Audio Devices

From the TypeScript frontend, devices are retrieved via Tauri commands:

```typescript
// Frontend TypeScript
const devices = await invoke<AudioDevice[]>('list_audio_devices');
console.log('Available audio devices:', devices);

```

The Rust implementation in the Tauri command handler:

```rust
// src/lib.rs
#[tauri::command]
async fn list_audio_devices() -> Result<Vec<AudioDevice>, String> {
    audio::devices::list_all()
        .map_err(|e| e.to_string())
}

```

### Starting a Recording Session

To initiate recording with specific devices:

```typescript
await invoke('start_recording', {
  mic_device_name: "Built-in Microphone",
  system_device_name: "BlackHole 2ch",  // macOS example
  meeting_name: "Team Sync"
});

```

The [`recording_manager.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/recording_manager.rs) file orchestrates this process, selecting the appropriate backend (WASAPI, ScreenCaptureKit, or ALSA) based on the platform and opening the corresponding streams.

## Summary

- Meetily uses the **cpal** crate to abstract Windows (WASAPI), macOS (ScreenCaptureKit), and Linux (ALSA) audio APIs into a unified interface.
- **Windows**: `configure_windows_audio` in [`windows.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/windows.rs) manages WASAPI hosts and device configuration with intelligent format fallback strategies.
- **macOS**: `AudioCaptureBackend::ScreenCaptureKit` enables direct digital audio capture through `AudioStream::new` without virtual drivers.
- **Linux**: `configure_linux_audio` in [`linux.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/linux.rs) detects PulseAudio monitor sources through ALSA, enabling system audio capture alongside microphone input.
- The **pipeline** in [`pipeline.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/pipeline.rs) processes all platforms uniformly as 48 kHz stereo F32 streams after platform-specific device resolution.

## Frequently Asked Questions

### How does Meetily handle audio format incompatibilities across different platforms?

Meetily delegates format negotiation to the `cpal` crate's `SupportedStreamConfig` selection. On Windows, `get_windows_device` explicitly prefers stereo F32 configurations before falling back to any available F32 or default config. This ensures consistent 48 kHz stereo F32 input for the pipeline regardless of the hardware's native capabilities.

### Can Meetily capture system audio on macOS without additional drivers?

Yes. According to the source code in [`frontend/src-tauri/src/audio/capture/backend_config.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/capture/backend_config.rs), Meetily uses `AudioCaptureBackend::ScreenCaptureKit` to capture the digital output stream directly on macOS. ScreenCaptureKit captures system audio without requiring kernel extensions or virtual audio drivers like BlackHole, though it requires the user to grant screen recording permissions.

### Why does the Linux implementation scan for "monitor" devices?

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) searches for devices with "monitor" in their name because these are PulseAudio monitor sources. Monitor sources are virtual ALSA devices that represent the audio output of the system. By detecting and classifying these as `DeviceType::Output`, Meetily can mix system audio with microphone input using standard ALSA APIs.

### What happens if WASAPI is unavailable on a Windows system?

The `configure_windows_audio` function includes fallback logic that defaults to the system's default audio host if WASAPI initialization fails. This ensures the application remains functional even on restricted Windows environments or older systems where WASAPI might be disabled or unavailable, though with potentially reduced functionality for certain capture scenarios.