# Platform-Specific Audio Capture in Meetily: WASAPI, ScreenCaptureKit, and ALSA Implementations

> Explore Meetily's platform-specific audio capture: WASAPI for Windows, ScreenCaptureKit for macOS, and ALSA for Linux. Learn how Meetily abstracts native OS APIs for seamless audio device access.

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

---

**Meetily implements audio capture through a modular Rust architecture that abstracts native OS APIs—using WASAPI on Windows, ScreenCaptureKit on macOS, and ALSA/PulseAudio on Linux—exposing a uniform `AudioDevice` interface regardless of platform.**

Meetily is an open-source meeting transcription application developed by Zackriya-Solutions that processes audio locally for privacy. According to the source code in `frontend/src-tauri/src/audio/devices/`, the application leverages conditional compilation to provide高性能, low-latency recording across all three major desktop platforms while maintaining a consistent API for the transcription pipeline.

## Windows Audio Capture with WASAPI

On Windows, Meetily utilizes the **Windows Audio Session API (WASAPI)** to enumerate input devices and capture system audio. The platform-specific logic 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)](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/devices/platform/windows.rs).

The `configure_windows_audio()` function enumerates all available input and output devices through the WASAPI host. For system audio capture, the implementation leverages WASAPI loopback capabilities, allowing the application to record audio output from other applications without requiring stereo mix drivers. When a user selects a specific device, `get_windows_device()` resolves the selection into a `(cpal::Device, cpal::SupportedStreamConfig)` tuple that the audio pipeline consumes.

```rust
use crate::audio::devices::platform::get_windows_device;
use crate::audio::devices::configuration::AudioDevice;

fn open_windows_device(selected: &AudioDevice) -> anyhow::Result<(cpal::Device, cpal::SupportedStreamConfig)> {
    // Resolve the CPAL device and a compatible config
    get_windows_device(selected)
}

```

## macOS Audio Capture with ScreenCaptureKit and CoreAudio

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)](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/devices/platform/macos.rs) combines **ScreenCaptureKit** for system audio and **CoreAudio** for microphone input.

The `configure_macos_audio()` function uses CPAL's default host to enumerate microphone inputs while filtering built-in speakers from the output device list. ScreenCaptureKit handles the privileged system audio capture required for recording meeting audio from other applications, ensuring compliance with macOS privacy requirements while maintaining low-latency audio quality for transcription.

## Linux Audio Capture with ALSA and PulseAudio

Linux support 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)](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/devices/platform/linux.rs) targets **ALSA** (Advanced Linux Sound Architecture) and **PulseAudio** monitor sources.

The `configure_linux_audio()` function gathers microphone inputs through the default host and specifically identifies PulseAudio monitor sources (devices containing the "monitor" keyword) to enable system audio recording. This approach captures the PulseAudio sink monitor without requiring kernel-level ALSA configuration changes, providing reliable access to system-wide audio on most Linux distributions.

## The Unified Device Discovery Interface

All platform modules are conditionally compiled and re-exported through [[`frontend/src-tauri/src/audio/devices/platform/mod.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/devices/platform/mod.rs)](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/devices/platform/mod.rs), enabling the rest of the application to work with a uniform device structure regardless of the underlying OS.

The entry point `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)](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/devices/discovery.rs) asynchronously creates a `cpal::Host` and delegates to the appropriate platform helper—`configure_windows_audio()`, `configure_macos_audio()`, or `configure_linux_audio()`—based on the `target_os` compilation flag.

```rust
// In a Tauri command or any async context
use crate::audio::devices::discovery::list_audio_devices;

#[tauri::command]
async fn get_available_devices() -> Result<Vec<AudioDevice>, String> {
    list_audio_devices()
        .await
        .map_err(|e| format!("Failed to list audio devices: {}", e))
}

```

For permission handling, `trigger_audio_permission()` constructs a short-lived input stream to provoke the OS permission dialog on macOS and Windows, ensuring user consent before recording begins.

```rust
use crate::audio::devices::discovery::trigger_audio_permission;

#[tauri::command]
fn request_audio_permission() -> Result<bool, String> {
    trigger_audio_permission()
        .map_err(|e| format!("Permission request failed: {}", e))
}

```

## Integrating Platform Audio into the Transcription Pipeline

Once a device is selected, platform-specific resolvers (currently only `get_windows_device()` for Windows) return a `(cpal::Device, cpal::SupportedStreamConfig)` tuple. [[`frontend/src-tauri/src/audio/pipeline.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/pipeline.rs)](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/pipeline.rs) consumes these streams, applies Voice Activity Detection (VAD), mixes microphone and system audio, and forwards the speech-only stream to the Whisper backend.

```rust
let device = /* obtained from platform helper */;
let config = /* chosen SupportedStreamConfig */;

let stream = device.build_input_stream(
    &config.clone().into(),
    move |data: &[f32], _: &cpal::InputCallbackInfo| {
        // Forward raw PCM to the pipeline for mixing/VAD
        audio_pipeline.process_mic_chunk(data);
    },
    |err| eprintln!("Audio stream error: {}", err),
    None,
)?;
stream.play()?; // Begins capturing

```

Because the code relies on the cross-platform `cpal` crate, the platform modules only need to handle OS-specific quirks—such as WASAPI loopback, PulseAudio monitors, or ScreenCaptureKit privileges—while the higher-level audio logic remains portable.

## Summary

- **Windows** uses WASAPI via `configure_windows_audio()` and `get_windows_device()` in [`platform/windows.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/platform/windows.rs) to enumerate devices and support loopback recording.
- **macOS** combines ScreenCaptureKit for system audio with CoreAudio for microphones via `configure_macos_audio()` in [`platform/macos.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/platform/macos.rs).
- **Linux** leverages ALSA and PulseAudio monitor sources via `configure_linux_audio()` in [`platform/linux.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/platform/linux.rs) to capture both microphone and system audio.
- **Abstraction** occurs through [`platform/mod.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/platform/mod.rs) conditional compilation and the [`discovery.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/discovery.rs) module, which exposes `list_audio_devices()` and `trigger_audio_permission()`.
- **Pipeline integration** happens in [`pipeline.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/pipeline.rs), which receives raw audio from the platform layer, applies VAD filtering, and forwards speech data to the Whisper transcription engine.

## Frequently Asked Questions

### How does Meetily capture system audio on Windows without requiring stereo mix drivers?

Meetily uses the **WASAPI loopback** capability available in [`platform/windows.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/platform/windows.rs). The `configure_windows_audio()` function accesses the WASAPI host to enumerate loopback-capable output devices, allowing direct recording of system audio output without relying on legacy stereo mix drivers or virtual audio cables.

### What is the role of ScreenCaptureKit in Meetily's macOS implementation?

ScreenCaptureKit handles **privileged system audio capture** on macOS, enabling Meetily to record audio from other applications while complying with macOS privacy requirements. The `configure_macos_audio()` function in [`platform/macos.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/platform/macos.rs) uses ScreenCaptureKit for system audio alongside CoreAudio for microphone input, filtering built-in speakers from the output list to avoid feedback loops.

### Why does Meetily specifically identify PulseAudio "monitor" sources on Linux?

PulseAudio monitor sources represent sink monitors that allow applications to capture the audio being played through a specific output device. In [`platform/linux.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/platform/linux.rs), the `configure_linux_audio()` function identifies these sources by the "monitor" keyword to enable **system audio recording** without requiring kernel-level ALSA configuration or additional user privileges.

### How does Meetily abstract different native audio APIs into a single cross-platform interface?

Meetily uses **conditional compilation** in [`platform/mod.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/platform/mod.rs) to re-export only the current platform's module, while [`discovery.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/discovery.rs) provides a unified `list_audio_devices()` async function. This architecture allows the transcription pipeline in [`pipeline.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/pipeline.rs) to work with a standard `AudioDevice` struct and `cpal::Device` objects regardless of whether the underlying implementation uses WASAPI, ScreenCaptureKit, or ALSA.