Skip to content

One guest's (Jamal) audio is distorted and low quality in CoreVideo; the meeting audio is clean #465

Description

@iamfatness

Owner observation, live, 2026-09-10 (build e26a0e9, test meeting): "Audio from Jamal is very distorted and low quality. Meeting audio doesn't have any artifacts."

Evidence captured a minute later (/snapshot, audioMixSession):

  • Per-guest channels carry PCM. In a 10 s sample, guests 16783360 and 16789504 showed real levels, so the per-guest (ISO) audio path is live, not just the Zoom program mix.
  • Every guest strip has gainDb: +6 and noiseSuppression: true. The summary reads "9 boosted". The only limiter is on master.
  • Jamal (userId 16778240) was not talking during the sample, so his channel read silent (−120 dBFS). Earlier, Zoom reported him talking at audioLevel 78, which makes him one of the louder voices.
  • Monitor: monitorUnderruns: 2 over about 154 s of monitor play. Status was "muted" at capture time.

Why this points at our per-guest path: the meeting mix is clean, but one guest's stem isn't. A loud source on a +6 dB strip, or our noise suppression on that stem, would affect one voice and leave the meeting mix alone.

Hypotheses, cheapest to check first:

  1. Clipping on the strip. The +6 dB boost plus a hot talker can clip before the master limiter. Check Jamal's strip peakDbfs while he talks.
  2. Our noise suppression degrading one voice. Toggle it off on his strip and A/B.
  3. The stem itself. Zoom's isolated stem for that user may be low bitrate or mono (the up-mix path). Record an ISO of him and inspect the raw stem: spectrum and clipping.
  4. Resampling or ring underruns on that one participant's SHM ring (per-slot drops).

Still unknown: where the owner heard it (their monitor, Program/recording, or the strip solo). That decides which hypothesis comes first.

Activity

  1. iamfatness commented on Sep 11, 2026

    @iamfatness
    OwnerAuthor

    New evidence (2026-09-11), in the test meeting on the combined #478+#481 build, and also on yesterday's installed 5a24225.

    Jamal (userId 16778240, the first participant in the roster) shows talking: true, Zoom audioLevel 78. His audio subscription participant-audio-16778240-mix is subscribed: true, and his channel is unmuted. Yet his channel gets no PCM at all: inputRmsDbfs and rmsDbfs both −120 across 12 consecutive seconds of him talking. Every other guest's channel lights up when they talk (Susan −25.8, Anika −40.2). This predates today's fixes: the same pattern was sampled on 2026-09-10 on installed 5a24225.

    The one thing that sets him apart: the meeting-mix subscription is keyed to participants[0], and that is him (meeting-audio-16778240-program).

    Ruled out by reading the code, so not the cause:

    • Core dedup: keyed by the full sourceUuid, with audio at key −1.
    • Engine targets: m_targets is keyed by sourceUuid. The isolate target is matched on participant_id == user_id in onOneWayAudioRawDataReceived.
    • SHM rings: named <prefix><sourceUuid>_audio.
    • Core pending keys: ISO → participantId, mix → "zoom-mix".

    So the collision theory is not confirmed.

    Next diagnostic: the answer is in the engine's debug events (audio_target_added, audio_one_way_frame_received per source_uuid), which production logging drops. Run once with Extra logs on, or let debug audio stage lines through, and compare Jamal's uuid with a working guest's. Also test by moving meeting-audio onto a participant who is NOT a guest source (or a synthetic id), and see whether Jamal's ISO comes alive.

    The owner's report ("distorted and low quality") may be what the program mix sounds like while his isolated stream is missing: he would then be heard only through zoom-mix, if that is routed.

  2. iamfatness commented on Sep 11, 2026

    @iamfatness
    OwnerAuthor

    Diagnostic run 2026-09-11, installed beta-2026-09-11-404602b, test meeting 8916561023, Extra logs on for ~90 s then off. Control API only (no keyboard/mouse).

    Setup. Joined as CoreVideo Producer (16794624). Engine was off after join (sourceCount=0); transport.engine.set true then produced 18 subscriptions (8 video + 10 audio, including isolate for every source and meeting-audio-16778240-program).

    Roster[0] is still Jamal (16778240). Meeting mix is keyed to him: ZoomMediaSpinePayloadBuilder sets meeting-audio participantId = participants[0].sdkUserId.

    Engine debug (the missing evidence). When Jamal talks (talking: true, Zoom audioLevel 78):

    • Isolate is subscribed: participant-audio-16778240-mix subscribed: true
    • Engine does fire one-way frames: audio_one_way_frame_received source_uuid=participant-audio-16778240-mix count 1 → 250 → 1250, byte_len=960, participant_id=16778240
    • Core logs the first drain: [zoom-audio] stream participant-audio-16778240-mix chunk #1 rate=48000 ch=1 pending=480
    • Mixer strip stays digital silence: inputRmsDbfs=-120 rmsDbfs=-120 status=silent (not waiting-for-pcm). noiseSuppression is on his strip; input is already −120, so NS is not the gate.

    Control (Susan Cho 16789504 talking, audioLevel 78): same isolate path, mixer inputRmsDbfs=-37 peak=-26.8 status=cleaning.

    What this rules out. The earlier collision guess (core dedup / SHM name / m_targets keyed by uuid) is not the break: the isolate uuid is distinct, the engine writes one-way frames onto it, and the core opens that ring. Meeting mix continues on meeting-audio-16778240-program via audio_frame_received (mixed callback), ingested as zoom-mix. There is no zoom-mix strip in this session's mixer (perGuestIso leaves it unrouted).

    What is still true. Isolate PCM that lands on Jamal's ring measures as silence while Zoom says he is talking. Other talkers' isolate rings have real speech. The only thing that uniquely identifies him is that he is participants[0] and therefore the meeting-mix subscribe identity.

    Next, one-line experiment (then the fix): key meeting-audio at a synthetic id that is not a guest (0 / mix), so Zoom's mixed subscribe is not bound to Jamal. If his isolate then shows levels when he talks, the SDK is suppressing one-way for the mix-anchor user (or delivering zeros). That is the change to ship.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions