LC3 Tables and Constants Reference

 

LC3 Tables and Constants Reference
Chapter 3, Section 3.7 — Band Tables, MDCT Windows, SNS Codebooks, TNS, LTPF, and Spectral Tables
Chapter
3 — Section 3.7
Subsections
3.7.1 to 3.7.7
Level
Reference

Section 3.7 contains all the pre-computed tables that the LC3 encoder and decoder reference during processing. These tables are not generated at runtime — they are fixed constants baked into every conformant implementation. This tutorial explains what each table is, how many entries it has, how it is indexed, and which algorithm steps use it. The actual numeric values are in the LC3 spec PDF (pages 89–221) and are too large to fully reproduce here, but all sizes, shapes, and usage references are covered completely.

Keywords

Band Index Tables Ifs LD-MDCT Windows SNS Codebooks LFCB HFCB MPVQ Offsets TNS Tables LTPF Filter Tables Arithmetic Coder Tables

3.7.1 Band Index Tables Ifs — 10 ms Frame Duration

These tables map band number b to the starting MDCT coefficient index for that band. Ifs(b) is the first coefficient in band b; Ifs(b+1)−1 is the last. Used by energy estimation (3.3.4.4), SNS analysis (3.3.7.2), bandwidth detector (3.3.5.2), and SNS spectral shaping (3.3.7.5 / 3.4.7.4).

Table Name Sampling Rate Size (entries) NF Nb (bands) Last entry (=NE)
I_8000[65] 8 kHz 65 80 64 80
I_16000[65] 16 kHz 65 160 64 160
I_24000[65] 24 kHz 65 240 64 240
I_32000[65] 32 kHz 65 320 64 320
I_48000[65] 44.1/48 kHz 65 480 64 400 (NE, not NF)

For 8 kHz (NF=80, NE=80): all 80 MDCT coefficients map 1:1 to bands at the low end, then progressively wider bands at high frequencies. For 48 kHz, only 400 of the 480 MDCT coefficients are encoded (NE=400), so the last entry of I_48000 is 400.

3.7.2 Band Index Tables Ifs — 7.5 ms Frame Duration

Same structure as the 10 ms tables but for 7.5 ms frame sizes. Notable exception: 8 kHz at 7.5 ms has NF=60 and Nb=60 (not 64) — the only configuration in the spec where Nb ≠ 64.

Table Name Sampling Rate Size NF Nb
I_8000_7.5ms[61] 8 kHz 61 60 60
I_16000_7.5ms[65] 16 kHz 65 120 64
I_24000_7.5ms[65] 24 kHz 65 180 64
I_32000_7.5ms[65] 32 kHz 65 240 64
I_48000_7.5ms[65] 44.1/48 kHz 65 360 64

3.7.3 LD-MDCT Windows

The LD-MDCT window coefficients are pre-computed from an offline optimization. They cannot be derived mathematically — you must use the exact values from the spec. Each window has length 2×NF (the MDCT operates on a 2×NF buffer). The last Z entries are exactly zero (the leading zeros that create the look-ahead delay).

Window Name Frame NF Window Size (2×NF) Z (trailing zeros) Section
w_N80[160] 10ms, 8kHz 80 160 30 3.7.3.1.1
w_N160[320] 10ms, 16kHz 160 320 60 3.7.3.1.2
w_N240[480] 10ms, 24kHz 240 480 90 3.7.3.1.3
w_N320[640] 10ms, 32kHz 320 640 120 3.7.3.1.4
w_N480[960] 10ms, 48kHz 480 960 180 3.7.3.1.5
w_N60[120] 7.5ms, 8kHz 60 120 14 3.7.3.2.1
w_N120[240] 7.5ms, 16kHz 120 240 28 3.7.3.2.2
w_N180[360] 7.5ms, 24kHz 180 360 42 3.7.3.2.3
w_N240_7.5ms[480] 7.5ms, 32kHz 240 480 56 3.7.3.2.4
w_N360[720] 7.5ms, 48kHz 360 720 84 3.7.3.2.5

All window values are double precision (64-bit) floats. The window can have amplitude > 1.0 in some regions — fixed-point implementations must account for this carefully to avoid overflow. At the decoder, the same window is used flipped: w(2N−1−n) instead of w(n).

