60db Logo
  • Engineering

FEC, redundant audio, or concealment?

Compare audio recovery mechanisms using payload, decoder, deadline, and playback evidence instead of a negotiated FEC flag.

Editorial date
Reading time
25 min
Recovery data approaches a deadline while replacement samples remain a separate mechanism

TL;DR: Codec recovery, redundant encoded audio, and concealment solve different parts of missing-media handling. Compare actual supporting payload, decoder use, deadline eligibility, and observed playout separately; negotiated capability alone cannot prove that missing original media was recovered or played.


The call negotiates an FEC option, the test removes a packet, and the report labels the missing audio recovered. Nobody checked whether the encoder supplied useful recovery data or whether the decoder used it.

A continuous output waveform can hide the same mistake. The receiver may have generated replacement samples that sound plausible while changing the one word the caller needed to understand.

Start with recovery evidence stages. Capability, available data, decoder behavior and playout are separate facts, and each needs the boundary that can observe it.

The transport guide establishes the media path. This article adds a standards-based mechanism comparison, a bounded evidence classifier, and a reproducible protocol for actual codec and listening trials.

Every example is synthetic. The reference function classifies supplied evidence and does not decode audio, reproduce a browser's media stack, or claim production results for 60db Agent.

Table of contents

  1. Define what recovery means
  2. Separate mechanisms by responsibility
  3. Inspect the negotiated contract
  4. Run a bounded evidence classifier
  5. Keep deadlines attached to recovery
  6. Measure overhead with a denominator
  7. Plan an actual codec trial
  8. Review decoded speech and task behavior
  9. Collect a recovery evidence ledger
  10. Choose a qualified operating policy
  11. Make the evidence adapter falsifiable
  12. Keep failure classes separate in the report
  13. Decide what additional waiting would buy
  14. Audit the labels before comparing outcomes
  15. Frequently asked questions
  16. Begin with one missing unit

Define what recovery means

The word recovery can describe several observations. An application might mean that supporting encoded data exists, that a decoder reconstructed samples using that data, or that useful content reached a listener before the task deadline.

Keep the term scoped whenever it appears in a report. A capability flag can support a statement about negotiation without supporting a statement about what happened to a particular missing unit.

Primary media decoding is another case. If the original packet arrived and was decoded normally, that success should not be counted as recovery merely because redundancy was also enabled.

Concealment produces locally synthesized replacement samples when original media cannot be used. It can help continuity while leaving the factual content of the missing speech uncertain.

The WebRTC statistics specification defines concealed samples at its own receiver boundary. It also distinguishes those samples from observations such as received or discarded packets, so do not collapse all of the counters into one repaired count.

A decoder returning output is still weaker than observing timely playout. Output can wait in another queue, become obsolete after interruption, or never reach the documented receiver boundary.

The playback evidence guide explains why local acceptance, provider events and acoustic observations are separate. None of them automatically proves comprehension or permission to act on a spoken instruction.

Choose the observation that matters for the current engineering question. An encoder interoperability test needs different evidence from a caller-facing test of whether a damaged confirmation preserved its amount and condition.

Primary and redundant encoded data feed the decoder while locally generated replacement samples remain a separate alternative

The diagram teaches mechanism boundaries. Its arrows are conceptual responsibilities and do not reveal or assert a particular product's internal codec pipeline.

Separate mechanisms by responsibility

Codec-specific in-band recovery carries information useful for reconstructing earlier missing media inside a supported codec representation. Its usefulness depends on the actual mode, emitted content, receiving decoder and deadline.

Redundant encoding carries additional encoded representations of earlier audio. RFC 2198 specifies the RTP redundant-audio format, while the tested adapter still needs to establish which earlier content the received payload can support.

Packet-loss concealment supplies replacement audio from the receiver's own state when primary or recovery input is unavailable. It does not establish that the original missing word or sample values were restored.

The Opus specification describes codec behavior and context. A generic application-level Python example cannot stand in for that decoder merely by filling a missing slot with a convenient placeholder.

RFC 8854 distinguishes audio FEC mechanisms and their constraints. Use the named mechanism and its applicability rather than treating every form of extra data as interchangeable protection.

The following table compares responsibilities, not vendors. A check means the mechanism supplies the property under its supported contract; a cross means it does not establish that property by itself.

Criterion Codec in-band recovery Redundant encoded audio Concealment
Uses transmitted recovery content ✓ When supplied ✓ Additional encoded content ✗ Local replacement
Can work without supporting later input ✗ Depends on mechanism ✗ Depends on supplied coverage ✓ Under decoder behavior
Extra encoded bytes possible ✓ Mode-dependent ✓ Explicit redundant content ✗ No transmitted repair required
Guarantees arbitrary burst repair ✗ No ✗ No ✗ No original recovery claim
Proves timely playout ✗ Separate observation ✗ Separate observation ✗ Separate observation
Proves critical-field correctness ✗ Needs task review ✗ Needs task review ✗ Needs task review

Avoid describing a mechanism as free because one local metric improved. Extra bytes, waiting, encoder choices, decoder work and the cost of additional clarification can all matter at different boundaries.

The loss-shape guide explains why a single average loss rate is insufficient. Losing the supporting packet can remove the very information the recovery mechanism needed.

Inspect the negotiated contract

Negotiation tells peers what representation and options are supported for a stream. It is necessary interoperability context, while actual media behavior still depends on what the sender emits and the receiver does.

The Opus RTP payload format documents relevant parameters. Record the accepted configuration and the actual codec implementation version when designing a recovery trial.

Do not infer emitted recovery data from the presence of one option. Encoder mode, loss feedback and implementation behavior can affect whether the particular encoded payload contains usable information.

A real developer question asks how to confirm that Opus FEC is sent. The thread provides a useful historical problem statement, not a guarantee about current browser counters or a universal setting that proves use.

Use the narrowest available observation. A payload inspection can establish supporting content where the format and encryption boundary permit it; a decoder trace can establish which mode it used; a receiver event can establish a later delivery boundary.

Keep unavailable observations explicit. An encrypted packet capture without decryption evidence cannot reveal the full codec payload simply because the investigator knows the negotiated format.

The WebRTC media transport requirements provide protocol context. Real route, encryption and telemetry support still need to be recorded for the tested implementation.

A mechanism can be negotiated and capable yet unused in a particular trial. That is a valid outcome and should remain visible instead of being forced into either recovered or failed categories.

Supported capability, present recovery data and deadline eligibility are checked before attempting a decoder, without promising recovery

Run a bounded evidence classifier

Save the full fence as recovery_evidence.py and run Python 3.11 or later. It uses immutable records and synthetic evidence to keep capability, decoder use and observed playout distinct.

The trusted adapter supplies the observations. Constructing an evidence record is not proof that a codec performed the action, and the function never creates or reconstructs audio samples.

The fixture named capable-but-unused covers an important negative case: supported payload and negotiation exist, but the decoder used concealment or did not attempt recovery. That case must never return recovered output.

from dataclasses import dataclass, replace, FrozenInstanceError
import math


@dataclass(frozen=True)
class Evidence:
    mechanism: str
    negotiated: bool
    payload_capable: bool
    arrival_ms: float | None
    deadline_ms: float
    decoder_mode: str
    decode_success: bool | None
    playout_observed: bool

    def __post_init__(self):
        if self.mechanism not in ("inband", "red", "plc"):
            raise ValueError("unknown mechanism")
        if self.decoder_mode not in ("recovery", "primary", "plc", "unused"):
            raise ValueError("unknown decoder mode")
        if any(type(x) is not bool for x in
               (self.negotiated, self.payload_capable, self.playout_observed)):
            raise ValueError("boolean observations required")
        if self.decode_success is not None and type(self.decode_success) is not bool:
            raise ValueError("invalid decode observation")
        for value in (self.arrival_ms, self.deadline_ms):
            if value is not None and (type(value) not in (int, float)
                                     or not math.isfinite(value) or value < 0):
                raise ValueError("finite local times required")
        if self.deadline_ms is None:
            raise ValueError("deadline required")


def classify(e):
    if e.decoder_mode == "primary":
        return "primary_decode_not_recovery"
    if e.mechanism == "plc" or e.decoder_mode == "plc":
        return "replacement_not_original_recovery"
    if not e.negotiated:
        return "unsupported"
    if not e.payload_capable or e.arrival_ms is None:
        return "recovery_data_unavailable"
    if e.arrival_ms > e.deadline_ms:
        return "too_late_for_declared_deadline"
    if e.decoder_mode != "recovery":
        return "capable_but_unused"
    if e.decode_success is None:
        return "decode_outcome_unknown"
    if not e.decode_success:
        return "decode_failed"
    return ("recovered_playout_observed" if e.playout_observed
            else "recovered_decode_only")


def overhead(primary_bytes, recovery_bytes):
    if any(type(x) is not int or x < 0 for x in (primary_bytes, recovery_bytes)):
        raise ValueError("nonnegative byte counts required")
    return None if primary_bytes == 0 else recovery_bytes / primary_bytes


def tests():
    base = Evidence("inband", True, True, 10, 20, "recovery", True, False)
    assert classify(base) == "recovered_decode_only"
    cases = [
        (replace(base, playout_observed=True), "recovered_playout_observed"),
        (replace(base, decoder_mode="unused"), "capable_but_unused"),
        (replace(base, decoder_mode="plc"), "replacement_not_original_recovery"),
        (replace(base, mechanism="plc"), "replacement_not_original_recovery"),
        (replace(base, decoder_mode="primary"), "primary_decode_not_recovery"),
        (replace(base, negotiated=False), "unsupported"),
        (replace(base, payload_capable=False), "recovery_data_unavailable"),
        (replace(base, arrival_ms=None), "recovery_data_unavailable"),
        (replace(base, arrival_ms=21), "too_late_for_declared_deadline"),
        (replace(base, decode_success=None), "decode_outcome_unknown"),
        (replace(base, decode_success=False), "decode_failed"),
    ]
    for evidence, expected in cases:
        assert classify(evidence) == expected
    assert classify(replace(base, arrival_ms=20)) == "recovered_decode_only"
    assert overhead(100, 25) == 0.25
    assert overhead(100, 0) == 0
    assert overhead(0, 0) is None
    try:
        base.payload_capable = False
        raise AssertionError("evidence was writable")
    except FrozenInstanceError:
        pass
    for bad in (lambda: replace(base, arrival_ms=float("nan")),
                lambda: replace(base, decoder_mode="pretend"),
                lambda: overhead(-1, 0), lambda: overhead(1, True)):
        try:
            bad()
            raise AssertionError("invalid observation accepted")
        except ValueError:
            pass
    print("synthetic recovery evidence fixtures passed")


if __name__ == "__main__":
    tests()

The observed-playout outcome refers only to the adapter's declared observation boundary. It does not claim acoustic audibility, comprehension, agreement, or task completion.

The byte ratio uses synthetic fixture counts and a declared primary-byte denominator. It is not a measured overhead value for any codec, carrier, browser or workload.

Keep deadlines attached to recovery

Supporting data can arrive too late to help the current playout schedule. A report that counts every eventual successful decode as timely recovery can hide the waiting that made the conversation unusable.

Declare the relevant deadline and clock. The local classifier accepts arrival equal to the deadline; a real decoder trial needs its own explicit admission rule and evidence for the actual timing boundary.

The jitter-buffer guide shows how waiting can make more arrivals usable while adding delay. That decision belongs in the mechanism evaluation instead of being treated as an unrelated tuning detail.

A missing supporting packet can make recovery data unavailable. A long consecutive loss can remove both the primary unit and the later data that might have helped reconstruct it.

The burst-versus-random fixture guide supplies paired masks for that condition. Keep the actual pattern so a successful isolated-loss trial is not generalized to arbitrary bursts.

A decoder may produce output after the application's response generation has become obsolete. Media-level recovery does not renew conversational authority, so final output still needs current-generation and age checks.

The backpressure guide explains held chunks and final admission after waiting. Reject stale identity before applying expiry side effects to any current response.

A synthetic missing-primary sequence places supporting redundancy after its declared deadline, so it is not counted as timely recovery

Measure overhead with a denominator

Extra encoded bytes are one cost of transmitted recovery. Keep primary payload, recovery payload, protocol overhead and retransmission traffic separate when the adapter can observe them.

A ratio of recovery bytes to primary bytes answers one question. A ratio of all transmitted bytes to useful decoded duration answers another, and both need the actual population and units.

Do not report an undefined denominator as zero overhead. A trial with no primary bytes cannot support the same ratio as a trial that sent primary media and no recovery data.

Negotiation does not determine the realized overhead for every packet. Observe what was emitted under the tested codec mode and workload, preserving the raw counts needed to recompute the calculation.

Keep time cost beside byte cost. A mechanism that requires later supporting input can consume part of the available response budget even when its byte overhead is modest.

Additional traffic can affect congestion behavior. A local comparison that ignores feedback and route capacity should state that limit instead of promising a net improvement on a busy network.

The cost-per-success guide adds the task denominator. Extra media work can be worthwhile when it preserves a critical value, while unnecessary retries and repeated calls can erase a narrow encoding saving.

In-band recovery, redundant encoding and concealment are compared by supporting input, extra bytes and replacement behavior

Plan an actual codec trial

Use a valid encoded baseline and the tested decoder's supported API. The versioned Opus decoder documentation provides an example of the adapter contract that a real trial must follow.

Do not add a dependency merely to produce a result-shaped chart. If the current task is to define evidence and fixtures, the bounded classifier can stand alone while the real codec experiment remains explicitly unperformed.

When a real trial is authorized, save source audio, encoded packets, negotiated settings, decoder version, actual impairment mask and declared timing policy. Those inputs let a reviewer reproduce the specific recovery opportunity.

Include a capability-without-use fixture. Supply supporting data and negotiated permission but configure the decoder not to use recovery, then assert the report remains capable-but-unused or replacement rather than recovered.

Include recovery data that arrives after the deadline. Decoder success afterward should remain a late outcome for the earlier playout question, even if the output is useful for offline analysis.

Include primary media that survives. That case should be classified as ordinary primary decode instead of being credited to FEC because the feature was enabled globally.

The regression testing guide explains how to retain these cases. A test suite should distinguish a repair of the evidence contract from an improvement in actual decoded quality.

Review decoded speech and task behavior

A real decoder trial should retain output for an authorized review. Inspect whether the recovered or replacement segment preserves the critical field that the task needs, not merely whether output samples exist.

Choose safe synthetic phrases with canonical expected values. Keep those values outside the audio fixture so the evaluator can identify a changed digit, negation or condition without relying on a subjective quality impression.

The multilingual evaluation guide helps preserve those critical fields across languages. Do not treat a result on one speaking style or language as evidence for every supported caller population.

A listener can understand imperfect audio, and a recognizer can produce a plausible but wrong transcript. Keep acoustic review, recognition result and task consequence as separate observations.

The outcome metrics guide provides that separation. A failed critical value should remain visible even when a broad average looks favorable.

A controller can also respond safely by asking for a repair. Record whether it detects uncertainty and preserves the corrected field rather than treating every clarification as a codec failure or every fluent guess as success.

The spoken correction guide covers the accepted-value boundary. Recovery should not leave the old damaged interpretation hidden in an action argument after the caller replaces it.

Collect a recovery evidence ledger

Keep one record per expected source identity and join observations to it. The ledger should distinguish primary availability, supporting payload, deadline eligibility, decoder mode, decode outcome and declared playout evidence.

Save stream identity and receiver epoch with cumulative counters. A restart that reuses the same SSRC must not be treated as a continuous measurement merely because the next counter happens to look larger.

Keep raw values and units before deriving rates. Missing recovery telemetry means unavailable evidence, while a supported zero count is an observation for the stated interval.

The observability guide explains why each boundary needs its own event. A generic success flag can hide whether the sender, decoder or player supplied the claim.

Negotiated capability, encoded payload evidence, decoder outcome and listening review remain distinct evidence stages

Do not publish raw call identifiers or customer audio to make the report feel realistic. Synthetic identities and controlled source fixtures can verify the same contract without disclosing a person or a private implementation.

Choose a qualified operating policy

Choose a policy from the workload evidence and the task's deadline. The result can be conditional: one mechanism may be appropriate on a supported route while another remains unavailable or unqualified elsewhere.

Keep negotiated capability and actual use in separate columns during rollout. That makes a deployment change that disables recovery visible without turning a missing counter into an invented failure estimate.

The chunk-size guide adds packetization context. Changing packet duration can alter both damage shape and recovery timing, so it belongs in the same qualified configuration.

The interruption ownership guide supplies the final authority check. A successful recovery of old media cannot make that media appropriate after the caller changes the task.

This article reports no measured codec winner or production quality improvement. The runnable classifier proves a local evidence distinction; actual encoding, decoding, deadlines, playback and listener outcomes remain the separate proof required for deployment claims.


Make the evidence adapter falsifiable

The classifier is intentionally easy to call. That makes the adapter that supplies its fields the more demanding part of the experiment. A truthful classifier can still produce a misleading result when an adapter labels an encoder setting as payload capability or labels a decoder return as observed playout.

Write a short observation contract for every field before connecting it to a real implementation. Identify the producing component, the unit it describes, the timestamp boundary, the clock domain, and the condition that makes the observation unavailable. Keep that contract next to the test configuration so a change in decoder instrumentation does not silently change the meaning of a result label.

For negotiation, retain the relevant supported configuration and the identity of the connection on which it became effective. An offer containing an option is weaker evidence than an agreed configuration. A configuration recorded on an earlier connection does not establish support after renegotiation or a receiver restart. The artifact accepts a Boolean only after the adapter resolves that distinction.

For payload capability, document how the adapter establishes that the received representation contains usable support for the missing unit. A packet being larger than a neighboring packet is not enough. Neither is a codec setting that permits recovery in principle. When the available API cannot expose the relevant information, classify capability as unknown in the real ledger and keep it outside the artifact's affirmative-capability fixtures.

For decoder mode, prefer an explicit invocation or instrumented observation at the supported decoder boundary. A general output callback may combine normal decoding, recovery, and concealment. If those modes cannot be separated, the report should say that useful output was observed while the mechanism remains unresolved. It should not assign every successful callback to the protection option currently under test.

For playout, choose one observable boundary and name it precisely. Submission to an output API is local acceptance. A provider's documented playback event is a different boundary. An acoustic capture is another observation, with its own setup and alignment uncertainty. The classifier's affirmative playout field means the experiment has established its declared boundary; it never turns an arbitrary callback into proof that a human heard or understood the content.

Attach an event identity to each supporting observation. The negotiated state, payload inspection, decoder invocation and playout record must describe the same missing media unit and the same experiment. A decoder result from a neighboring unit can otherwise make a trace look complete while leaving the original loss unexplained.

Use negative adapter tests as well as positive ones. Feed a supported negotiation with no recovery invocation. Feed an invocation that reports failure. Feed a successful decode whose output is deliberately withheld from the selected playout boundary. Each result should stop at the evidence stage reached. The article's fixtures establish those distinctions within supplied data; adapter tests establish whether real observations populate that data honestly.

The audio contract review is relevant here because a recovery unit still needs a representation, duration and identity. Without that contract, two components can report success while referring to different samples or different positions in the stream.

Keep failure classes separate in the report

A useful recovery report preserves the reason a missing unit did not become useful output. Unsupported negotiation, missing supporting payload, late supporting payload, unused capability, decoder failure and unobserved playout are different engineering findings. Combining them into a single unrecovered bucket hides which change could help.

Begin with the complete offered population. Record which primary units were intentionally removed and which remained available. Keep the original impairment mask, then add receiver observations rather than rewriting the mask when redundancy succeeds. Otherwise a system with successful recovery can appear to have experienced a cleaner network than the one the generator supplied.

Next record eligibility. A unit can have supported recovery content and still be ineligible because its supporting data arrives after the declared deadline. That is a timing outcome. It does not establish a broken codec or an incorrect decoder invocation. Conversely, data arriving before the deadline does not establish that the decoder chose or succeeded at recovery.

Then record decoder behavior and output. The capable-but-unused fixture is especially valuable because it defeats a tempting shortcut: counting a negotiated feature plus a qualifying payload as a recovered unit. The receiver may have selected concealment, reached another policy limit, or exposed insufficient instrumentation. The classifier keeps the supplied unused case separate instead of guessing which explanation occurred.

Finally join the selected playout boundary. A recovered decode can become obsolete while waiting for an output queue. An interruption can cancel the response that owned it. A disconnected receiver can leave the result locally ready but undelivered. Preserve a decoded-only outcome when that is what the evidence supports, even if the codec experiment otherwise succeeded.

Keep percentages attached to these populations. An eligibility rate uses the relevant missing-unit population. A decoder success rate uses the population for which recovery was attempted under the stated eligibility rules. A timely playout rate needs its own observed-output population. Those denominators answer different questions; none can substitute for the others merely because the resulting chart looks simpler.

Do not average across incompatible durations without stating the weighting. A unit-count fraction describes units. A duration-weighted fraction describes media time. A task-field score describes the reviewed fields, such as a spoken date or confirmation condition. An apparently small damage interval can contain the entire meaning of one critical field, so media continuity and task correctness need separate results.

The burst-loss comparison provides the paired masks for that experiment. Keep the same primary damage when changing the recovery setting, and preserve any increase in transmitted supporting data. A comparison that changes both loss arrangement and recovery mechanism cannot attribute the difference to either factor alone.

Use a lossless control to reveal overhead or compatibility failures that exist even when nothing is missing. Use a zero-support control to verify that the measurement pipeline does not manufacture recovered results from concealment. Use a deliberately late-support control to prove the deadline label follows arrival evidence rather than the mere presence of recovery bytes somewhere in the trace.

Decide what additional waiting would buy

A recovery mechanism can create an opportunity to wait for supporting data, but the decision to wait belongs to the conversational policy as well as the codec. The important question is what useful result becomes available before the caller's task has moved on.

Hold the arrival trace fixed when exploring a different deadline. This isolates the scheduling decision from the network conditions. Record which missing units change from too late to eligible, then check which of those eligible units lead to a supported decoder result and useful playout. More eligible inputs are an opportunity, not a measured improvement by themselves.

Also inspect the speech that was already available. Waiting for one missing unit may delay neighboring content that could otherwise have progressed. A receiver may make a different trade-off for a short confirmation than for a longer explanation. The bounded classifier deliberately does not choose that policy because it has no representation of the caller's task, output queue or interruptibility.

The jitter-buffer replay offers a separate way to reason about arrival deadlines. Combining the two experiments requires an explicit adapter: the replay's media identity and deadline must match the classifier's unit, and the clocks must be comparable. Simply placing results from the two tools beside each other does not establish that join.

Prefer a small set of predeclared candidate policies over searching until one sample sounds good. Keep the same source material, damage masks, decoder version, output configuration and review procedure. Record the policy difference before inspecting the result so the experiment can be repeated without reconstructing choices from memory.

Review the cases that remain bad under every candidate. They may expose a boundary that extra waiting cannot repair, such as unavailable recovery content, a burst longer than the available support, an unsupported receiving mode, or a correction that made the response obsolete. Those findings help prevent a latency increase from being presented as a universal repair.

Review the cases that improve only at the codec boundary but fail at the task boundary. The decoder may produce plausible speech while a critical amount remains ambiguous. The listening procedure should preserve uncertainty and permit a clarification outcome. It should not force a reviewer to choose a transcription merely to make the evaluation table complete.

A qualified operating decision names the mechanism, its supported configuration, the admitted deadlines, the observed benefits and the remaining failure classes. It also identifies the condition that would reopen the choice, such as a different packet duration, a new receiver implementation or a changed task profile. That is more useful to a future maintainer than an unqualified recommendation to turn FEC on.

Audit the labels before comparing outcomes

Before plotting a recovery comparison, select a small set of individual missing units and follow each one through the evidence stages. Start with the original loss mask, locate its supporting payload if one exists, inspect the decoder observation, and finish at the declared output boundary. This manual join checks the meaning of the aggregate without inventing a performance score.

Include one capable-but-unused unit in that audit. Its negotiation and payload fields can look promising, but its decoder mode must keep it out of the recovered category. Include a concealment case too. Locally generated replacement samples may be useful to the listener while remaining a different mechanism from transmitted recovery content.

Include a late-support unit whose payload is present in the archived trace. That case prevents an offline analyzer from forgetting the live deadline. A file containing all eventual arrivals can make reconstruction seem possible after the fact even though those bytes were unavailable when output had to progress.

Include a successful decode without observed playout. Ask the reviewer to identify exactly which additional event would justify advancing the result. If the answer is merely that the decoder usually feeds the player, the ledger is relying on an assumption. Preserve decoded-only until the chosen boundary supplies evidence.

Check that primary-only success stays outside recovery totals. If the primary unit arrived normally, a recovery-enabled configuration does not change the mechanism that produced its output. Counting all output under that configuration as recovered would make the lossless control look like a recovery success population.

Read the legend using the same words as the classifier. A label such as protected can mean configured support, eligible payload or observed useful output. Replace that ambiguity with explicit stage names. A future maintainer should be able to infer the required evidence from the report without opening the code first.

Record unresolved cases separately. Missing instrumentation should not be converted to decoder failure, and a decoder failure should not be converted to an unsupported negotiation. Both may block a stronger claim, but they lead to different next measurements and different repairs.

When a trial changes the mechanism, audit the labels again at the adapter boundary. A different decoder or provider can expose a callback with a familiar name and a different meaning. The bounded classifier remains useful only while the supplied evidence preserves the same contract.

Keep the audit small enough that every claimed recovery can be inspected, then scale the same evidence schema to the larger trial. Scaling should add observations rather than weaken the definition. If the larger environment cannot expose the decoder mode that the small experiment used, keep its result at a weaker stage instead of silently substituting output continuity for observed recovery.

Have the report identify which boundaries were instrumented and which were inferred. The strongest claim should use only the instrumented or otherwise supported join. An inference can motivate another experiment, but it should remain labeled as an inference until that experiment supplies the missing observation.

A maintenance review can repeat this audit after any adapter change without rerunning a broad benchmark. Choose the capable-but-unused, too-late and decoded-only controls first. If those labels remain distinct and the positive fixture still progresses, the primary evidence contract survives. Actual codec quality, real-device playout and task behavior still require the separate trials described above.

Frequently asked questions

How do FEC and concealment differ?

FEC uses transmitted supporting information under its mechanism's contract. Concealment generates replacement samples locally, so continuous output from concealment is not proof that the original missing content was reconstructed.

