annotate doc/PCM8-conversions @ 242:f081a6850fb5

libgsmfrp: new refined implementation The previous implementation exhibited the following defects, which are now fixed: 1) The last received valid SID was cached forever for the purpose of handling future invalid SIDs - we could have received some valid SID ages ago, then lots of speech or NO_DATA, and if we then get an invalid SID, we would resurrect the last valid SID from ancient history - a bad design. In our new design, we handle invalid SID based on the current state, much like BFI. 2) GSM 06.11 spec says clearly that after the second lost SID (received BFI=1 && TAF=1 in CN state) we need to gradually decrease the output level, rather than jump directly to emitting silence frames - we previously failed to implement such logic. 3) Per GSM 06.12 section 5.2, Xmaxc should be the same in all 4 subframes in a SID frame. What should we do if we receive an otherwise valid SID frame with different Xmaxc? Our previous approach would replicate this Xmaxc oddity in every subsequent generated CN frame, which is rather bad. In our new design, the very first CN frame (which can be seen as a transformation of the SID frame itself) retains the original 4 distinct Xmaxc, but all subsequent CN frames are based on the Xmaxc from the last subframe of the most recent SID.
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 09 May 2023 05:16:31 +0000
parents e4a4bf11f37c
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
235
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
1 What is the authoritatively correct, officially endorsed bidirectional mapping
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
2 between G.711 A-law and mu-law encodings on one side and 16-bit 2's complement
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
3 linear PCM on the other side? Surprisingly, there is no official answer to this
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
4 problem anywhere in the specs! Instead the specs provide the following partial
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
5 answers:
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
6
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
7 * The G.711 spec itself provides one mapping from A-law code octets to linear
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
8 numeric values in range [-4032,4032] and another mapping from mu-law code
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
9 octets to linear numeric values in range [-8031,8031]. The output from each
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
10 of these mapping is given in "pure mathematical" form, without specifying any
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
11 bit-level encoding, and furthermore, mu-law decoder output in its pure
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
12 "conceptual" form has both +0 and -0 values. (The same signed zero problem
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
13 does not occur in A-law because it's a mid-riser code rather than mid-tread,
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
14 and thus has no quantized values equal to 0.)
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
15
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
16 * If one takes the "pure mathematical" output from the spec-prescribed G.711
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
17 decoder and represents it in 2's complement form, squashing +0 and -0 outputs
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
18 from the canonical mu-law decoder into "plain 0" at this step, the result is
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
19 a 13 bits wide 2's complement value for A-law decoding and a 14 bits wide 2's
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
20 complement value for mu-law.
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
21
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
22 * All GSM speech encoders take 13-bit 2's complement linear PCM samples as their
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
23 input. How should this 13-bit GSM codec input be derived from A-law or mu-law
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
24 code octets? GSM specs refer to ITU's G.726 spec for ADPCM - it just so
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
25 happens that inside the ADPCM algorithm of G.726 (a totally unrelated codec of
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
26 no relevance to GSM codec work outside of this reference) there is a pair of
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
27 functions for expanding A-law and mu-law to linear PCM and compressing linear
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
28 PCM back to A-law or mu-law.
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
29
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
30 * Following this obscure G.726 reference, we eventually conclude that in the
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
31 case of A-law, GSM specs call for the obvious treatment: take the "natural"
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
32 output from the canonical A-law decoder, represent it in 2's complement form,
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
33 the result is 13 bits wide, and just feed that 13-bit 2's complement form to
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
34 the input of GSM speech encoders. However, in the case of mu-law the
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
35 "natural" G.711 decoder output is one sign bit plus 13 bits of magnitude,
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
36 requiring 14 bits in 2's complement representation - and none of the specs I
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
37 could find says anything about exactly how this 14-bit input should be reduced
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
38 to 13 bits for feeding to GSM speech encoders. Canonical C implementations
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
39 of all GSM speech encoders take their input in 16-bit words and clear the 3
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
40 least significant bits as their first step; if the 14-bit mu-law decoder
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
41 output is represented in 16-bit words by padding 2 zero bits on the right and
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
42 this output is then fed to GSM speech encoder functions, the end effect is
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
43 that the least-significant bit of the 14-bit decoder output is simply cut off.
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
44 This form of mu-law-to-GSM transcoder implementation is consistent with
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
45 TESTx-U.INP and TESTx-U.COD sequences provided in the GSM 06.54 package for
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
46 EFR.
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
47
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
48 Based on the above considerations, we have our answer for how we should convert
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
49 from G.711 to 16-bit 2's complement linear PCM:
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
50
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
51 * For A-law, we emit the "natural" output in 13-bit 2's complement form and
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
52 append 3 zero bits on the right; this transformation is fully lossless.
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
53
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
54 * For mu-law, we emit the "natural" output in 14-bit 2's complement form and
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
55 append 2 zero bits on the right. This transformation is almost lossless,
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
56 with just one exception: the "pure" decoder's -0 output (resulting from PCMU
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
57 octet 0x7F) is squashed to "plain 0", and will be re-emitted as PCMU octet
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
58 0xFF rather than 0x7F on subsequent re-encoding to G.711 PCMU.
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
59
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
60 For anyone needing a G.711 to 16-bit linear PCM decoder, the present package
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
61 provides ready-made decoding tables (following the above rules) in
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
62 dev/a2s-regen.out and dev/u2s-regen.out, generated by dev/a2s-regen.c and
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
63 dev/u2s-regen.c programs.
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
64
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
65 Now for the opposite problem: what is the most correct way to compress 16-bit
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
66 2's complement linear PCM to A-law or mu-law? In this direction the official
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
67 specs leave even more ambiguity than in the G.711 decoding direction:
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
68
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
69 * The G.711 spec itself says: "The conversion to A-law or mu-law values from
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
70 uniform PCM values corresponding to the decision values, is left to the
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
71 individual equipment specification." The specific implementation used in the
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
72 guts of G.726 ADPCM codec is referred to only as a non-normative example.
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
73
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
74 * GSM specs likewise refer to this G.726 section 4.2.8 (for compression of
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
75 13-bit speech decoder output to G.711) with language that suggests a
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
76 non-normative example.
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
77
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
78 After painstakingly comparing the C implementation of G.726 in the ITU-T G.191
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
79 STL against the language of G.726 spec itself and convincing myself that they
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
80 really do match, and then painstakingly comparing this approach against the one
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
81 implemented in the same G.191 STL for G.711 in alaw_compress() and
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
82 ulaw_compress() and against the table lookup method implemented in libgsm/toast
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
83 (my first reference, before I went down the rabbit hole of tracking down
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
84 official specs), I reached the following conclusions:
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
85
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
86 * For A-law encoding all 3 parties (G.191 STL alaw_compress() function, G.726
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
87 "compress" block and toast_alaw.c) agree on the same mapping. In this
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
88 mapping only the most significant 12 bits of the 2's complement input word
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
89 (equivalent to one sign bit and 11 bits of magnitude) are relevant, leading
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
90 to the following two interesting properties:
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
91
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
92 - the least-significant bit of GSM speech decoder output is always discarded
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
93 when converting to A-law;
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
94
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
95 - conversion can be easily implemented with a 4096-byte look-up table based
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
96 on the upper 12 bits of input, exactly as was done in toast_alaw.c in the
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
97 venerable libgsm source.
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
98
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
99 * Mu-law encoding is the real hair-raiser: if the input to the to-be-implemented
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
100 encoder has 14 or more bits (including the most practical problem of 16-bit
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
101 2's complement input), there are no less than 3 different ways to implement
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
102 this encoder!
0ee1a66c1846 doc/PCM8-conversions: beginning of document
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
103
236
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
104 Let us now look at the 3 different ways of encoding a 14-bit or 16-bit 2's
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
105 complement linear PCM input to G.711 mu-law. In this analysis we shall use
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
106 14-bit notation, with 2's complement inputs contained in the domain
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
107 [-8192,8191]. The difference between the 3 identified ways of mapping from this
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
108 domain to mu-law have to do with boundaries between quantization intervals.
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
109 Tables 2a and 2b in the G.711 spec list all defined quantization intervals and
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
110 all decision values that mark boundaries between them; here is a digested form
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
111 of the beginning of the canonical quantization table for either side of zero:
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
112
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
113 Quantization interval Quantized value
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
114 (range of magnitudes) (absolute)
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
115 ---------------------------------------
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
116 0-1 0
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
117 1-3 2
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
118 3-5 4
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
119 ...
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
120 29-31 30
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
121 31-35 33
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
122 35-39 37
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
123 ...
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
124 91-95 93
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
125 95-103 99
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
126 ...
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
127
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
128 This canonical quantization table is defined in terms of absolute values, and
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
129 is therefore fully symmetric around zero. A careful look at the above table
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
130 raises a question: which quantization interval (and thus which PCMU octet
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
131 output) should be selected if the input value to the encoder has a magnitude
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
132 exactly equal to one of the threshold points, or decision values as they are
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
133 officially called? In other words, what should the encoder do if the magnitude
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
134 of the 14-bit input value equals 1, 3, 5, ..., 31, 35, 39 etc? The answer to
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
135 this question is where the 3 candidate mappings under our consideration differ:
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
136
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
137 * The "compress" function of G.726 operating in mu-law mode selects the higher
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
138 (in absolute value) quantization interval at every decision value threshold,
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
139 on both sides of zero: see Table 15/G.726. PCMU octet 0x7F (meaning -0) will
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
140 never be emitted by this version, and an input sequence of -3, -2, -1, 0, 1,
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
141 2, 3 will map to quantized values -4, -2, -2, 0, 2, 2, 4.
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
142
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
143 * The ulaw_compress() function in G.191 STL behaves like the G.726 version for
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
144 positive values, but selects the smaller-absolute-value quantization interval
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
145 for negative inputs. Given the same input sequence as above, the output will
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
146 correspond to quantized values -2, -2, -0, 0, 2, 2, 4. (Quantized value -0
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
147 is PCMU octet 0x7F.)
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
148
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
149 * The s2u[] table in toast_ulaw.c in libgsm source is flat-out wrong and should
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
150 not be used or considered further (and because those authors did not include
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
151 the source for whatever program they used to generate their broken s2u[] and
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
152 u2s[] tables, we have no way to really analyze them), but one CAN construct a
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
153 new table for the same function, using the upper 13 bits of 16-bit 2's
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
154 complement input to generate PCMU output - see our dev/s2u-regen.c program
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
155 and its output table in dev/s2u-regen.out. The resulting mapping is
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
156 "mirrored" around zero compared to G.191 STL ulaw_compress(): for the same
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
157 input sequence as in the previous two examples, the output will correspond to
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
158 quantized values -4, -2, -2, 0, 0, 2, 2. Just like the G.726 version, this
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
159 look-up table version will never emit PCMU octet 0x7F for -0.
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
160
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
161 It is important to note that all GSM speech decoders produce 2's complement
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
162 outputs that are only 13 bits wide, not 14 - therefore, when the input to the
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
163 G.711 encoder comes from the output of a GSM speech decoder, the difference
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
164 between all 3 alternatives listed above is masked, with all 3 producing
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
165 identical output.
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
166
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
167 For production software, our (Themyscira) recommendation is to use look-up
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
168 tables (dev/s2a-regen.out and dev/s2u-regen.out) for both A-law and mu-law
4c7d0dc1eecb doc/PCM8-conversions: finish encoding description
Mychaela Falconia <falcon@freecalypso.org>
parents: 235
diff changeset
169 encoding, using the upper 12 bits from 16-bit 2's complement input for A-law
237
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
170 encoding and the upper 13 bits for mu-law encoding. For mu-law encoding the
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
171 resulting mapping is different from what G.191 STL ulaw_compress() function
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
172 produces, and many will consider that function to be canon - but our approach
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
173 exhibits the same key properties, just mirrored around zero, and has the
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
174 advantage of needing only the upper 13 bits.
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
175
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
176 Command line utilities
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
177 ======================
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
178
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
179 As usual, the present Themyscira GSM codec libraries & utilities package
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
180 provides command line utilities for working with the subject of this article:
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
181 conversions between 16-bit linear PCM (the format read and written by other
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
182 tools in the present suite) and 8-bit PCM in G.711 A-law or mu-law. The
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
183 following utilities are provided:
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
184
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
185 pcm16-to-alaw These two utilities read 16-bit linear PCM in raw format (BE
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
186 pcm16-to-ulaw byte order by default, or LE with -l option) and convert the
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
187 recording into one byte per sample G.711 format, with each
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
188 program emitting its respective encoding law. pcm16-to-alaw
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
189 has only one mapping, but pcm16-to-ulaw supports two possible
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
190 mappings: by default it applies the mapping of G.191 STL
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
191 ulaw_compress(), or if use specify -t option it applies the
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
192 same mapping that would be produced by our recommended 13-bit
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
193 look-up table method.
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
194
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
195 pcm8-to-pcm16 This utility reads a G.711 8-bit PCM recording (alaw or ulaw
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
196 selected with a mandatory command line argument) from a "raw"
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
197 G.711 file and converts it to 16-bit linear PCM. The output
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
198 byte order is BE by default, or can be changed to LE with an
e4a4bf11f37c doc/PCM8-conversions: document command line utilities
Mychaela Falconia <falcon@freecalypso.org>
parents: 236
diff changeset
199 extra command line qualifier.