Also known as: TETRA (K a) interleaver, TETRA block interleaving
The TETRA block interleaver reorders a channel’s coded bits before transmission so that a physical
burst of errors on the air is spread into isolated single errors the convolutional decoder
can then correct.1 TETRA uses a multiplicative interleaver: the bit at
1-indexed input position i is written to output position k = 1 + ((a·i) mod K), where K is the block
length and a is a channel-specific multiplier chosen coprime with K so the mapping is a full permutation.2
Because a fading channel damages adjacent symbols together, scattering them across the block is what makes
the downstream FEC effective — a run of errors on air becomes one error per codeword after de-interleaving.
The (K, a) rule
The interleaver is defined by a single congruence. For each input index i = 1..K, the output index is
k = 1 + ((a·i) mod K); the de-interleaver inverts it by walking i and reading back from k. Choosing a
coprime with K guarantees the map is a bijection, so the round-trip is the identity. Each logical channel
carries its own (K, a) pair, matched to its block length:
// internal/radio/framing/interleave_tetra.go — ETSI EN 300 392-2 §8.3.1.
const (
InterleaveKBSCH = 120; InterleaveABSCH = 11 // BSCH §8.3.1.2
InterleaveKSCHHD = 216; InterleaveASCHHD = 101 // SCH/HD, BNCH, STCH §8.3.1.4.1
InterleaveKSCHHU = 168; InterleaveASCHHU = 13 // SCH/HU §8.3.1.4.3
InterleaveKSCHF = 432; InterleaveASCHF = 103 // SCH/F §8.3.1.4.5
)
The BSCH interleaves 120 bits with a = 11; SCH/HD, BNCH, and STCH share a 216-bit block with a = 101;
SCH/HU uses (168, 13); and the full-slot SCH/F uses (432, 103). Because a good multiplier scatters bits
far apart — a near a fraction of K maximises the minimum separation — the pairs are chosen for the
interleaving distance they produce, not arbitrarily.
Position in the chain
Interleaving is one step in TETRA’s type-1-through-type-5 bit-processing chain. On the transmit side the order is: encode with the RCPC code (type-1 → type-2 → type-3), interleave (type-3 → type-4), then scramble (type-4 → type-5). A receiver reverses it: descramble, de-interleave, then Viterbi-decode. Getting the interleaver right matters because it sits between the convolutional decoder and the channel — an incorrect permutation leaves the decoder facing clustered errors it was never designed to handle, so the FEC fails even on a clean signal.
Relevance to SDR
internal/radio/framing/interleave_tetra.go implements BlockInterleaveTetra / BlockDeinterleaveTetra and
exports the four (K, a) constants, one per logical channel. Callers pass
the matching K and a for the channel they are decoding, so the same tiny permutation function serves the
BSCH, the half-slot signalling channels, and the full-slot SCH/F alike. It is a small piece of code whose
correctness is load-bearing: paired with the RCPC decoder and the scrambler, it is what lets a marginal TETRA
burst survive the fading that would otherwise defeat the convolutional code outright.
Sources
-
Burst error-correcting code — Wikipedia, on why spreading burst errors lets a random-error code correct them. ↩
-
Interleaving — Wikipedia, on reordering data so that contiguous damage becomes distributed. ↩