What does redundant audio carry?

Redundant encoding carries additional encoded representations of earlier audio under the supported format. Its usefulness depends on coverage, arrival timing and decoder behavior rather than the presence of extra bytes alone.

Does negotiating FEC prove it was sent?

Negotiation establishes supported options for the stream. Inspect actual encoded payload or suitable implementation evidence before claiming that the particular missing unit had usable recovery information.

Does receiving redundancy prove it was used?

Available supporting data can remain unused by the decoder. Preserve capable-but-unused as a distinct outcome, and record decoder mode and success before claiming recovered output.

Why does the playout deadline matter?

Supporting data that arrives after the useful deadline cannot establish timely recovery for that schedule. A later offline decode can be valid evidence for another question, but it does not erase the earlier late outcome.

Can the next packet repair a missing one?

Some mechanisms can carry supporting information for earlier media. Verify the actual codec mode, payload and decoder use, and retain the timing dependency rather than treating the next packet as automatic repair.

What if both packets are missing?

If the primary unit and its supporting information are unavailable, that recovery opportunity is absent. The decoder may use concealment or another supported mechanism, which must be reported under its actual behavior.

Can redundancy protect arbitrary bursts?

A finite redundancy scheme has finite supplied coverage and timing constraints. Test the burst patterns the workload needs and avoid generalizing an isolated-loss success to every consecutive gap.

How should overhead be measured?

Record primary and recovery bytes separately and state the denominator. Include protocol traffic or retransmissions only when the report explicitly measures them, and keep undefined zero-population ratios unavailable.

Can I infer recovered audio from packet count?

Network packet count does not establish which source units were recovered. Preserve original media identity and the supporting-data mapping the adapter can observe instead of assuming one packet equals one recovery.

What does Opus mode change?

Codec mode and implementation settings can affect emitted recovery content and decoder behavior. Record the tested configuration and version rather than treating a negotiated option as a complete description of the stream.

Is RED identical to Opus in-band recovery?

RED and codec in-band recovery have different representation and support contracts. Name the mechanism used and test its payload, decoder and deadline evidence separately.

Does concealment reconstruct the original signal?

Concealment creates replacement samples from the decoder's available state. It can reduce audible discontinuity while leaving the original missing content and critical-field correctness unproven.

How should unsupported counters be treated?

Keep unsupported counters unavailable. Replacing them with zero invents an observation and can distort comparisons between implementations with different telemetry support.

Which decoder version belongs in a report?

Record the actual tested decoder and relevant settings with its encoded fixture and impairment trace. A specification reference explains the contract but does not identify the exact implementation that produced the output.

Can FEC worsen congestion?

Transmitted recovery can add traffic and interact with congestion behavior. Measure the actual route and workload before claiming that a byte or quality trade-off is beneficial under constrained conditions.

What does the local evaluator prove?

It verifies the distinction between supplied capability, payload availability, timing, decoder use and observed playout evidence. It does not encode, decode, play audio or independently validate the adapter's observations.

How do listening tests complement raw counters?

Counters describe supported media observations, while listening and task review can reveal a changed or missing critical value. Keep both so continuous decoded output is not mistaken for successful understanding.

Should incomplete trials be included?

Include incomplete, disconnected and unavailable trials in the workload accounting. If a quality or latency calculation uses only completed runs, state that conditional denominator alongside the omitted outcomes.

Where should mechanism selection begin?

Begin with one valid baseline and one missing-unit fixture whose supporting data and deadline are known. Prove the evidence stages, then broaden to representative burst patterns and listening tasks.

Begin with one missing unit

Choose one synthetic missing source unit and record whether supporting payload exists, arrives in time, is used by the decoder and reaches the declared playout boundary. Run the classifier fixtures before adding claims to a report.

Use that evidence chain to qualify a mechanism on the actual workload. Keep unknown observations and failed cases visible so the next engineering decision rests on observed recovery rather than an enabled feature flag.