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

431 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# GCall Receive Profiles
This document is the working reference for the live receive-policy profiles used by the group-call audio engine.
Primary code:
- [src/lib/group-call/groupCallAudioReceiveEngine.ts](/home/qortal/Desktop/desktop-app-official/qortal-desktop/src/lib/group-call/groupCallAudioReceiveEngine.ts)
- [src/lib/group-call/groupCallAudioReceiveEngine.test.ts](/home/qortal/Desktop/desktop-app-official/qortal-desktop/src/lib/group-call/groupCallAudioReceiveEngine.test.ts)
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.