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 supportconfigure_linux_audio– Configures ALSA or PulseAudio pipelines depending on system availabilityconfigure_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_devicesfunction indiscovery.rsuses cpal to detect hardware across all platforms. - Platform configurators: Dedicated functions in
platform/*.rshandle Windows, Linux, and macOS-specific setup. - macOS dual-path: The
should_use_enhanced_system_audiohelper selects Core Audio on macOS or falls back to ScreenCaptureKit. - System detection:
MacOSSystemAudioDetectormonitors Core Audio properties with 500 ms debouncing to detect when applications play sound. - Pipeline integration:
EnhancedAudioStreamManagersynchronizes 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →