How Meetily Performs Audio Backend Selection and Configuration

Meetily automatically selects the optimal audio backend by detecting the host operating system and choosing between Core Audio or ScreenCaptureKit on macOS while configuring platform-specific pipelines for Windows and Linux.

In the Zackriya-Solutions/meetily repository, audio backend selection and configuration are handled through a layered architecture that prioritizes platform-native capabilities. The system combines automatic device enumeration with OS-specific configurators to ensure reliable microphone and system-audio capture across macOS, Windows, and Linux.

Automatic Audio Backend Selection Across Platforms

The audio subsystem begins by discovering available hardware through the cross-platform cpal crate, then delegates configuration to platform-specific implementations based on the compilation target.

Device Enumeration with cpal

The entry point for audio backend selection resides in frontend/src-tauri/src/audio/devices/discovery.rs. The list_audio_devices async function enumerates all available audio endpoints using cpal's host abstraction, returning a structured list of input and output devices.

// Enumerate all platform audio devices
let devices = audio::devices::discovery::list_audio_devices().await?;
println!("Available devices: {:?}", devices);

After enumeration, the code constructs a platform-specific configurator that filters and sets up devices according to OS capabilities.

Platform-Specific Configuration Functions

Based on the target triple, the discovery module dispatches to specialized configurators in the frontend/src-tauri/src/audio/devices/platform/ directory:

  • configure_windows_audio – Sets up WASAPI or DirectSound backends with default loopback capture support
  • configure_linux_audio – Configures ALSA or PulseAudio pipelines depending on system availability
  • configure_macos_audio – Prepares both microphone access and system audio routing through Core Audio

Each configurator returns a normalized device list that the higher-level audio managers consume uniformly, abstracting platform differences from the recording pipeline.

macOS Audio Backend Configuration and Detection

On macOS, Meetily implements a sophisticated dual-path system that selects between an enhanced Core Audio implementation and a legacy ScreenCaptureKit fallback.

Enhanced vs. Legacy Path Selection

The decision logic lives in frontend/src-tauri/src/audio/system_audio_stream.rs within the helper function should_use_enhanced_system_audio. This function returns true unconditionally on macOS, triggering the Core Audio path, while returning false on other platforms to force fallback behavior.

// Initialize the enhanced manager (automatically selects Core Audio on macOS)
let mut manager = audio::system_audio_stream::EnhancedAudioStreamManager::new(state);
manager
    .start_streams(
        Some(mic_device),      // optional microphone input
        Some(system_device),   // optional system-audio device
        Some(recording_sender),
    )
    .await?;

When the enhanced path is active, the EnhancedAudioStreamManager creates a SystemAudioStreamManager that manages both microphone and system streams simultaneously.

Core Audio System Detection

For system-audio monitoring on macOS, Meetily employs the MacOSSystemAudioDetector defined in frontend/src-tauri/src/audio/system_detector.rs. This detector registers Core Audio property listeners for the DEVICE_IS_RUNNING_SOMEWHERE property on the default output device, receiving callbacks whenever any application begins or stops playing audio.

The implementation debounces rapid state changes with a 500 ms timeout to prevent flickering during short audio events. When activity is detected, the detector invokes a user-provided callback with either SystemAudioStarted(apps)—containing a list of process names currently producing audio—or SystemAudioStopped.

// Subscribe to system-audio activity changes (macOS only)
let mut sys_detector = audio::system_detector::SystemAudioDetector::new();
sys_detector.start(Box::new(|event| {
    match event {
        SystemAudioEvent::SystemAudioStarted(apps) => {
            println!("System audio detected from: {:?}", apps);
        }
        SystemAudioEvent::SystemAudioStopped => {
            println!("System audio stopped");
        }
    }
}));

Integrating Audio Streams with the Recording Pipeline

Once the backend is selected and configured, the system must synchronize multiple audio sources into a unified stream for transcription.

SystemAudioStreamManager Implementation

The SystemAudioStreamManager::create method in audio/system_audio_stream.rs constructs a SystemAudioCapture instance, starts the underlying Core Audio stream, and wraps it in an AudioCapture object. This wrapper feeds raw audio samples into the centralized mixing pipeline defined in frontend/src-tauri/src/audio/pipeline.rs.

Buffering and Synchronization

To maintain synchronization between microphone and system-audio streams, the manager spawns an async task that buffers incoming samples using a 1024-frame ring buffer. Once the buffer reaches the threshold, the task hands the chunk to AudioCapture::process_audio_data, ensuring both streams align temporally for voice activity detection (VAD) and mixing.

This architecture decouples the platform-specific capture logic from the application-level audio processing, allowing the pipeline to operate identically regardless of whether the source originated from Core Audio, WASAPI, or ALSA.

Summary

  • Automatic enumeration: The list_audio_devices function in discovery.rs uses cpal to detect hardware across all platforms.
  • Platform configurators: Dedicated functions in platform/*.rs handle Windows, Linux, and macOS-specific setup.
  • macOS dual-path: The should_use_enhanced_system_audio helper selects Core Audio on macOS or falls back to ScreenCaptureKit.
  • System detection: MacOSSystemAudioDetector monitors Core Audio properties with 500 ms debouncing to detect when applications play sound.
  • Pipeline integration: EnhancedAudioStreamManager synchronizes microphone and system audio using 1024-frame buffers before passing data to the mixing pipeline.

Frequently Asked Questions

How does Meetily choose between Core Audio and ScreenCaptureKit on macOS?

According to the source code in audio/system_audio_stream.rs, the boolean function should_use_enhanced_system_audio determines the path. On macOS, it always returns true, causing the EnhancedAudioStreamManager to instantiate a SystemAudioStreamManager that uses Core Audio directly. On non-macOS platforms, it returns false, triggering fallback to the legacy AudioStream::create implementation that relies on ScreenCaptureKit for system audio capture.

What is the role of the MacOSSystemAudioDetector?

The MacOSSystemAudioDetector in audio/system_detector.rs provides real-time monitoring of system audio activity on macOS. It registers Core Audio property listeners for the DEVICE_IS_RUNNING_SOMEWHERE property on the default output device and debounces state changes for 500 milliseconds. This allows Meetily to detect precisely when applications start or stop producing audio, enabling automatic recording triggers based on system sound activity.

How does Meetily handle audio device enumeration on Linux and Windows?

On Linux and Windows, the list_audio_devices function delegates to configure_linux_audio or configure_windows_audio respectively, located in audio/devices/platform/*.rs. These functions use cpal's host-specific backends to enumerate ALSA/PulseAudio devices on Linux and WASAPI/DirectSound devices on Windows. The configurators normalize device capabilities and names into a cross-platform format before returning them to the discovery layer.

Where is the audio mixing pipeline implemented in Meetily?

The central mixing and voice activity detection pipeline is implemented in frontend/src-tauri/src/audio/pipeline.rs. This module receives audio chunks from both microphone and system-audio streams through the AudioCapture::process_audio_data method. The pipeline handles synchronization, mixing multiple sources, and preparing the final audio buffer for transcription services, operating independently of the platform-specific capture backends.

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 →