3.7.4 SNS Quantization Tables

The SNS section uses several pre-computed tables:

Table Size Used By Description
LFCB[32][8] 32 × 8 = 256 doubles 3.3.7.3.2 Stage 1 Low-frequency codebook. 32 entries of dimension 8, trained offline for lower 8 scale factors. Indexed by ind_LF (5 bits).
HFCB[32][8] 32 × 8 = 256 doubles 3.3.7.3.2 Stage 1 High-frequency codebook. Same structure. Indexed by ind_HF (5 bits).
D[16][16] 256 doubles 3.3.7.3.3 Stage 2 16×16 orthogonal DCT rotation matrix used for Stage 2 shape analysis (DCT) and synthesis (IDCT). D^T × D = I. Stored column-wise.
MPVQ_offsets[10][11] 10 × 11 = 110 uint32 3.3.7.3.3.8 Enumeration
3.4.7.2.2.1 De-enum
Offset table for MPVQ enumeration/de-enumeration. Entry (n, k) = number of PVQ vectors of dimension n+1 with L1-norm k. Defined recursively by Eq. 57.
sns_vq_reg_adj_gains[2] 2 values 3.3.7.3.3.6 Gain sets Adjustment gain values for shape_j=0 (regular). 2 levels indexed by gain_i = 0 or 1.
sns_vq_reg_lf_adj_gains[4] 4 values 3.3.7.3.3.6 Gain levels for shape_j=1 (regular_lf). 4 levels.
sns_vq_near_adj_gains[4] 4 values 3.3.7.3.3.6 Gain levels for shape_j=2 (outlier_near). 4 levels.
sns_vq_far_adj_gains[8] 8 values 3.3.7.3.3.6 Gain levels for shape_j=3 (outlier_far). 8 levels.

3.7.5 TNS Tables

TNS uses two arithmetic coding tables for transmitting the reflection coefficient indices:

Table Size Indexing Used By
ac_tns_order_bits[2][8] 2 × 8 = 16 entries [tns_lpc_weighting][rcorder−1] 3.3.8.3 (Eq 76): fractional bit cost (×2048) for transmitting the filter order.
ac_tns_coef_bits[8][17] 8 × 17 = 136 entries [k][rci(k,f)] 3.3.8.3 (Eq 77): fractional bit cost for each quantized reflection coefficient index (0–16). Varies by coefficient position k (0–7).
ac_tns_order_cumfreq[2][9]
ac_tns_order_freq[2][9]
2 × 9 each [tns_lpc_weighting][rcorder] 3.3.13.4 arithmetic encoder / 3.4.2.5 decoder: cumulative and symbol frequencies for the order symbol.
ac_tns_coef_cumfreq[8][17]
ac_tns_coef_freq[8][17]
8 × 17 each [k][rci] Arithmetic encoder/decoder: cumulative and symbol frequencies for each reflection coefficient index per coefficient position k.

3.7.6 LTPF Tables

Table Size Used By Description
tab_resamp_filter[240] 240 doubles 3.3.9.3 (Eq 79) FIR low-pass filter impulse response for polyphase resampling to 12.8 kHz. h12.8(n) = tab_resamp_filter[n+119], n = −119..120.
tab_ltpf_interp_R[32] 32 doubles 3.3.9.7 (Eq 100) FIR filter for 1/4-sample interpolation of the autocorrelation R12.8, used for fractional pitch-lag determination. h4(n) = tab_ltpf_interp_R[n+15], n = −15..16.
tab_ltpf_interp_x12k8[16] 16 doubles 3.3.9.8 (Eq 105) FIR filter for interpolating the 12.8 kHz signal at fractional pitch lag. hi(n) = tab_ltpf_interp_x12k8[n+7], n = −7..8.
tab_ltpf_num_fs[4][Lnum+1] 4 rows × variable column count 3.4.9.4 (Eq 146) Numerator FIR coefficients (before gain scaling) for the LTPF decoder IIR filter. Indexed by [gain_ind][k], k = 0..Lnum. There is one sub-table per sampling rate.
tab_ltpf_den_fs[4][Lden+1] 4 rows × variable column count 3.4.9.4 (Eq 147) Denominator FIR coefficients for the LTPF decoder filter. Indexed by [pfr][k], k = 0..Lden. pfr = 0..3 (fractional pitch lag quarter-sample). One sub-table per sampling rate.

