# How Meetily's Audio Device Modularization Is Structured: A Deep Dive into the Platform-Abstraction Layer

> Explore Meetily's audio device modularization. Discover its four-layer architecture, isolation of OS-specific code, and unified, platform-agnostic API using Rust compile-time configuration.

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

---

**Meetily's audio device modularization implements a four-layer architecture that isolates OS-specific code into dedicated platform modules while exposing a unified, platform-agnostic API through Rust's compile-time configuration system.**

Meetily, an open-source meeting assistant built by Zackriya-Solutions, organizes its audio subsystem under `frontend/src-tauri/src/audio/devices/` using a clean "devices → platform" pattern. This modular design separates device discovery, configuration, and I/O handling from the core application logic, enabling consistent cross-platform behavior across Windows, macOS, and Linux without leaking implementation details into the audio pipeline.

## The Four-Layer Architecture

Meetily's audio device modularization follows a strict hierarchy that abstracts hardware access into four distinct layers, each with specific responsibilities and file locations.

### Device Abstraction Layer

The foundation defines generic audio device types used throughout the codebase regardless of the operating system. Located in [`configuration.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/configuration.rs), this layer exposes the **`AudioDevice`** and **`DeviceControl`** structs that capture universal properties including device name, ID, channel layout, and volume controls.

Supporting files like [`microphone.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/microphone.rs), [`speakers.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/speakers.rs), and [`fallback.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/fallback.rs) provide type-specific implementations, ensuring the rest of the application interacts with audio hardware through consistent data structures rather than raw platform handles.

### Discovery and Configuration Layer

The [`discovery.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/discovery.rs) module provides high-level helpers such as **`list_audio_devices()`** and **`trigger_audio_permission()`** for enumerating available hardware and requesting system permissions. Rather than containing platform logic directly, these functions delegate to OS-specific implementations through the **`AudioPlatform`** trait.

The companion [`configuration.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/configuration.rs) file handles user-provided settings and default device selection, storing parsed configurations that the pipeline uses to initialize capture streams without concerning itself with how the underlying OS identifies audio endpoints.

### Platform Implementation Layer

OS-specific code lives exclusively in the `platform/` subdirectory, with dedicated files for each supported operating system:
- **[`platform/windows.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/platform/windows.rs)** – Implements WASAPI enumeration and control
- **[`platform/macos.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/platform/macos.rs)** – Interfaces with ScreenCaptureKit and CoreAudio
- **[`platform/linux.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/platform/linux.rs)** – Handles ALSA and PulseAudio backends

Each file implements the same **`AudioPlatform`** trait with methods like **`enumerate_input_devices()`** and **`enumerate_output_devices()`**, ensuring identical behavior across platforms while containing all system dependencies within isolated compilation units.

### Public API Layer

The [`mod.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/mod.rs) file serves as the single entry point for the entire audio device subsystem. Using conditional compilation attributes (`#[cfg]`), it selects the appropriate platform implementation at compile time and re-exports the public functions. This design allows callers throughout Meetily to use `audio::devices::list_audio_devices()` without managing platform-specific imports or conditional logic themselves.

## How Platform Abstraction Works

The modularization relies on Rust's trait system to enforce consistent interfaces across operating systems. The **`AudioPlatform`** trait defines the contract that every OS implementation must fulfill:

```rust
// From platform/windows.rs (similar for macos.rs and linux.rs)
#[cfg(target_os = "windows")]
impl AudioPlatform for WindowsPlatform {
    fn enumerate_input_devices(&self) -> Result<Vec<AudioDevice>> {
        // WASAPI-specific enumeration logic
    }

    fn enumerate_output_devices(&self) -> Result<Vec<AudioDevice>> {
        // WASAPI-specific output enumeration
    }
}

```

When the application compiles, [`mod.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/mod.rs) instantiates the correct platform struct based on the target triple and exposes it through a uniform API. This zero-cost abstraction eliminates runtime overhead while maintaining strict compile-time safety guarantees.

## Integration with the Audio Pipeline

Higher-level components such as [`pipeline.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/pipeline.rs) and [`recording_manager.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/recording_manager.rs) import the unified API from `audio::devices`, maintaining strict separation between device handling and audio processing. This decoupling allows the mixing engine, Voice Activity Detection (VAD), and Whisper transcription modules to focus on sample manipulation while the device layer manages hardware state changes and permission lifecycle.

The architecture ensures that adding support for a new operating system requires only implementing the `AudioPlatform` trait in a new `platform/` file and updating the conditional imports in [`mod.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/mod.rs), without touching the recording logic or transcription pipeline.

## Practical Code Examples

### Listing Available Devices

Accessing hardware information works identically across all platforms:

```rust
use frontend::src_tauri::audio::devices::list_audio_devices;

fn print_devices() {
    match list_audio_devices() {
        Ok(devices) => {
            for d in devices {
                println!("{} ({})", d.name, d.id);
            }
        }
        Err(e) => eprintln!("Failed to enumerate devices: {e}"),
    }
}

```

### Selecting Default Input

The configuration layer provides convenient helpers for common operations:

```rust
use frontend::src_tauri::audio::devices::default_input_device;

let mic = default_input_device()
    .expect("No microphone found");
println!("Using microphone: {}", mic.name);

```

### Platform-Specific Implementation

Each OS module implements the same trait interface, ensuring consistent behavior:

```rust
#[cfg(target_os = "windows")]
impl AudioPlatform for WindowsPlatform {
    fn enumerate_input_devices(&self) -> Result<Vec<AudioDevice>> {
        // WASAPI logic here…
    }

    fn enumerate_output_devices(&self) -> Result<Vec<AudioDevice>> {
        // WASAPI logic here…
    }
}

```

## Summary

- **Meetily's audio device modularization** resides under `frontend/src-tauri/src/audio/devices/` and follows a strict four-layer hierarchy: Device Types, Discovery & Configuration, Platform Implementations, and Public Re-exports.
- The **`AudioPlatform`** trait enforces consistent interfaces across Windows (WASAPI), macOS (ScreenCaptureKit), and Linux (ALSA/PulseAudio) implementations.
- **[`mod.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/mod.rs)** uses compile-time `cfg` attributes to select the correct platform module, exposing a unified API that eliminates conditional logic in consuming code.
- **[`discovery.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/discovery.rs)** and **[`configuration.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/configuration.rs)** handle high-level device enumeration and settings parsing, delegating to OS-specific code only at the lowest level.
- Higher-level modules like [`pipeline.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/pipeline.rs) and [`recording_manager.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/recording_manager.rs) remain platform-agnostic, importing only from the public `audio::devices` interface.

## Frequently Asked Questions

### How does Meetily handle platform-specific audio APIs?

Meetily isolates platform-specific code in dedicated files under [`platform/windows.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/platform/windows.rs), [`platform/macos.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/platform/macos.rs), and [`platform/linux.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/platform/linux.rs). Each file implements the **`AudioPlatform`** trait with OS-specific logic for device enumeration, while the public API in [`mod.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/mod.rs) re-exports only the platform-agnostic interface using Rust's conditional compilation system.

### What is the role of the AudioPlatform trait in Meetily's architecture?

The **`AudioPlatform`** trait defines the contract that all operating system implementations must fulfill, including methods like **`enumerate_input_devices()`** and **`enumerate_output_devices()`**. This ensures that [`discovery.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/discovery.rs) can delegate to any platform implementation without knowing which OS is running, enabling true zero-cost abstraction across different audio backends.

### How can I add support for a new operating system to Meetily's audio layer?

To add a new platform, create a new file in `frontend/src-tauri/src/audio/devices/platform/` (e.g., [`bsd.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/bsd.rs)) that implements the `AudioPlatform` trait. Then update [`mod.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/mod.rs) to conditionally import and instantiate your implementation using `#[cfg(target_os = "bsd")]`. No changes are required to [`discovery.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/discovery.rs), [`pipeline.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/pipeline.rs), or any other consuming code.

### Where does Meetily store audio device configuration settings?

Device configuration parsing and default selection logic reside in **[`configuration.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/configuration.rs)**, which defines the **`AudioDevice`** and **`DeviceControl`** structs. These structures capture device names, IDs, channel layouts, and volume controls in a platform-agnostic format, allowing the rest of the application to reference audio hardware through stable identifiers rather than OS-specific handles.