# How to Add Support for a New Audio Input Device Platform in Meetily

> Learn how to add support for a new audio input device platform in Meetily by creating a Rust module implementing configuration and discovery logic. Integrate seamlessly.

- Repository: [Zackriya Solutions/meetily](https://github.com/Zackriya-Solutions/meetily)
- Tags: how-to-guide
- Published: 2026-07-31

---

**To add support for a new audio input device platform in Meetily, create a platform-specific Rust module implementing `configure_<platform>_audio` to enumerate devices, register it in [`platform/mod.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/platform/mod.rs) using `#[cfg(target_os = "...")]`, and wire it into [`discovery.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/discovery.rs) to expose devices to the UI.**

Meetily's audio subsystem uses a modular architecture that isolates OS-specific device enumeration logic from the core audio pipeline. This design allows developers to extend support to new operating systems or embedded hardware platforms without modifying the cross-platform audio processing code.

## Understanding the Audio Device Architecture

The audio system splits platform detection into compile-time conditional blocks that route device discovery to the appropriate OS-specific implementation.

### The Discovery Flow

In [`frontend/src-taura/src/audio/devices/discovery.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-taura/src/audio/devices/discovery.rs), the entry point calls a platform-specific configuration function based on the target OS:

```rust
#[cfg(target_os = "windows")] { platform::configure_windows_audio(&host)? }
#[cfg(target_os = "macos")]   { platform::configure_macos_audio(&host)? }
#[cfg(target_os = "linux")]   { platform::configure_linux_audio(&host)? }

```

Each function returns a `Vec<AudioDevice>` that populates the device selection dropdown in the frontend UI.

### Platform Module Contract

Each platform module under `frontend/src-taura/src/audio/devices/platform/` must expose specific public symbols:

- **`configure_<platform>_audio(host: &cpal::Host) -> Result<Vec<AudioDevice>>`** – Enumerates available input devices (microphones) and output devices (system audio monitors).
- **`get_<platform>_device(audio_device: &AudioDevice) -> Result<(cpal::Device, cpal::SupportedStreamConfig)>`** – (Optional, Windows only) Returns a CPAL device with a manually selected stream configuration. Most platforms omit this and use the generic helper in [`configuration.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/configuration.rs).

These modules are re-exported through [`frontend/src-taura/src/audio/devices/platform/mod.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-taura/src/audio/devices/platform/mod.rs) using conditional compilation gates.

## Step-by-Step Implementation Guide

Follow these steps to add support for a new platform (example: `myos`):

### Step 1: Create the Platform Module File

Create [`frontend/src-taura/src/audio/devices/platform/myos.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-taura/src/audio/devices/platform/myos.rs). This file will contain all OS-specific device enumeration logic and platform API integrations.

### Step 2: Implement Device Enumeration

Implement `configure_myos_audio` to return a vector of `AudioDevice` structs. Use the appropriate audio API for your platform (ALSA, CoreAudio, WASAPI, or a custom library):

```rust
use anyhow::Result;
use cpal::traits::{DeviceTrait, HostTrait};
use crate::audio::devices::configuration::{AudioDevice, DeviceType};

pub fn configure_myos_audio(host: &cpal::Host) -> Result<Vec<AudioDevice>> {
    let mut devices = Vec::new();

    // Input devices (microphones)
    for device in host.input_devices()? {
        if let Ok(name) = device.name() {
            devices.push(AudioDevice::new(name, DeviceType::Input));
        }
    }

    // Output devices (system audio monitors)
    for device in host.output_devices()? {
        if let Ok(name) = device.name() {
            if name.contains("monitor") {
                devices.push(AudioDevice::new(
                    format!("{} (System Audio)", name),
                    DeviceType::Output,
                ));
            }
        }
    }

    Ok(devices)
}

```

### Step 3: Handle Special Configuration Cases (Optional)

If your platform requires special handling to obtain a `SupportedStreamConfig` (as Windows does), implement `get_myos_device`. Most platforms can omit this and rely on the generic lookup in [`configuration.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/configuration.rs):

```rust
pub fn get_myos_device(audio_device: &AudioDevice) -> Result<(cpal::Device, cpal::SupportedStreamConfig)> {
    super::super::configuration::get_device_and_config(audio_device)
}

```

### Step 4: Register the Module

Add conditional compilation entries to [`frontend/src-taura/src/audio/devices/platform/mod.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-taura/src/audio/devices/platform/mod.rs):

```rust
#[cfg(target_os = "myos")]
pub mod myos;

#[cfg(target_os = "myos")]
pub use myos::{configure_myos_audio, get_myos_device};

```

### Step 5: Wire Into the Discovery Layer

Add a new conditional block in [`frontend/src-taura/src/audio/devices/discovery.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-taura/src/audio/devices/discovery.rs) to invoke your platform function:

```rust
#[cfg(target_os = "myos")]
{
    platform::configure_myos_audio(&host)?
}

```

### Step 6: Configure Cargo and Build Targets

If the new OS requires a specific Rust target triple or additional system libraries, update [`frontend/src-taura/Cargo.toml`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-taura/Cargo.toml) with the necessary dependencies and features. Ensure your CI pipeline includes build steps for the new target architecture.

### Step 7: Test the Integration

Run the Tauri application on the target platform and verify that `list_audio_devices()` returns the expected microphones and system audio sources, and that recording and transcription function correctly end-to-end.

## Key Implementation Files

- **[`frontend/src-taura/src/audio/devices/discovery.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-taura/src/audio/devices/discovery.rs)** – Central dispatcher that calls platform-specific enumeration functions based on compile-time OS detection.
- **[`frontend/src-taura/src/audio/devices/platform/mod.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-taura/src/audio/devices/platform/mod.rs)** – Re-exports platform modules using `#[cfg(target_os = "...")]` gates to ensure only relevant code is compiled.
- **[`frontend/src-taura/src/audio/devices/platform/windows.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-taura/src/audio/devices/platform/windows.rs)** – Reference implementation showing complex device enumeration and manual stream configuration selection.
- **[`frontend/src-taura/src/audio/devices/configuration.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-taura/src/audio/devices/configuration.rs)** – Defines the shared `AudioDevice` struct and `DeviceType` enum used across all platforms, plus the generic `get_device_and_config` fallback.

## Summary

- **Platform isolation** – Meetily separates OS-specific code into dedicated modules under `frontend/src-taura/src/audio/devices/platform/`.
- **Standardized interface** – Implement `configure_<platform>_audio` to return `Vec<AudioDevice>` structs that the UI consumes without platform-specific logic.
- **Compile-time selection** – Use `#[cfg(target_os = "...")]` in [`platform/mod.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/platform/mod.rs) and [`discovery.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/discovery.rs) to include only the relevant platform implementation.
- **Optional configuration helper** – Only implement `get_<platform>_device` if your OS requires special stream configuration negotiation; otherwise rely on [`configuration.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/configuration.rs).
- **Shared data model** – All platforms use the `AudioDevice` and `DeviceType` definitions from [`configuration.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/configuration.rs), ensuring the frontend receives consistent data structures.

## Frequently Asked Questions

### Do I need to modify the frontend TypeScript code when adding a new platform?

No. The frontend invokes the Tauri command `list_audio_devices`, which returns a platform-agnostic `Vec<AudioDevice>` from the Rust backend. As long as your platform module returns properly formatted `AudioDevice` structs with `name` and `device_type` fields, the React frontend will display them without modification.

### What is the difference between Input and Output device types?

**Input** devices (`DeviceType::Input`) represent physical microphones or audio capture endpoints. **Output** devices (`DeviceType::Output`) represent system audio monitor sources (such as "Monitor of Built-in Audio" on Linux) that allow capturing the computer's internal audio output. The Linux implementation in [`linux.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/linux.rs) demonstrates detecting monitor sources by filtering device names for the substring "monitor".

### Can I use platform-specific audio APIs instead of CPAL?

Yes. While existing implementations use CPAL (Cross-Platform Audio Library) for consistency, you can replace CPAL-based enumeration with direct OS API calls (such as raw ALSA on Linux or AudioObject on macOS) as long as you construct `AudioDevice` structs compatible with the shared model defined in [`configuration.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/configuration.rs).

### Why does Windows require a separate `get_windows_device` function?

Windows audio drivers often expose multiple stream configurations with varying sample rates and buffer sizes that CPAL cannot automatically negotiate for the transcription pipeline. The `get_windows_device` function in [`windows.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/windows.rs) manually selects a compatible `SupportedStreamConfig` before passing the device to the audio pipeline. Most other platforms work correctly with CPAL's default device selection, allowing them to use the generic fallback.