How to Add Support for a New Audio Device Platform in Meetily: Complete Guide
You can add support for a new audio device platform in Meetily by creating a platform-specific module under frontend/src-tauri/src/audio/devices/platform/ that implements the standardized device enumeration interface and registering it via conditional compilation in the platform mod.rs file.
Meetily's audio subsystem uses a modular architecture that isolates platform-specific code from the core application logic. To extend support to additional operating systems like FreeBSD or Solaris, developers implement a standardized enumeration interface that integrates seamlessly with the existing device discovery pipeline. This guide provides the exact file paths, function signatures, and implementation patterns required to add a new audio device platform to the Zackriya-Solutions/meetily repository.
Architecture Overview
Meetily deliberately splits its audio subsystem into platform-specific modules located in frontend/src-tauri/src/audio/devices/platform/. This separation ensures that the core recording and transcription logic remains agnostic of the underlying operating system.
Each platform module exposes a primary enumeration function that returns a vector of AudioDevice structs. The core device discovery logic in discovery.rs calls the appropriate platform-specific function based on the compile-time target. The AudioDevice struct, defined in configuration.rs, standardizes device metadata across all platforms.
Step-by-Step Implementation Guide
1. Create the Platform Module
Create a new Rust file in the platform directory using your target OS name:
frontend/src-tauri/src/audio/devices/platform/freebsd.rs
This file must expose a public function with the exact signature pattern used by existing platforms. For FreeBSD, this would be configure_freebsd_audio.
2. Implement Device Enumeration
Implement the primary enumeration function that returns anyhow::Result<Vec<AudioDevice>>. The function accepts a cpal::Host reference and populates a vector with available input and output devices.
use anyhow::Result;
use cpal::traits::{DeviceTrait, HostTrait};
use crate::audio::devices::configuration::{AudioDevice, DeviceType};
pub fn configure_freebsd_audio(host: &cpal::Host) -> Result<Vec<AudioDevice>> {
let mut devices = Vec::new();
// Enumerate input devices
for dev in host.input_devices()? {
if let Ok(name) = dev.name() {
devices.push(AudioDevice::new(name, DeviceType::Input));
}
}
// Enumerate output devices (system audio)
for dev in host.output_devices()? {
if let Ok(name) = dev.name() {
if name.contains("monitor") {
devices.push(AudioDevice::new(name, DeviceType::Output));
}
}
}
Ok(devices)
}
The function must handle both microphone inputs (DeviceType::Input) and system audio outputs (DeviceType::Output).
3. Add the Device Resolution Helper (Optional)
If your platform requires special handling to obtain stream configurations—similar to Windows' implementation—expose a secondary helper function:
pub fn get_freebsd_device(
audio_device: &AudioDevice,
) -> Result<(cpal::Device, cpal::SupportedStreamConfig)> {
let host = cpal::default_host();
match audio_device.device_type {
DeviceType::Input => {
for dev in host.input_devices()? {
if let Ok(name) = dev.name() {
if name == audio_device.name {
let config = dev.default_input_config()?;
return Ok((dev, config));
}
}
}
}
DeviceType::Output => {
for dev in host.output_devices()? {
if let Ok(name) = dev.name() {
if name == audio_device.name {
let config = dev.default_output_config()?;
return Ok((dev, config));
}
}
}
}
}
Err(anyhow::anyhow!("Device not found: {}", audio_device.name))
}
Prefer f32 sample format with 2-channel stereo configuration when selecting from supported configs.
4. Register the Platform Module
Edit frontend/src-tauri/src/audio/devices/platform/mod.rs to conditionally compile and re-export your new module:
#[cfg(target_os = "freebsd")]
pub mod freebsd;
#[cfg(target_os = "freebsd")]
pub use freebsd::{configure_freebsd_audio, get_freebsd_device};
This pattern mirrors the existing blocks for Windows, macOS, and Linux.
5. Integrate with Device Discovery
Ensure the generic device discovery code in frontend/src-tauri/src/audio/devices/discovery.rs can invoke your new function. The discovery logic typically calls the platform-specific configure_*_audio function based on the active target. Update any match statements or generic aliases to include your new platform.
6. Update Cargo.toml
Add any platform-specific dependencies to frontend/src-tauri/Cargo.toml using target-specific guards:
[target.'cfg(target_os = "freebsd")'.dependencies]
freebsd-audio-sys = "0.1"
7. Test and Document
Add unit tests that verify your enumeration function returns at least one AudioDevice when hardware is present. Use #[cfg(target_os = "freebsd")] to gate platform-specific tests.
Update the project README or audio architecture documentation to list the new supported platform and any special requirements, such as permissions or virtual device naming conventions.
Reference Implementations
Study these existing platform modules to understand implementation variations:
-
frontend/src-tauri/src/audio/devices/platform/windows.rs– Demonstrates a fully-featured implementation with theget_windows_devicehelper for stream configuration resolution. -
frontend/src-tauri/src/audio/devices/platform/macos.rs– Shows a minimal implementation without extra resolution helpers, relying on CPAL defaults. -
frontend/src-tauri/src/audio/devices/platform/linux.rs– Illustrates handling of PulseAudio monitor sources for system audio capture. -
frontend/src-tauri/src/audio/devices/platform/mod.rs– Central registry for all platform modules. -
frontend/src-tauri/src/audio/devices/configuration.rs– Defines theAudioDevicestruct used by all platforms. -
frontend/src-tauri/src/audio/devices/discovery.rs– Orchestrates device discovery by calling the appropriate platform function.
Summary
- Create a new file in
frontend/src-tauri/src/audio/devices/platform/named after your target OS. - Implement
configure_*_audio(host: &cpal::Host) -> Result<Vec<AudioDevice>>to enumerate devices using CPAL traits. - Optionally implement
get_*_deviceif your platform needs custom stream configuration resolution. - Register the module in
mod.rsusing#[cfg(target_os = "your_os")]attributes. - Wire the function into
discovery.rsto enable the discovery flow. - Update
Cargo.tomlwith any target-specific dependencies. - Test with
#[cfg(target_os = "your_os")]gated unit tests to verify enumeration.
Frequently Asked Questions
What function signature must my platform module expose?
Your primary function must follow the pattern configure_[platform]_audio(host: &cpal::Host) -> anyhow::Result<Vec<AudioDevice>>. It accepts a CPAL host reference and returns a result containing a vector of AudioDevice structs. This signature ensures compatibility with the discovery logic in discovery.rs.
Do I need to modify the core audio recording logic?
No. Meetily's architecture isolates platform-specific code in the audio/devices/platform/ directory. By implementing the standardized enumeration interface, you extend support without touching the higher-level pipeline, recorder, or transcription modules.
How does Meetily handle platform-specific audio formats?
The optional get_*_device helper function allows platforms to specify exact stream configurations. When implemented, it returns a tuple of (cpal::Device, cpal::SupportedStreamConfig). The implementation should prefer f32 sample format with 2-channel stereo when available, falling back to the device's default configuration otherwise.
Can I add support for embedded or custom audio hardware?
Yes. As long as you can access the hardware through CPAL or a custom backend that integrates with Rust's audio ecosystem, you can implement the enumeration logic. For specialized hardware not supported by CPAL, you would replace the CPAL host calls with your custom enumeration logic while still returning standard AudioDevice structs to maintain compatibility with the rest of the system.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →