Skip to main content

WAI Extension: Opus Deep Redundancy, Decoded Exactly

Mirrored from the canonical text at commit 260cbd09 ().

Status: Draft. Registers two companion-only capabilities for the deep redundancy (DRED) of draft-ietf-mlcodec-opus-dred-07: a compact neural latent of the recent speech, carried in an Opus packet’s padding, from which a receiver rebuilds the acoustic features of packets that were lost. wai.audio.opus.dred is that decoding as the draft defines it, held to the draft’s own conformance test (its §4.1), which admits any decoder whose features lie within its thresholds of the reference. wai.audio.opus.dred.int is the same decoding through an integer profile, dred-int/1: the draft’s own decoder network and its own weights file, pinned by digest, lowered to wai-ops/1 graphs (integer-operators) whose output is the same integers on every machine and on every fabric whose operator implementation conforms. With it, a stream under loss has one reconstruction, named by a digest that a verifier recomputes from the packets, the loss and the weights, and a player can sign that digest in the log of synthesis §10.3. This extension also says where the working group’s other documents stand in WAI’s registry and in synthesis’s lattice (§2.3, §7.1), and measures the profile against the floating-point network (§6). No new transport. The reference implementation is the dred_exact module of wai-rs (feature dred_exact); the corpus is live-conformance/dred/, and its second implementation is live-conformance/dred_verify.py. The integer profile as a proposal to the working group is drafted in proposals/dred-integer-profile.md, which is not filed. Keywords MUST, MUST NOT, SHOULD, MAY are RFC 2119/8174.

Texts read for this revision, each pinned to the version named: draft-ietf-mlcodec-opus-dred-07 (4 August 2026), with the files its §7 references by SHA-256 ([DRED-Weights], [DRED-Test-Vectors], [DRED-Compare], [DRED-Ref-Impl]); draft-ietf-mlcodec-opus-extension-06; draft-ietf-mlcodec-opus-speech-coding-enhancement-04; draft-ietf-mlcodec-opus-scalable-quality-extension-02; draft-ietf-mlcodec-test-battery-00; RFC 6716 §3, §4.1 and §5.1; RFC 7587.

1. Scope

The draft’s decoder has two parts (its §4): a feature decoder, a recurrent network that turns the latents into 20 acoustic features per 10 ms, which the draft makes normative and tests within tolerances; and a vocoder that turns features into samples, which the draft leaves to the implementation (its §2.2.4, §4.2). This extension’s profile is of the first part.

Conformance targets.

Out of scope.

2. Registration

2.1 Two strings, one payload

stringkindrolereplicate classparameter set
wai.audio.opus.dredcompanionenhancement layer over wai.audio.opus.packetStandardTolerance: features within the draft’s §4.1 thresholds of the referencethe draft’s, fixed by the draft
wai.audio.opus.dred.intcompanionenhancement layer over wai.audio.opus.packetNeuralIntegerExact: the features of §4, exactlyone file, the draft’s weights file (§4.1)

Both carry the same payload. They differ in what a sink that advertises them promises, which is what a sender chooses between: a sender that needs any rebuilt speech names the first; a sender whose reconstruction is to be recomputed, signed or presented at decode-equivalence names the second, with a pin on the weights file (SPEC §3.1) that declares tier decode-equivalence. Two strings are needed because a capability’s class bounds the tier a pin may claim (SPEC §3.1, Tier): a decode admitted within tolerances cannot back replicate, and the draft’s decoding is admitted within tolerances.

2.2 Why a companion, not a refinement

A refinement-only capability is applied to the output of the stage below it, bound to that output’s producer by content hash (staged-delivery): its payload corrects what the base decoded. DRED corrects nothing the base decoded: it is a second, coarser encoding of the same speech, sent ahead so that a receiver can rebuild what a loss took, and it is read only where the base’s own frames are missing. Its payload has no meaning without the encode it was made with: its offsets index that encode’s frames (draft §3), and its first rebuilt samples continue that encode’s last decoded ones (draft §2.2.4). That is the model of an enhancement layer (SPEC §5): a companion-only capability, decoded by its own standard over one base encode, bound to exactly one selectable rendition of a base it lists, and the base of no second layer. So both strings are registered as enhancement layers. Their one base is wai.audio.opus.packet, one Opus packet per object, because there the envelope itself aligns the DRED payload with the packet it belongs to; this revision pins no alignment of a separate DRED stream with an Ogg Opus stream (wai.audio.opus), as SPEC §5 pins none for a separately carried LCEVC stream.

DRED is carried one of two ways, as an enhancement layer is (SPEC §5, Enhancement layers):

2.3 The working group’s other documents

2.4 Licence class

Both strings are classed patent-pool, the conservative class REGISTRY.md gives a capability whose royalty status is not established. One IPR disclosure on the individual draft that became draft-ietf-mlcodec-opus-dred, the IETF’s disclosure 6063, states an intent to license royalty-free if the technology is included in a standard the IETF adopts; until that happens the status is not established. A later revision MAY move both strings to royalty-free once it is.

3. Finding DRED and its integers

3.1 The packet

A sink reads an Opus packet’s framing as RFC 6716 §3.2 defines it, and holds it to §3.4’s rules R1–R7. A packet that breaks one is not a valid Opus packet: nothing in it is read, and its DRED is refused (packet_malformed). From a valid packet it takes the number of frames, each frame’s duration in units of 2.5 ms (RFC 6716 §3.1: 4, 8, 16 or 24 for configurations 0–11 by configuration modulo 4; 4 or 8 for 12–15 by configuration modulo 2; 1, 2, 4 or 8 for 16–31 by configuration modulo 4), and the padding of a code-3 packet.

3.2 The extensions

The padding’s extensions are read as draft-ietf-mlcodec-opus-extension-06 §2 defines them, including the frame separator (ID 1) and the repeat mechanism (ID 2, §2.3), in bitstream order, each instance with its frame index. Iteration stops at the first extension whose length, or whose frame index, would read past the padding or the packet’s last frame (§2.7); the instances before it stand.

The packet’s DRED payload is the first instance, in that order, that is either:

Its frame offset is its instance’s frame index times the frame duration, in units of 2.5 ms. A packet with no such instance carries no DRED. (The reference implementation the draft names in its Appendix B finds DRED this way, under ID 126.)

3.3 The payload

The payload is decoded with the range decoder of RFC 6716 §4.1, as draft §3 and §3.1 define it. This section fixes the details the draft’s prose leaves open, as the draft’s reference decoder does; where the two could be read apart, the reference decoder’s reading is this profile’s.

  1. The header: q0 = uint(16), dQ = uint(8), X = uint(2); if X = 1, an extended offset E = uint(256), else E = 0; an indicator I = uint(32). uint(n) is ec_dec_uint of RFC 6716 §4.1.5 for n ≤ 256, one symbol of n equally likely values. encoded_offset = 32·E + I.
  2. qmax: 15, unless q0 < 14 and dQ ≠ 0. Then, with n = 14 − q0, a symbol is decoded over a total of 2n (ec_decode): a value s ≥ n gives qmax = q0 + (s − n) + 1 and is consumed as [s, s + 1); a value s < n gives 15 and is consumed as [0, n).
  3. The offset, dred_offset = 16 − encoded_offset + frame_offset, in units of 2.5 ms: the newest feature vector the payload rebuilds ends this long after the start of the frame that carries the extension.
  4. The initial state: 50 coefficients k = 0 … 49, at quantizer q0, with the state tables (draft Tables 6, 8 and 9). Then latent vectors l = 0, 1, …, newest first, each of 25 coefficients at quantizer q_l = min(qmax, q0 + ⌊(D[dQ]·l + 8) / 16⌋) with D = [0, 2, 3, 4, 6, 8, 12, 16], the slope table of draft §3 in sixteenths, with the latent tables (Tables 2, 4 and 5). Before each latent vector, if 8·len − tell ≤ 7, where len is the payload’s length in bytes and tell is ec_tell (RFC 6716 §4.1.6.1), no more are decoded.
  5. A coefficient with decay r and zero probability p0 (the tables’ entries for its coefficient and quantizer): if r = 0 or p0 = 255, it is 0 and nothing is decoded. Otherwise, with P = 128·p0 and S = 32768 − P, a symbol is decoded by ec_dec_icdf16 (with ftb = 15) against the table [S, ⌊S/2⌋, 0]: 0 is a zero coefficient, 1 positive, 2 negative. A non-zero coefficient’s magnitude is then 1 + v_1 + v_2 + …, each v_j decoded by ec_dec_icdf16 against icdf[0] = max(7, 128·r), icdf[i] = max(7 − i, ⌊icdf[i − 1]·128·r / 2^15⌋) for i = 1 … 6, icdf[7] = 0, while the symbol just decoded is 7. When the magnitude being summed passes 2^16, the payload is refused (dred_latent_range): the draft’s escape rule bounds nothing, and past a payload’s last byte the decoder reads zero bytes (RFC 6716 §4.1.2), so a crafted payload could otherwise keep a decoder reading.

The draft’s test bit files carry payloads with no header (each record gives q0, with no slope, and a count of latents); §6 reads them so.

4. The integer profile dred-int/1

4.1 The parameter set

The parameter set of wai.audio.opus.dred.int is one file: the decoder weights file draft §2.2.2.1 and §7.1 name ([DRED-Weights]), whose SHA-256 is 394f0ecf19926cebd678019dc94a54c88ae078340c16325069707f286cdf28a6. A sink MUST check the file against that digest before it reads it, and MUST refuse any other file (weights_digest_mismatch): the draft makes another set of weights non-conforming (its §4.1, “an alternate DNN model is not allowed”), and §4.4 makes these weights’ integers a function of this file’s bytes. A pin over the set names that digest.

The file is read as the draft’s Appendix A defines it. The profile reads, for each layer of the table below, the arrays dec_<layer>_weights_float and dec_<layer>_bias, and for a block-sparse layer dec_<layer>_weights_idx; it reads no other array. A dense matrix is stored input-major (weights[in·outputs + out], A.3.1). A block-sparse one (A.3.2) is a run of groups of 8 outputs, each a count of blocks and then each block’s first input (a multiple of 4), and its weights are blocks of 8 outputs by 4 inputs stored input-major inside the block (w[in·8 + out]); every position no block covers is 0.

layerinputsoutputssparse
dense12696no
hidden_init50128no
gru_init128320yes
gru1_input … gru5_input96, 192, 288, 384, 480192yes
gru1_recurrent … gru5_recurrent64192no
glu1 … glu56464no
conv_dense1 … conv_dense5160, 256, 352, 448, 54432yes
conv1 … conv56432no
output57680yes

The weights are not in this repository. The corpus names the file by digest, and its fetch script (live-conformance/dred/fetch.sh) fetches it from the location the draft gives and checks the digest.

4.2 The tables

The decoder reads draft Tables 2, 4, 5, 6, 8 and 9 (scale, decay and P(0), for the latents and for the state). Serialized row by row (coefficient k from 0, the sixteen quantizers in order, one byte each), in the order latent scale, latent decay, latent P(0), state scale, state decay, state P(0), their SHA-256 is 03f7d6b22e2aca5f5a28525a1311e1113d94b917fbc74a5493b04bbed5c97ded. An implementation that transcribes them checks its transcription against this digest.

4.3 The inputs

Every graph input is an integer at 2^16 (Q16). A coefficient x of the initial state, with state scale s at q0, and a coefficient of latent l, with latent scale s at q_l, stand for x·256 / max(1, s) (draft §3.1), which the input holds as ⌊(2·x·2^24 + s′) / (2·s′)⌋ with s′ = max(1, s): the quotient rounded to the nearest integer, a tie upward. A latent’s 26th input is q_l/8 − 1 (draft §2.2.2), held as (q_l − 8)·2^13.

4.4 Weights to integers

Every weight becomes an integer at 2^24, and every bias an integer at the scale of the accumulator it joins: 2^40 for dense1 and hidden_init, whose inputs are at 2^16, and 2^39 for every other layer, whose inputs are activations at 2^15. Each is computed from the float32 value’s bits alone, with no floating-point arithmetic:

A value that is not finite (e = 255), a weight whose integer does not fit i32, a missing array, an array of the wrong length, a block that starts at an input that is not a multiple of 4 or past the layer’s inputs, a group that names one block twice, or a record the file format refuses, makes the set fail to lower (model_mismatch, integer-operators §10.5). The pinned file does none of these.

4.5 Activations

Activations are integers at 2^15 (Q15), in [−32767, 32767]. tanh and the sigmoid are lut16 tables (integer-operators §5.6), read at 2^12 and 2^11. Their entries are this integer computation, not the functions’ exact values:

Every intermediate fits 128 bits. Serialized as their 65,536 entries in order, each a 16-bit two’s-complement little-endian integer, the tables’ SHA-256 are aea887ef206a10ea37bd31ef310a75c2ff05ca17df7edbbc15916969bccb4c22 (tanh) and 1fe2d7c6b3255127f612576093f2f50e9e13d88da546ad4c04de264e2bbc8c36 (sigmoid).

4.6 The graphs

dred-int/1 lowers the set to two WHG1 graphs (integer-operators §10), init and step, in which every tensor is [C, 1, 1]. Below, dense(x; L, s) is a conv with kh = kw = 1 and groups = 1 over x, with layer L’s integer weights (w_bytes 4), and an RQ with no multiplier, one shift s, L’s integer bias placed pre (b_bytes 8) and round half_up; T_tanh and T_sig are lut16 with the tables of §4.5; C(·) marks an output tensor whose policy is clamp [−32767, 32767] (every table input, and every GRU state); mul(a, b) is mul with an RQ of shift 15, no bias, half_up; [a, b] is concat; every other tensor’s policy is derived.

init. Input 0 is the initial state [50], policy clamp [−(2^31 − 1), 2^31 − 1].

  1. a = T_tanh(C(dense(IS; hidden_init, 28))) [128];
  2. s = T_tanh(C(dense(a; gru_init, 27))) [320];
  3. outputs: the five GRU states h_k = split(s, 64·(k − 1), 64), k = 1 … 5.

step. Inputs: the latent Z [26], policy clamp [−(2^31 − 1), 2^31 − 1]; the GRU states h_1 … h_5 [64]; the convolution memories c_1 … c_5 [32]; each of the last ten with policy clamp [−32767, 32767]. Then:

  1. t = T_tanh(C(dense(Z; dense1, 28))) [96].
  2. For k = 1 … 5, with x = t, h = h_k, I = gru<k>_input and U = gru<k>_recurrent:
    • the gates: g = T_sig(C(conv([x, h]))), [128], where the conv is dense with shift 28 whose output o < 128 has the weights of row o of I followed by those of row o of U, and the bias b_I[o] + b_U[o] (each converted by §4.4 on its own); z = split(g, 0, 64), r = split(g, 64, 64);
    • the candidate: p = dense(x; rows 128–191 of I, 19) + mul(r, dense(h; rows 128–191 of U, 19)) (add), at 2^20; then hc = T_tanh(C(rescale(p))), the rescale with one shift 8, no bias, half_up;
    • the state: h′ = C(hc + mul(z, h + rescale⁻(hc))), where rescale⁻ is rescale with one multiplier −1 (m_bytes 4), shift 0, no bias, floor, and each + is add. This is draft §2.2.2’s z·h + (1 − z)·hc, written so that each product has one rounding; with 0 ≤ z < 2^15 its value lies between hc and h, so the clamp changes nothing;
    • the GLU: u = mul(h′, T_sig(C(dense(h′; glu<k>, 28))));
    • t ← [t, u];
    • the causal convolution: c = T_tanh(C(dense(t; conv_dense<k>, 27))) [32] and v = T_tanh(C(dense([c_k, c]; conv<k>, 27))) [32];
    • t ← [t, v]; the new h_k is h′ and the new c_k is c.
  3. x = dense(t; output, 23) [80], at 2^16, policy clamp [−2^31, 2^31 − 1].

Outputs, in order: x, the five new GRU states, the five new memories.

Tensors are numbered as integer-operators §13.0 numbers a lowered graph (inputs first, then each operator’s output in operator order), every input declares max_h = max_w = 1, every exponent is none, and the operators are written in the order above (for the GRU: concat, the gates’ conv, lut16, the two splits, the candidate’s two convs, mul, add, rescale, lut16, then rescale⁻, add, mul, add). For the pinned set, the graphs’ identities (the SHA-256 of their WHG1 bytes) are 6527304e48bbd6c972fb41cb24ab5f387a3adee6f88347dfc8f10f47060e5c9d (init) and 4c76f2e5f6b2657b985aa171f7872fc18ae48b9419447e69cb3e52a3225b34d2 (step).

4.7 The driver

A payload is decoded as a sequence of graph runs:

  1. init on the state input (§4.3); its outputs are the GRU states. The memories are 0.
  2. For latent l = 0, 1, …, newest first: step on the latent’s input (§4.3), the GRU states and the memories; its first output x gives four feature vectors, and the others are the states and memories of the next latent.

The rows of the payload are those vectors, newest first: row 4l + j is x[20j], …, x[20j + 19] of latent l (draft §2.2.2: the four vectors of a latent are in reverse chronological order), and each row is 10 ms older than the row before it. Row 0 ends at the payload’s offset (§3.3 step 3). Each value is the feature at 2^16, an i32.

Decoding the first n latents gives the first 4n rows, the same integers whatever follows: the network runs newest first, so a row never depends on an older latent. A sink MAY stop after the rows it needs.

4.8 Profile and fabrics

Every operator of both graphs is in wai-ops/1-i32 (integer-operators §9.1), and both graphs’ certificates meet acc64 and not acc32: a 16-bit activation times a 32-bit weight, summed over up to 576 inputs, passes 32 bits. The registry’s ops member of wai.audio.opus.dred.int is {"set": "wai-ops/1", "profile": "acc64", "subset": "full", "lowering": "dred-int/1"}; the payload’s range decoder is RFC 6716’s and not a stage operator of integer-operators §5E, so the member has no stage. On a GPU, the reference implementation’s WGSL kernels (wai-ops-gpu) run both graphs at acc64, and wai-rs/tests/dred_exact_gpu.rs holds their outputs to the CPU’s graph by graph.

5. A stream under loss

5.1 The loss pattern

A loss pattern is a seed of 32 bytes and two thresholds, enter and stay, each an integer in 0 … 2^16. Packet n (from 0) draws u_n, the first two bytes, big-endian, of SHA-256("wai:dred-loss\x01" ‖ seed ‖ n as a big-endian u32). It is lost when u_n < enter and the packet before it was received (or n = 0), and when u_n < stay and the packet before it was lost.

5.2 Slots

A stream is a run of packets of one frame each, all of duration d (in units of 2.5 ms), so packet n starts at n·d. Each lost packet’s frame is two 10 ms slots, half 0 (the earlier) and half 1, and half h of frame m ends at E = m·d + 4·(h + 1). A maximal run of lost packets is recovered by the packet after it, when that packet was received and carries DRED whose payload is not refused (§3); then, with A = n·d + dred_offset the end of its row 0 (n the recovering packet), half h of frame m takes row r = ⌊(A − E) / 4⌋ of it when A − E ≥ 0 and r is less than four times the payload’s latent count. Otherwise the slot is not covered: no DRED rebuilds it.

5.3 The reconstruction buffer

The reconstruction of a stream is its slots in order (frame ascending, then half), as bytes: for each, the frame (u32), the half (u8) and 1 if it is covered or 0 if not (u8); for a covered one then the recovering packet (u32), the row (u32) and the row’s 20 features (i32 each); every integer little-endian. Its digest is SHA-256 over those bytes. The buffer of one run is the same over that run’s slots alone.

5.4 The record

A record of a reconstruction states:

5.5 Verification

A verifier is given the stream (each received packet as the object a live track carries it in: a WAI1 envelope of wai.audio.opus.packet, with nothing where a packet was lost), its loss pattern, the record, and the weights file. It checks, in order, and refuses at the first check that fails:

  1. the record’s weights_sha256 is the digest of §4.1 (weights_digest_mismatch);
  2. the packets the loss pattern loses are the record’s lost, and are exactly the packets the stream lacks (loss_pattern_mismatch);
  3. the slots §5.2 gives are the record’s slots (reconstruction_mismatch);
  4. the digest of the reconstruction §4 gives is the record’s output (reconstruction_mismatch).

A reconstruction that passes is the one every conforming sink gives: the profile admits no other.

6. Measurement

What the profile changes is the arithmetic: the same network, the same weights, at fixed point. wai-rs/tests/dred_exact_measure.rs measures how far that moves the features, on the draft’s own test vectors ([DRED-Test-Vectors]): all eight DRED bit files, 20 records each, every record’s latents decoded through the profile, and through the network in floating point (f64, from the same float32 weights, with tanh and the sigmoid computed exactly to f64 precision); and every packet of the eight packet files that carries DRED, its DRED decoded both ways. Each pair is compared by the draft’s feature comparison (its §4.1 and its tool [DRED-Compare]): per feature, the mean squared difference over the frames; total the square root of their sum, max of their largest, the pitch feature left out of both; pitch the mean absolute pitch difference over the frames the reference voices. The draft’s DRED decoding test passes at total ≤ 0.5, max ≤ 0.15 and pitch ≤ 0.02. Two figures are added: the largest absolute difference of any feature but pitch, and a band log-spectral distance. The 18 cepstral features are the orthonormal DCT-II of the log10 band energies (draft §2.1.3), so the inverse DCT of their difference is the difference of the log band energies, and ten times its root mean square over the bands is a distance in decibels for each frame; its mean over the frames and its largest are given.