3.7.7 Spectral Data Tables (Arithmetic Coder)

The arithmetic coder uses context-dependent probability tables for encoding and decoding spectral 2-tuples. These are the largest tables in the spec (many kilobytes each).

Table Size Used By Description
ac_spec_lookup[4096] 4096 uint16 entries 3.3.10.4, 3.3.13.4, 3.4.2.5 Maps context index t (0–1023) + level (0–3) to a probability table index pki. Indexed as ac_spec_lookup[t + lev×1024]. Returns the index into the cumfreq/freq tables.
ac_spec_bits[N_PKIS][17] N_PKIs × 17 uint16 3.3.10.4 bit estimation Fractional bit costs (×2048) for each symbol (0–16) under each probability model pki. Entry [pki][16] is the escape symbol cost.
ac_spec_cumfreq[N_PKIS][17] N_PKIs × 17 uint16 3.3.13.4 encoder,
3.4.2.5 decoder
Cumulative frequency table for the range coder. cumfreq[sym] = sum of freq[0..sym−1]. Required by ac_encode and ac_decode.
ac_spec_freq[N_PKIS][17] N_PKIs × 17 uint16 3.3.13.4 encoder,
3.4.2.5 decoder
Individual symbol frequency for the range coder. All freq[pki][0..16] sum to 1024 (= 2^10) for each pki. The sum property ensures the range coder operates correctly.

N_PKIs is the number of distinct probability models in the system. The context variable c in the encoder and decoder tracks which probability model to use for the current 2-tuple based on the previous encoding history.

Implementation Notes

When implementing LC3 from scratch (rather than using liblc3), these are the key points about table management:

  • Band tables: Select the correct table for your (fs, Nms) combination at session init time. No computation needed per frame.
  • MDCT windows: Select based on NF. The same window is used for both encoder analysis and decoder synthesis (flipped). Values are read-only constants.
  • SNS codebooks (LFCB, HFCB, D matrix): Used in both encoder and decoder Stage 1/2 processing. Values are read-only; they are not modified per frame.
  • MPVQ_offsets: Can be recomputed from the recursive formula in Eq. 57, but the pre-computed table is recommended for speed.
  • TNS and spectral tables: Large lookup tables that should be compiled as static const arrays. The arithmetic coder tables are the most performance-critical — they are accessed inside the inner encoding loop for every 2-tuple.
  • LTPF filter tables: Selected per-frame based on sampling rate and gain_ind/pfr. Small lookup — 4 × a few coefficients.
/* Session init: select tables once based on (fs, Nms) */
const int *Ifs;       /* Band index table pointer */
const double *wN;     /* MDCT window pointer      */
int NF, NE, Nb, Z;

switch(fs) {
    case 48000: Ifs = I_48000; wN = w_N480; NF=480; NE=400; Nb=64; Z=180; break;
    case 32000: Ifs = I_32000; wN = w_N320; NF=320; NE=320; Nb=64; Z=120; break;
    case 24000: Ifs = I_24000; wN = w_N240; NF=240; NE=240; Nb=64; Z=90;  break;
    case 16000: Ifs = I_16000; wN = w_N160; NF=160; NE=160; Nb=64; Z=60;  break;
    case 8000:  Ifs = I_8000;  wN = w_N80;  NF=80;  NE=80;  Nb=64; Z=30;  break;
    /* 7.5ms variants: use corresponding _7.5ms tables */
}
/* Tables are now ready for all per-frame encode/decode calls */

LC3 Tutorial Series Complete!

You have completed all 17 tutorials covering every section of Chapter 2 and Chapter 3 of the LC3 Specification v1.0. You now have a complete understanding of how LC3 encodes and decodes audio for Bluetooth LE Audio.

← Back to All Tutorials Start from Tutorial 1

Leave a Reply

Your email address will not be published. Required fields are marked *