Also known as: TETRA RCPC, rate-compatible punctured convolutional code, TETRA convolutional code
TETRA RCPC codes are the rate-compatible punctured convolutional codes that carry forward error correction on every TETRA logical channel.1 TETRA uses two 16-state (constraint length K=5) mother codes: a rate-1/3 code for the speech traffic channel (EN 300 395-2 §5.4.3) and a rate-1/4 code for the signalling channels (EN 300 392-2 §8.2.3.1). A single low-rate mother code is punctured — some of its output bits are deleted — to reach each channel’s target rate, and the decoder fills the deleted positions with erasures and runs one common Viterbi survivor search.2
The mother codes
Both mother codes share the same 16-state structure but differ in output count and polynomials. GopherTrunk stores them as the per-stage XOR taps derived from the generator polynomials:
// Traffic (TCH) mother, K=5 rate 1/3 — EN 300 395-2 §5.4.3.
// G1 = 0x1F, G2 = 0x1B, G3 = 0x15
g1 = bit ^ d1 ^ d2 ^ d3 ^ d4 // 1 + D + D^2 + D^3 + D^4
g2 = bit ^ d1 ^ d3 ^ d4 // 1 + D + D^3 + D^4
g3 = bit ^ d2 ^ d4 // 1 + D^2 + D^4
// Signalling mother, K=5 rate 1/4 — EN 300 392-2 §8.2.3.1.
// G1 = 0x13, G2 = 0x1D, G3 = 0x17, G4 = 0x1B
Each block is flushed with K−1 = 4 zero tail bits so the Viterbi survivor is forced to terminal state 0. The rate-1/3 code protects speech; the rate-1/4 code, one output stream stronger, protects the BSCH, SCH/HD, BNCH, STCH, SCH/HU, and SCH/F signalling channels.
Rate compatibility and puncturing
Rate-compatible means the higher-rate patterns are subsets of the lower-rate ones: a bit kept at a
strong (low) rate is also kept at every weaker (higher) rate, so one encoder and one decoder serve the whole
family and a channel can even change rate mid-stream without swapping codecs. Puncturing follows the
§5.4.3.2 formula — for a period t and pattern puncture[], the kept mother-code index is
k = period·((j−1) div t) + puncture[(j−1) mod t] (1-indexed). The traffic channel’s class-1 bits use the
rate-2/3 pattern {1, 2, 4} (period 6); its class-2 bits use the rate-8/18 pattern
{1,2,3,4,5,7,8,10,11} (period 12); and under frame-stealing the rate-8/17 pattern (period 24) applies.
The signalling code carries its own family — a rate-2/3 pattern {1, 2, 5} used by every standard signalling
channel, plus stronger and special 292/432 and 148/432 rates.
Relevance to SDR
internal/radio/framing/rcpc_tetra.go and rcpc_tetra_sig.go implement the two mother codes, their
hard-decision 16-state Viterbi decoders, and the puncture/depuncture helpers, with the puncture patterns
exported as spec-verbatim tables. Depuncturing fills a mother-length buffer with a DepunctureMark erasure
at each deleted position, so the Viterbi metric simply skips those. Soft-decision variants exist so the
receiver’s per-symbol confidences flow through, roughly doubling traffic yield on marginal captures. Chained
after the block interleaver and scrambler,
these codes are what let a real TETRA channel survive a fading mobile path.
Sources
-
Convolutional code — Wikipedia, on shift-register codes and their generator polynomials. ↩
-
Punctured code — Wikipedia, on deleting output bits to raise a code’s rate while sharing one decoder. ↩