# HG changeset patch # User Mychaela Falconia # Date 1683516520 0 # Node ID 4c7d0dc1eecbd688686b1813fd98f67b4a3cc8ff # Parent 0ee1a66c1846137e10e151c3ebab62d5b3be6ea3 doc/PCM8-conversions: finish encoding description diff -r 0ee1a66c1846 -r 4c7d0dc1eecb doc/PCM8-conversions --- a/doc/PCM8-conversions Mon May 08 00:45:26 2023 +0000 +++ b/doc/PCM8-conversions Mon May 08 03:28:40 2023 +0000 @@ -101,3 +101,70 @@ 2's complement input), there are no less than 3 different ways to implement this encoder! +Let us now look at the 3 different ways of encoding a 14-bit or 16-bit 2's +complement linear PCM input to G.711 mu-law. In this analysis we shall use +14-bit notation, with 2's complement inputs contained in the domain +[-8192,8191]. The difference between the 3 identified ways of mapping from this +domain to mu-law have to do with boundaries between quantization intervals. +Tables 2a and 2b in the G.711 spec list all defined quantization intervals and +all decision values that mark boundaries between them; here is a digested form +of the beginning of the canonical quantization table for either side of zero: + +Quantization interval Quantized value +(range of magnitudes) (absolute) +--------------------------------------- +0-1 0 +1-3 2 +3-5 4 +... +29-31 30 +31-35 33 +35-39 37 +... +91-95 93 +95-103 99 +... + +This canonical quantization table is defined in terms of absolute values, and +is therefore fully symmetric around zero. A careful look at the above table +raises a question: which quantization interval (and thus which PCMU octet +output) should be selected if the input value to the encoder has a magnitude +exactly equal to one of the threshold points, or decision values as they are +officially called? In other words, what should the encoder do if the magnitude +of the 14-bit input value equals 1, 3, 5, ..., 31, 35, 39 etc? The answer to +this question is where the 3 candidate mappings under our consideration differ: + +* The "compress" function of G.726 operating in mu-law mode selects the higher + (in absolute value) quantization interval at every decision value threshold, + on both sides of zero: see Table 15/G.726. PCMU octet 0x7F (meaning -0) will + never be emitted by this version, and an input sequence of -3, -2, -1, 0, 1, + 2, 3 will map to quantized values -4, -2, -2, 0, 2, 2, 4. + +* The ulaw_compress() function in G.191 STL behaves like the G.726 version for + positive values, but selects the smaller-absolute-value quantization interval + for negative inputs. Given the same input sequence as above, the output will + correspond to quantized values -2, -2, -0, 0, 2, 2, 4. (Quantized value -0 + is PCMU octet 0x7F.) + +* The s2u[] table in toast_ulaw.c in libgsm source is flat-out wrong and should + not be used or considered further (and because those authors did not include + the source for whatever program they used to generate their broken s2u[] and + u2s[] tables, we have no way to really analyze them), but one CAN construct a + new table for the same function, using the upper 13 bits of 16-bit 2's + complement input to generate PCMU output - see our dev/s2u-regen.c program + and its output table in dev/s2u-regen.out. The resulting mapping is + "mirrored" around zero compared to G.191 STL ulaw_compress(): for the same + input sequence as in the previous two examples, the output will correspond to + quantized values -4, -2, -2, 0, 0, 2, 2. Just like the G.726 version, this + look-up table version will never emit PCMU octet 0x7F for -0. + +It is important to note that all GSM speech decoders produce 2's complement +outputs that are only 13 bits wide, not 14 - therefore, when the input to the +G.711 encoder comes from the output of a GSM speech decoder, the difference +between all 3 alternatives listed above is masked, with all 3 producing +identical output. + +For production software, our (Themyscira) recommendation is to use look-up +tables (dev/s2a-regen.out and dev/s2u-regen.out) for both A-law and mu-law +encoding, using the upper 12 bits from 16-bit 2's complement input for A-law +encoding and the upper 13 bits for mu-law encoding.