The reference features are the test vectors’ own. “8-bit emulation” is the floating-point network computing each layer the weights file also holds 8-bit weights for as the reference implementation does when it reads them: each input rounded to ⌊0.5 + 127·x⌋, the 8-bit weights, each output scaled by its scale.

comparedframestotalmaxpitchlargest differenceband LSD mean (dB)band LSD max (dB)
integer, reference160000.13140.07670.004920.41390.29451.0034
float, reference160000.13140.07670.004920.41510.29441.0060
8-bit emulation, reference160000.08310.04580.002550.25420.18440.6929
integer, float160000.00210.00130.000110.00840.00480.0210
integer, float (packets)804520.00220.00130.000040.00850.00490.0208

What the table shows:

The last point was also checked once, informatively, on one arm64 host, by building the draft’s reference implementation ([DRED-Ref-Impl]) twice: in its default configuration, which reads the 8-bit weights, and with its float weights, which it computes in float32 with a rational approximation of tanh. Over the eight vectors, the default build’s features lie at total 0.090–0.096 from the test vectors and the float build’s at 0.131–0.136; the profile and the floating-point network each lie at 0.015–0.018 from the float build, and at 0.129–0.135 from the default build. The two builds differ from each other by about 0.13 (on the three vectors compared directly), and neither gives the test vectors’ features. Two builds of the draft’s own decoder on one machine, and the build that wrote the test vectors, give three different sets of features from the same latents; under the integer profile there is one.

7. Receipts and the synthesis lattice

7.1 Classes

In synthesis’s lattice (§3.2):

7.2 The presentation statement

A player that presents a reconstruction under the profile signs it in its log (synthesis §10.3): for each run of lost packets it presents, a present entry whose

That variant is the lowering wai.audio.opus.dred.int’s registration names. A reconstruct-session claim of the same decode may name its decoder entry’s path by it, by exact or by null: each is an exact path of a NeuralIntegerExact capability (jwp-receipts §2.4.12, variant). Any other term is not, and the entry is refused (session_variant_not_exact).

A verifier checks the log as synthesis §10.3 does (record_malformed, bad_key, bad_signature, player_chain_broken), then each present entry: its decoder, variant and tier are those above, its subject is the content hash of the object that recovers a run of the stream, and its output is the digest of that run’s buffer that §4 gives. Otherwise the entry states an output the object does not decode to (present_output_irreproducible, synthesis §9.2). The features are the statement’s subject because they are what the profile fixes; a player that also states the digest of its vocoder’s samples states its own output, which no other sink reproduces unless it runs the same vocoder, exactly.

8. Refusals

The codes this extension adds, each with where it is raised:

reasonraised at
packet_malformed§3.1
dred_latent_range§3.3 step 5
weights_digest_mismatch§4.1, §5.5 step 1
loss_pattern_mismatch§5.5 step 2
reconstruction_mismatch§5.5 steps 3 and 4

A set that fails to lower or load is refused model_mismatch (integer-operators §10.5). A verifier of a presentation statement also raises synthesis’s codes for a log (§7.2).

9. Conformance

live-conformance/dred/ holds the corpus, written from fixed seeds by wai_dred_vectors gen with the weights file of §4.1, which it names and does not hold: vectors.json, its README, and fetch.sh. It has:

Every packet of the corpus is written by its generator: its DRED indices are drawn from the draft’s own distributions, by decoding a seeded byte stream with §3.3’s coefficient rule at q0, and requantized to each chunk’s quantizer (x·s_q / s_q0, rounded half up, where q codes the coefficient). The primary frames are empty (length 0, RFC 6716 §3.2.1). No recorded speech is in the corpus.

Feature equivalence. For each payload vector and each case, a conforming implementation reaches the outcome the vector states, and for an accepted one, the same digests, rows and statements, byte for byte.

On every fabric. wai-rs/tests/dred_exact_gpu.rs decodes the corpus’s payloads with every graph on each GPU adapter found and holds the output to the CPU’s.

10. Security and privacy considerations