> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Troubleshooting: video echo and codec mismatch — distorted, delayed, and looping audio in rooms

> Diagnose echo and codec-mismatch distortion on video calls — acoustic echo, broken device DSP, capture-pipeline fight, and relay-path asymmetry — with client-side echo cancellation and media-policy fixes, not MOS.

# Troubleshooting: video echo and codec mismatch — distorted, delayed, and looping audio in rooms

The room connects, video and audio both flow, and then one or both parties
report audio that is wrong in a way packet metrics cannot see: your own
voice returned a beat after you speak (echo), a hollow or robotic warble
with a clean network (codec mismatch), or a delayed, listening-over-your-
own-shoulder loop on one specific endpoint. These are non-loss distortions:
jitter, loss, and the voice-side MOS score can all be clean while the call
is unusable, because each one is scored per leg and says nothing about an
echo round trip. This page works that class for video rooms; the MOS/
jitter/loss classes live in
[Troubleshooting: video room and call quality](/troubleshooting/video-call-quality).

## Cause index

Echo and codec distortion have a small set of causes. Identify which end
hears the distortion, then start at the matching row.

| Cause                                                                                                                                                                                                      | What it sounds like                                                                         | Fix section                                                                 |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
| No acoustic echo cancellation at the far end — the loudspeaker plays the room back into the far end's own microphone                                                                                       | You hear your own voice returned a moment after you speak; the far end hears you fine       | [Acoustic echo](#acoustic-echo)                                             |
| A Bluetooth or USB audio device with a broken DSP pairing — the device advertises an echo-cancellation processor that does not run, or its capture path bypasses the browser's software AEC                | Echo that follows one specific headset or speakerphone, and disappears with a wired headset | [Acoustic echo](#acoustic-echo)                                             |
| Headset profile mismatch across operating systems — the same USB headset enumerates a different capture profile on Windows vs macOS, and only one profile engages the hardware AEC                         | Echo from participants on one OS only                                                       | [Acoustic echo](#acoustic-echo)                                             |
| Capture-processing fight — echo cancellation disabled in the client while the platform media policy or the OS-level driver applies its own, or two processors (browser AEC + OS AEC) clamp the same stream | Robotic, hollow, or underwater warble that packet metrics cannot explain                    | [Codec and capture-pipeline mismatch](#codec-and-capture-pipeline-mismatch) |
| System-level microphone gain re-clipping pre-processed audio — the OS boost applies after processing, wrecking the encoder's input headroom                                                                | Overdriven, clipping distortion on one participant only                                     | [Codec and capture-pipeline mismatch](#codec-and-capture-pipeline-mismatch) |
| Asymmetric relay path — TURN round-trip variance presents to the listener as a delayed echo or one-way loop rather than as loss                                                                            | A loop or delayed return that only appears when the session relays                          | [Relay-path checks](#relay-path-checks)                                     |

## Confirm before you fix

Work the checks in order; change one variable per test call.

1. **Read the receiver's network telemetry first.** A distortion that only
   rides a degraded network path belongs on
   [Troubleshooting: video room and call quality](/troubleshooting/video-call-quality),
   not here. Pull the participant's live sample from
   `GET /api/v1/video/connection-quality/:name/participants/:identity/stats`
   — `quality_label`, `rtt_ms`, and `jitter_ms` — or the
   `video.participant.qos` webhook. Clean samples with audible distortion
   confirm a capture-side problem and put you on this page.
2. **Isolate the endpoint.** Echo is endothermic: the fix lives on the end
   that *originates* the return, which is almost never the end that reports
   it. Have the far end switch to a wired headset for one test call. If the
   echo dies with the headset swap, the cause is that endpoint's speaker or
   DSP pairing — not the room, not the SFU.
3. **Read the capture flags.** If you embed with your own client, confirm
   what capture constraints were actually negotiated: `getStats()` on the
   publisher's peer connection exposes the echo-cancellation and
   echo-return-loss metrics the browser computed, and the room's media
   policy (`media_policy.noise_suppression` on the room settings) tells you
   whether the platform asked the publisher to run a capture processor. If
   you use the prebuilt `<orbit-video-room>` element, the audio-processing
   toggles (echo cancellation, noise suppression, auto gain control) are
   user-visible and persist per user — check the affected participant's
   toggle state before changing anything else.

## Acoustic echo

Echo is a client-side problem the SFU faithfully relays: the far end's loud
speaker feeds the far end's microphone, and the round trip returns to you.
No platform-side change removes it; the knobs that do are tenant-owned.

* **Enable echo cancellation on the publishing client.** Echo cancellation
  is a publish option on the media capture layer Orbit video rooms run on.
  The prebuilt embed defaults it on through the audio-processing toggles; a
  custom client must set it in its capture defaults (the same option the
  softphone's audio preferences persist per user). A participant who joined
  with echo cancellation off is the single most common echo source.
* **Prefer a wired headset when one is present.** Any sealed acoustic path
  (headset, handset) kills the speaker-to-microphone loop outright. When
  echo follows a Bluetooth or USB speakerphone and vanishes with the wired
  swap, the device's DSP pairing is the fault, not the room.
* **Do not double-process.** If a room-level media policy already requires
  a capture-side audio processor, do not also stack an OS-level or
  driver-level echo canceller on top — two AECs fighting each other
  produces the warble class described below. Suppress the duplicate at the
  endpoint, keep exactly one.
* **Mixer rooms.** When the room mixes audio for a broadcast or a SIP
  dial-in leg, an endpoint that negotiated no echo cancellation feeds its
  return into every listener. The per-participant fix above still applies —
  the mixer cannot cancel what the publisher never processed.

## Codec and capture-pipeline mismatch

Distortion without echo is usually a capture-pipeline fight: the audio was
processed wrong, or processed twice, before it was ever encoded.

* **One processor only.** Pick which layer owns echo cancellation — the
  client capture defaults, the room media policy, or the OS driver — and
  disable the others. Browser AEC plus OS AEC on the same stream is the
  classic hollow/robotic signature.
* **Check microphone gain.** An OS-level mic boost applies after any
  capture-time processing and re-clips the signal back into distortion.
  Returns the system capture gain off the hardware ceiling and let the
  client's auto gain control, when it is enabled, hold the level.
* **Verify the negotiated codec family.** Video rooms negotiate a video
  codec (the H.264/H.265 family) for the picture and an audio codec for
  voice; an endpoint that accepts a profile it cannot actually render
  produces distortion that no retry fixes. On a SIP dial-in or dial-out leg
  the mismatch surfaces as a failed or audio-only negotiation — work that
  leg with [Troubleshooting: video room and call quality](/troubleshooting/video-call-quality),
  which covers the SIP dial-out codec profile.

## Relay-path checks

When the session relays through TURN, round-trip variance can present to
the listener as a delayed echo rather than as loss. Confirm the path
before treating the endpoint as the culprit: the same
`connection-quality` stats sample carries `rtt_ms` — a relay whose RTT
swings while jitter stays low is an echo-shaped network problem, and the
fix is the direct path the video-quality page's firewall section works
(SIP ALG off, the TCP/TLS fallback reachable), not an endpoint toggle.

## What not to do

* **Do not rejoin or recreate the room.** Echo and capture-processing
  faults live at the endpoint; a new WebRTC session or a new room id lands
  the same device on the same path with the same distortion.
* **Do not drop or rebuild the SIP trunk.** For an in-room echo complaint
  the trunk is uninvolved unless the distortion arrives specifically over
  a dial-in/dial-out PSTN leg — and then it is a codec or far-end-device
  issue on that leg, not a trunk-health issue.
* **Do not debug the MOS score.** Per-leg MOS does not observe an echo
  round trip; a call can carry audible echo at a clean MOS. Diagnose from
  the endpoint and capture flags above.

## What to send support

Work the sections above first; if the distortion persists on a wired
headset with exactly one capture processor enabled, open a ticket with:

1. **Room id** and **session id** (off the room or any `video.*` webhook),
   plus the **broken window in UTC**.
2. **The affected participant identities** — which end hears the
   distortion, and which end was on speaker.
3. **The endpoint details** for the echo-source participant: device type
   (speakerphone / Bluetooth / USB headset / wired), OS, and whether the
   audio-processing toggles were on.
4. **The receiver-side `getStats()` capture** if you run a custom client:
   the audio codec negotiated and the echo-cancellation / echo-return-loss
   metrics from the publisher's peer connection.
5. **Whether a SIP dial-in/dial-out leg is bridged**, and if so its
   negotiated audio and video profiles.

## See also

* [Troubleshooting: video room and call quality](/troubleshooting/video-call-quality)
  — the MOS/jitter/loss and throughput classes: frozen video, buffer
  stalls, the recording QC verdict, and SIP dial-out failures. Non-MOS
  distortions live on this page.
* [Troubleshooting: video room lifecycle](/troubleshooting/video-room-lifecycle)
  — when the room never connects at all: join-token refusals, capacity
  400s, and lobby gating.
* [Troubleshooting: voice call quality](/troubleshooting/voice-call-quality)
  — the PSTN/SIP counterpart: echo on a phone participant bridging into
  the room is diagnosed there.
* [Video channel: rooms, embeds, recording, and broadcast](/channels/video)
  — room kinds, media policies, and the embed contract.
* [Webhook events reference](/reference/webhook-events) — the
  `video.participant.qos` payload this page reads.
