Echo Cancellation
If your app plays audio and captures the microphone at the same time — a voice assistant, a call, any kind of barge-in — the microphone hears the speaker, and the far end hears itself. Acoustic echo cancellation removes it.
There are two ways to get it, and they can be combined:
- The device's own canceller, configured on the Realtime engine. Costs no CPU, but the implementation belongs to the platform. On iOS this is one switch; on Android it is several settings that have to agree, and results vary by device.
- A software AEC node in your graph, from the Speex or Superpowered extensions. Behaves identically everywhere, at the cost of CPU.
This page covers the device canceller on each platform.
iOS
One key:
{
"type": "Switchboard.Realtime",
"config": {
"microphoneEnabled": true,
"voiceProcessingEnabled": true,
"graph": { }
}
}
This enables Apple's voice processing IO, which applies echo cancellation and automatic gain control to the microphone input. No audio-session setup or permissions beyond microphone access are needed.
It does change the output path, so note the constraints:
- Only mono audio output is supported.
- Various filters are applied to the output signal.
- The user cannot set the volume to zero.
Android
Android has no single switch. Two keys do the work, and the device canceller only engages when both are set:
{
"type": "Switchboard.Realtime",
"config": {
"microphoneEnabled": true,
"inputPreset": "VOICE_COMMUNICATION",
"audioManagerMode": "MODE_IN_COMMUNICATION",
"speakerphoneOn": true,
"graph": { }
}
}
| Key | Why it is needed |
|---|---|
inputPreset: "VOICE_COMMUNICATION" | Asks the capture path for echo cancellation, noise suppression and close-talk gain control |
audioManagerMode: "MODE_IN_COMMUNICATION" | Puts the process in a voice session, which is what arms the canceller on most devices. Some devices engage it from the input preset alone; others do not |
speakerphoneOn: true | Optional. Routes to the loudspeaker rather than the earpiece — there is little echo to cancel on the earpiece, so it matters when testing |
The common failure is setting only one of them. MODE_NORMAL leaves the canceller unarmed no matter
how the input is configured, and inputPreset defaults to GENERIC, which does not request echo
cancellation — so audioManagerMode on its own is not enough either.
outputUsage is not required. Setting it to "USAGE_VOICE_COMMUNICATION" puts playback on in-call
volume and voice routing, which is usually what you want in a voice session, but it is a routing and
volume choice rather than part of enabling the canceller.
Requirements
Add the permission to your application's AndroidManifest.xml:
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
Without it, audioManagerMode silently does nothing. The SDK does not declare it for you.
These keys also need an application context. Switchboard.initialize(context, ...) provides one; if
you initialize from C++ with Switchboard::initialize(...) — a React Native C++ TurboModule, a
Flutter FFI plugin, or a plain NDK app — no Kotlin runs and the SDK never receives one, so hand it
over once:
Switchboard.setApplicationContext(context.applicationContext)
Without a context both keys are ignored and a warning is logged; the engine still starts.
This is best-effort
Android's specification says a device should provide echo cancellation for VOICE_COMMUNICATION
capture — not must. The implementation is the manufacturer's, so results vary by device and OS
version even with identical configuration. Known cases:
- Some devices need
MODE_IN_COMMUNICATIONon top of the input preset; others engage the canceller from the preset alone. VOICE_COMMUNICATIONmay only work in mono on some devices, and can prevent a low-latency stream in stereo.- A handful of devices return silence for
VOICE_COMMUNICATIONcapture entirely, and need a different preset.
If you need echo cancellation that behaves identically everywhere, use the software AEC node instead of, or in addition to, the device canceller.
Reading
- Realtime engine reference — every configuration key and its default
- AEC node — software echo cancellation
Android references for the accepted values:
MediaRecorder.AudioSource—inputPresetAudioManagerMODE_*—audioManagerModeAudioAttributesUSAGE_*—outputUsage- AAudio guide, Setting performance
mode —
performanceMode