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

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, 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, speakers.rs, and 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 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 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:

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 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:

// 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 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 and 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, without touching the recording logic or transcription pipeline.

Practical Code Examples

Listing Available Devices

Accessing hardware information works identically across all platforms:

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:

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:

#[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 uses compile-time cfg attributes to select the correct platform module, exposing a unified API that eliminates conditional logic in consuming code.
  • discovery.rs and 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 and 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, platform/macos.rs, and platform/linux.rs. Each file implements the AudioPlatform trait with OS-specific logic for device enumeration, while the public API in 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 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) that implements the AudioPlatform trait. Then update mod.rs to conditionally import and instantiate your implementation using #[cfg(target_os = "bsd")]. No changes are required to discovery.rs, 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, 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →