sys-voice
Cross-platform native voice I/O with OS-level Acoustic Echo Cancellation (AEC).
Current Status
Each platform has been roughly tested but this library is likely to have bugs. Contributions welcome.
Platform Support
| Platform | Backend | AEC Method |
|---|---|---|
| macOS | CoreAudio VoiceProcessingIO | Full hardware AEC |
| iOS | AVAudioEngine voiceChat mode | Full hardware AEC |
| Windows | WASAPI IAcousticEchoCancellationControl | Full hardware AEC |
| Linux | PulseAudio | Depends on module-echo-cancel |
| Android | Oboe VoiceCommunication | Hardware AEC |
Quick Start
use ;
let config = AecConfig ;
let handle = new?;
// Receive samples (async, blocking, or non-blocking)
while let Some = handle.recv_blocking
// Handle automatically stops capture on drop
Testing AEC
Run the included test tool to verify AEC is working on your system:
The test tool:
- Plays a 440Hz tone through your speakers
- Records from the microphone with AEC enabled for 10 seconds
- Saves the recording to
aec_recording.wav
Expected result: The recording should contain your voice but NOT the 440Hz tone. If you hear the tone clearly in the recording, AEC may not be active on your system.
Platform-Specific Notes
macOS
- Requires microphone permission (System Preferences → Security & Privacy → Microphone)
- Uses VoiceProcessingIO audio unit which automatically monitors system output for echo reference
- macOS pauses/ducks other audio (Spotify, Apple Music, etc.) when VoiceProcessingIO is active. This is a system-level behavior that cannot be disabled.
iOS
- Requires
NSMicrophoneUsageDescriptionin Info.plist - Uses AVAudioSession voiceChat mode which enables hardware AEC
- Permission must be granted before stream creation
Windows
- Requires audio device with AEC support
- Uses WASAPI with IAcousticEchoCancellationControl
- Automatically links capture to render device for echo reference
Linux
- Requires PulseAudio daemon running
- For AEC, load
module-echo-cancel:pactl load-module module-echo-cancel - The Simple API cannot pass media.role hints; AEC depends on system configuration
Android
- Requires
RECORD_AUDIOpermission in AndroidManifest.xml - Uses Oboe with VoiceCommunication usage which triggers hardware AEC
- Permission must be granted at runtime before stream creation
iOS Testing
See docs/ios-testing.md for detailed instructions on building and testing on iOS devices and simulators.
Limitations
- Linux: The PulseAudio Simple API cannot pass media.role hints. AEC depends on whether
module-echo-cancelis loaded in the system configuration. - Hardware AEC availability: Some devices may not support hardware AEC. The library will still capture audio, but without echo cancellation.
API Reference
Channels
AecConfig
CaptureHandle
// Capture stops automatically on drop
AecError
License
MIT