Also known as: LSP codebook, LSP split-VQ, line spectral pair codebook
The ACELP LSP codebooks are the split-vector-quantizer tables that the TETRA ACELP decoder uses to turn a handful of transmitted indices back into the ten line spectral pairs (LSPs) that describe a speech frame’s short-term spectral envelope.1 LSPs are simply an alternate, quantization-friendly representation of the linear-predictive-coding filter coefficients — living in the cosine domain on the open interval (−1, 1), where small errors stay bounded and an ordering property guarantees the reconstructed filter is stable.
Why split the vector
A single joint codebook covering all ten LSPs would need an impractically large table — an N-bit index demands 2^N stored vectors, and enough resolution for ten dimensions would be astronomical. Split-vector quantization slices the ten-dimensional LSP vector into smaller sub-vectors quantized independently, trading a little coding efficiency for a table small enough to store and search. TETRA’s ACELP uses a split-3 design: the first three LSPs, the middle three, and the final four are each quantized with their own codebook, for 8 + 9 + 9 = 26 bits of LSP information per frame. Grouping neighbouring LSPs together preserves the local correlation between adjacent spectral lines that carries most of the perceptual information.
The three codebooks
GopherTrunk stores the ETSI reference tables as lspDico1, lspDico2, and lspDico3 in
internal/voice/acelp/lsp_tables.go. Each row is a sub-vector of signed Q15 fixed-point values
in the cosine domain:
| Codebook | Index width | Entries | LSPs per row | Flat size |
|---|---|---|---|---|
lspDico1 |
8 bits | 256 | 3 (LSP 1–3) | 768 int16 |
lspDico2 |
9 bits | 512 | 3 (LSP 4–6) | 1536 int16 |
lspDico3 |
9 bits | 512 | 4 (LSP 7–10) | 2048 int16 |
The values are stored in Q15 here, one detail worth flagging: the ETSI reference keeps the
table in Q14 and doubles each value as it loads, and GopherTrunk folds that doubling directly
into the constants so the decoder can index the table without a scaling step. Getting the
fixed-point scale wrong at this stage would tilt
the whole reconstructed envelope. These are pure quantization data —
fixed constants derived from the reference codec, consumed by the decoder’s dLsp334 routine.
Reconstructing the envelope
For each frame the decoder reads the three indices, looks up the three sub-vectors, and
concatenates them into a ten-element LSP vector. That vector is converted from line spectral
pairs back to LPC coefficients, which define the all-pole synthesis filter 1/A(z). Exciting
that filter with the pitch and innovation contributions from the
adaptive and algebraic codebooks — scaled by the
dequantized gains — produces the reconstructed speech.
The LSP codebooks therefore fix the shape of the spectrum (the formant structure that makes a
vowel sound like that vowel), while the excitation codebooks supply its fine structure.
Because LSPs move slowly and smoothly frame to frame, a single mis-decoded index tends to produce an audible but brief spectral glitch rather than a catastrophic failure — the ordering property still yields a stable filter, so the synthesizer never diverges. This graceful behaviour under channel errors is one reason LSP quantization is the standard front end for CELP-family coders across cellular and land-mobile radio.
Relevance to SDR
For a scanner, the LSP codebooks are decode-only lookup tables: TETRA voice arrives as already-quantized indices, and reconstructing intelligible audio just requires the correct table values, scale, and ordering. GopherTrunk’s copies are validated as part of the wider end-to-end conformance of the TETRA ACELP path against the ETSI reference codec, so a decoded call’s spectral envelope matches the reference decoder rather than merely sounding plausible.
Sources
-
Line spectral pairs — Wikipedia, on the LSP representation of LPC filters and why it is used for robust quantization. ↩