FreeCalypso > hg > gsm-codec-lib
comparison doc/PCM8-conversions @ 235:0ee1a66c1846
doc/PCM8-conversions: beginning of document
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Mon, 08 May 2023 00:45:26 +0000 |
| parents | |
| children | 4c7d0dc1eecb |
comparison
equal
deleted
inserted
replaced
| 234:c7f02428bda6 | 235:0ee1a66c1846 |
|---|---|
| 1 What is the authoritatively correct, officially endorsed bidirectional mapping | |
| 2 between G.711 A-law and mu-law encodings on one side and 16-bit 2's complement | |
| 3 linear PCM on the other side? Surprisingly, there is no official answer to this | |
| 4 problem anywhere in the specs! Instead the specs provide the following partial | |
| 5 answers: | |
| 6 | |
| 7 * The G.711 spec itself provides one mapping from A-law code octets to linear | |
| 8 numeric values in range [-4032,4032] and another mapping from mu-law code | |
| 9 octets to linear numeric values in range [-8031,8031]. The output from each | |
| 10 of these mapping is given in "pure mathematical" form, without specifying any | |
| 11 bit-level encoding, and furthermore, mu-law decoder output in its pure | |
| 12 "conceptual" form has both +0 and -0 values. (The same signed zero problem | |
| 13 does not occur in A-law because it's a mid-riser code rather than mid-tread, | |
| 14 and thus has no quantized values equal to 0.) | |
| 15 | |
| 16 * If one takes the "pure mathematical" output from the spec-prescribed G.711 | |
| 17 decoder and represents it in 2's complement form, squashing +0 and -0 outputs | |
| 18 from the canonical mu-law decoder into "plain 0" at this step, the result is | |
| 19 a 13 bits wide 2's complement value for A-law decoding and a 14 bits wide 2's | |
| 20 complement value for mu-law. | |
| 21 | |
| 22 * All GSM speech encoders take 13-bit 2's complement linear PCM samples as their | |
| 23 input. How should this 13-bit GSM codec input be derived from A-law or mu-law | |
| 24 code octets? GSM specs refer to ITU's G.726 spec for ADPCM - it just so | |
| 25 happens that inside the ADPCM algorithm of G.726 (a totally unrelated codec of | |
| 26 no relevance to GSM codec work outside of this reference) there is a pair of | |
| 27 functions for expanding A-law and mu-law to linear PCM and compressing linear | |
| 28 PCM back to A-law or mu-law. | |
| 29 | |
| 30 * Following this obscure G.726 reference, we eventually conclude that in the | |
| 31 case of A-law, GSM specs call for the obvious treatment: take the "natural" | |
| 32 output from the canonical A-law decoder, represent it in 2's complement form, | |
| 33 the result is 13 bits wide, and just feed that 13-bit 2's complement form to | |
| 34 the input of GSM speech encoders. However, in the case of mu-law the | |
| 35 "natural" G.711 decoder output is one sign bit plus 13 bits of magnitude, | |
| 36 requiring 14 bits in 2's complement representation - and none of the specs I | |
| 37 could find says anything about exactly how this 14-bit input should be reduced | |
| 38 to 13 bits for feeding to GSM speech encoders. Canonical C implementations | |
| 39 of all GSM speech encoders take their input in 16-bit words and clear the 3 | |
| 40 least significant bits as their first step; if the 14-bit mu-law decoder | |
| 41 output is represented in 16-bit words by padding 2 zero bits on the right and | |
| 42 this output is then fed to GSM speech encoder functions, the end effect is | |
| 43 that the least-significant bit of the 14-bit decoder output is simply cut off. | |
| 44 This form of mu-law-to-GSM transcoder implementation is consistent with | |
| 45 TESTx-U.INP and TESTx-U.COD sequences provided in the GSM 06.54 package for | |
| 46 EFR. | |
| 47 | |
| 48 Based on the above considerations, we have our answer for how we should convert | |
| 49 from G.711 to 16-bit 2's complement linear PCM: | |
| 50 | |
| 51 * For A-law, we emit the "natural" output in 13-bit 2's complement form and | |
| 52 append 3 zero bits on the right; this transformation is fully lossless. | |
| 53 | |
| 54 * For mu-law, we emit the "natural" output in 14-bit 2's complement form and | |
| 55 append 2 zero bits on the right. This transformation is almost lossless, | |
| 56 with just one exception: the "pure" decoder's -0 output (resulting from PCMU | |
| 57 octet 0x7F) is squashed to "plain 0", and will be re-emitted as PCMU octet | |
| 58 0xFF rather than 0x7F on subsequent re-encoding to G.711 PCMU. | |
| 59 | |
| 60 For anyone needing a G.711 to 16-bit linear PCM decoder, the present package | |
| 61 provides ready-made decoding tables (following the above rules) in | |
| 62 dev/a2s-regen.out and dev/u2s-regen.out, generated by dev/a2s-regen.c and | |
| 63 dev/u2s-regen.c programs. | |
| 64 | |
| 65 Now for the opposite problem: what is the most correct way to compress 16-bit | |
| 66 2's complement linear PCM to A-law or mu-law? In this direction the official | |
| 67 specs leave even more ambiguity than in the G.711 decoding direction: | |
| 68 | |
| 69 * The G.711 spec itself says: "The conversion to A-law or mu-law values from | |
| 70 uniform PCM values corresponding to the decision values, is left to the | |
| 71 individual equipment specification." The specific implementation used in the | |
| 72 guts of G.726 ADPCM codec is referred to only as a non-normative example. | |
| 73 | |
| 74 * GSM specs likewise refer to this G.726 section 4.2.8 (for compression of | |
| 75 13-bit speech decoder output to G.711) with language that suggests a | |
| 76 non-normative example. | |
| 77 | |
| 78 After painstakingly comparing the C implementation of G.726 in the ITU-T G.191 | |
| 79 STL against the language of G.726 spec itself and convincing myself that they | |
| 80 really do match, and then painstakingly comparing this approach against the one | |
| 81 implemented in the same G.191 STL for G.711 in alaw_compress() and | |
| 82 ulaw_compress() and against the table lookup method implemented in libgsm/toast | |
| 83 (my first reference, before I went down the rabbit hole of tracking down | |
| 84 official specs), I reached the following conclusions: | |
| 85 | |
| 86 * For A-law encoding all 3 parties (G.191 STL alaw_compress() function, G.726 | |
| 87 "compress" block and toast_alaw.c) agree on the same mapping. In this | |
| 88 mapping only the most significant 12 bits of the 2's complement input word | |
| 89 (equivalent to one sign bit and 11 bits of magnitude) are relevant, leading | |
| 90 to the following two interesting properties: | |
| 91 | |
| 92 - the least-significant bit of GSM speech decoder output is always discarded | |
| 93 when converting to A-law; | |
| 94 | |
| 95 - conversion can be easily implemented with a 4096-byte look-up table based | |
| 96 on the upper 12 bits of input, exactly as was done in toast_alaw.c in the | |
| 97 venerable libgsm source. | |
| 98 | |
| 99 * Mu-law encoding is the real hair-raiser: if the input to the to-be-implemented | |
| 100 encoder has 14 or more bits (including the most practical problem of 16-bit | |
| 101 2's complement input), there are no less than 3 different ways to implement | |
| 102 this encoder! | |
| 103 |
