Files
qortal-go-2.0/docs/gcall-receive-profiles.md

12 KiB
Raw Permalink Blame History

GCall Receive Profiles

This document is the working reference for the live receive-policy profiles used by the group-call audio engine.

Primary code:

Primary runtime diagnostics:

  • audioSurfaceRuntimeDiagnostics.receiveEngine.livePolicyProfilesBySource
  • recentWindowTrends
  • events[].tag == "call-quality-worsened"

This file is meant to answer:

  • What profile did a bad call fall into?
  • Why did that profile activate?
  • What should we tune next if that profile still sounds bad?

How To Use This Doc

For a new export:

  • Check livePolicyProfilesBySource for each source.
  • Check exportWindowMetrics and recentWindowTrends for the matching side.
  • Match the observed metrics to the profile description below.
  • Tune that profile first before touching unrelated ones.

Do not create a new profile unless:

  • the failure shape is recurring,
  • it is materially different from the existing profiles,
  • and forcing it into an existing profile would likely harm other call shapes.

Shared Signals

The receive engine derives profile selection from live playout metrics such as:

  • avgPcmBufferedMs
  • jitterBufferDepthFramesMean
  • jitterNotReadyFraction
  • avgPlayoutDeltaMs
  • playoutUnderTargetFraction
  • playoutRateFractionBelow097
  • missingFrames
  • concealmentTicks
  • avgReticulumAudioBridgeToRendererIngressMs
  • oldestFrameAgeMs

Internal smoothed state includes:

  • buffered reserve EMA
  • playout delta EMA
  • under-target EMA
  • concealment EMA
  • playout-rate EMA
  • oldest-frame-age EMA
  • pre-process buffered frames
  • hold timers for stronger protection modes

Profiles

The receive engine exports one profile per active source. One-remote calls use the single-source profiles below. Multi-source calls use the multi-* profiles so 3+ diagnostics no longer appear as clean-low-latency while multi-source recovery controls are active.

clean-low-latency

What it means:

  • Listener looks healthy enough to stay in the normal low-latency path.

Typical signals:

  • decent reserve
  • no meaningful under-target pressure
  • no meaningful concealment pressure
  • no strong rate-chasing
  • no lean/prebuffer warning state

User symptom:

  • clear call
  • no obvious breakup
  • no obvious lag

If this profile sounds bad anyway:

  • first suspect a metrics blind spot
  • or a startup/playout-ready issue
  • or a transport/key/state issue outside receive policy

What to tune:

  • usually do not tune this profile first
  • only revisit if many healthy-looking calls still sound bad

multi-clean-low-latency

What it means:

  • Multi-source listener is not in recovery mode.
  • No multi-source target boost or extra hold is being applied for this source.

What to tune:

  • usually do not tune this profile first
  • if a 3+ call sounds bad here, verify that recovery mode is being entered when the live metrics justify it

multi-recovery

What it means:

  • Multi-source listener is in recovery mode, but this source is not currently the isolated weak leg.
  • The source still follows the multi-source feasible-target path.

What to tune:

  • multi-source recovery target/floor behavior
  • recovery exit timing if the call falls back too early

multi-weak-leg-recovery

What it means:

  • Multi-source recovery is active and this source has mild starvation or weak-leg priority.

Typical signals:

  • low source reserve relative to target
  • mild starvation classification
  • weak-leg prioritization selected for this source

What to tune:

  • weak-leg target boost
  • weak-leg accumulation target
  • extra hold frame cap

multi-protected-recovery

What it means:

  • Multi-source protected mode is active for this source.
  • This is the strongest multi-source profile before hard collapse.

What to tune:

  • protected-mode entry/exit streaks
  • protected-mode target tightening
  • extra hold frame cap if the weak leg still drains too quickly

multi-collapse-recovery

What it means:

  • Multi-source recovery is active and this source has strong starvation without protected mode currently latched.

What to tune:

  • strong-starvation classification
  • collapse recovery target/hold behavior
  • whether protected mode should enter sooner

steady-weak-listener

What it means:

  • Listener is weak enough to need help, but not in a severe collapse shape.

Typical signals:

  • modest under-target pressure
  • modest rate-chasing
  • some weak-listener pressure
  • not enough damage to justify a heavier profile

User symptom:

  • understandable but not clean
  • occasional breakup
  • sometimes “thin” sounding audio

What to tune:

  • light target boost
  • light floor behavior
  • post-recovery hysteresis
  • entry conditions if too many healthy listeners get classified here

When this profile is suspicious:

  • if reserve is clearly healthy and the call sounds fine
  • if a listener keeps being labeled weak when the path looks clean

repair-heavy-connected

What it means:

  • Listener is still connected and buffered, but too much audio is being repaired.

Typical signals:

  • meaningful missingFrames
  • meaningful concealmentTicks
  • meaningful under-target fraction
  • slower playout rate
  • reserve may still look “okay” on paper

User symptom:

  • breakup
  • static
  • patched / synthetic sounding audio
  • understandable but poor clarity

What to tune:

  • stronger hold duration
  • stricter clear conditions
  • profile-specific floor / target boost
  • recovery-mode hold while under-target and slow-rate pressure are still active
  • avoid relaxing back to low-latency too early

When this profile is suspicious:

  • if a side clearly sounds like collapse rather than repair-heavy survival
  • if reserve is very low and concealment is still exploding

Current tuning note:

  • This profile now uses stronger profile-specific target/floor behavior than steady-weak-listener, a longer hold window, and a slightly larger accumulation hold cap.
  • It should keep recovery-mode protection while the listener is still repair-heavy and rate-chasing, but it can stop forcing recovery once the current pressure has eased even if the profile hold is still carrying extra headroom.

repair-collapse

What it means:

  • Listener is both repair-heavy and very shallow on reserve.

Typical signals:

  • high concealment
  • shallow reserve
  • strongly negative playout delta
  • real “listener is failing hard” pattern

User symptom:

  • very broken audio
  • frequent collapse / heavy patching
  • hard to follow speech

What to tune:

  • stronger target boost
  • stronger floor
  • collapse-specific hold
  • stricter exit than repair-heavy-connected

Current tuning note:

  • This profile now uses the stronger severe single-source tier instead of the old 224ms floor / +120ms boost. It should stay above lean/weak recovery when the listener is shallow-buffered and repair-heavy, with a longer collapse hold so the target has time to rebuild reserve.

Use this instead of a new profile if:

  • the call is clearly repair-heavy and shallow-buffered
  • but still does not fit the simpler repair-heavy-connected path

persistent-lean

What it means:

  • Listener is not dramatically collapsing, but lives too close to empty for too long.

Typical signals:

  • low reserve for many windows
  • low prebuffer
  • low jitter depth
  • more lean than healthy, but not necessarily high concealment yet

User symptom:

  • not clear
  • weak audibility
  • ongoing roughness rather than one sharp failure

What to tune:

  • stronger steady target
  • stronger floor
  • longer hold
  • stricter exit only after reserve really rebuilds

When this profile is suspicious:

  • if the listener still sounds fine even with low reserve
  • if the real issue is actually startup or hidden playout readiness

silent-lean

What it means:

  • Listener is living dangerously close to empty, but the usual damage counters may still look deceptively mild.

Typical signals:

  • tiny reserve
  • tiny prebuffer
  • strongly negative delta
  • low concealment
  • low or zero obvious damage counters
  • may still have jitterHasReadyFrame: false at times

User symptom:

  • “I cant hear them well”
  • audio is weak or not clear
  • metrics may look cleaner than the user experience suggests

Why it exists:

  • this profile covers the blind spot where a side sounds bad before the usual damage counters fully explode

What to tune:

  • stronger floor
  • stronger target boost
  • longer hold
  • stricter exit conditions

When this profile is suspicious:

  • if the listener is actually repair-heavy and should have been in a heavier damage profile
  • if startup readiness never truly begins, which is a separate hidden-playout problem

post-failover-stabilization

What it means:

  • Listener is the newly promoted root after failover and should temporarily receive extra protection.

Typical signals:

  • recent root promotion after heartbeat timeout
  • call otherwise converged structurally
  • receive path still vulnerable right after promotion

User symptom:

  • failover succeeded, but the new root sounds weak or fragile immediately after

What to tune:

  • temporary target boost
  • temporary floor
  • hold duration after promotion

Do not use this for:

  • ordinary calls with no failover
  • generic weak-listener behavior

collapse-recovery

What it means:

  • Listener is in the strongest collapse-style recovery path.

Typical signals:

  • very low reserve
  • very negative delta
  • real under-target / concealment pressure
  • often elevated ingress age or empty prebuffer

User symptom:

  • very bad call quality
  • obvious collapse
  • severe breakup
  • speech hard to follow

What to tune:

  • collapse target boost
  • collapse floor
  • latch duration
  • stricter clear conditions after the collapse

Current tuning note:

  • This is the strongest single-source recovery tier. It now applies a higher floor and target boost than repair-collapse, plus a larger accumulation cap, for calls that are already correctly classified as severe but still sit near empty with ongoing concealment.

When this profile is suspicious:

  • if it keeps activating on merely moderate calls
  • if healthy or repair-heavy-but-buffered calls are being flattened into this stronger mode

Interpreting Real Exports

If the profile seems correct, but the call still sounds bad

That usually means:

  • the profile exists for the right reason
  • but its target/floor/hold behavior is still too weak

Tune:

  • target boost
  • floor
  • hold duration
  • clear conditions

If the profile seems wrong for the call shape

That usually means:

  • entry signals are too eager
  • or a neighboring profile is winning too early

Tune:

  • entry conditions
  • priority order
  • gating conditions for overlapping profiles

If the call sounds bad but the profile is clean-low-latency

That usually means one of:

  • a metrics blind spot
  • startup/pllayout readiness issue
  • key/state issue outside receive policy
  • a genuinely new failure class

Do not immediately add a new profile. First verify:

  • receive metrics
  • runtime diagnostics
  • startup readiness state
  • topology/key events

Current Mapping Heuristics

As of now, the rough intent is:

  • clean-low-latency: healthy listener
  • steady-weak-listener: modest weak path
  • repair-heavy-connected: buffered but breaking
  • repair-collapse: buffered and heavily damaged
  • persistent-lean: steady near-empty listener
  • silent-lean: near-empty but deceptively “clean” counters
  • post-failover-stabilization: promoted-root protection window
  • collapse-recovery: strongest collapse mode

If a call repeatedly lands in one of these and still sounds bad, tune that profile first.

Suggested Workflow For Future Call Logs

  1. Confirm the two exports are from the same room/call.
  2. Check each sides livePolicyProfilesBySource.
  3. Compare that profile to:
    • reserve
    • under-target
    • rate
    • concealment
    • missing frames
    • readiness state
  4. Decide:
    • correct profile, weak tuning
    • wrong profile, bad entry logic
    • not a receive-policy problem
  5. Only then patch code.

Updating This File

Whenever a profile changes materially:

  • update its “Typical signals”
  • update its “User symptom”
  • update its “What to tune”

Whenever a genuinely new recurring failure class appears:

  • add it here only after confirming it is not just a mis-tuned existing profile.