I am implementing the ITU-T G.711 standard and I decided to start with the reference code in G.191.
Running some tests on A-law compress made me doubt the correctness of the algorithm.
According to G.711, the input range 0-63 should be located on the first segment, with a step size of two. The sample code in G.191 maps this range as following:
- from 0 to 15 on segment 0 with a step size of 1
- from 16 to 31 on segment 1 with a step size of 1
- from 32 to 63 on segment 2 with a step size of 2
Not only we get a 1 segment offset when comparing the output to the value in the table, but the range is also halved, such that compressed FF corresponds to uniform 2047.
How should I proceed in order to have a G.711 compliant codec?
The code is commensurate with the standard.
Note first that the standard assumes 13-bit input (but always quantises the lsb), the code assumes 16-bit, and immediately discards all but the 12 msbs. So in 12-bit terms, Table 1a in G.711 is really saying:
The only remaining discrepancy is that the first segment is apparently split in two in the code. It's not really; note that the segments are not the same as exponents; Segment 1 encompasses both exponents
000
and001
. The code deals exclusively with exponents.