1 // TODO: Avoid shifting signed integers. Not well-defined behaviour.
2 /*
3 * This source code is a product of Sun Microsystems, Inc. and is provided
4 * for unrestricted use. Users may copy or modify this source code without
5 * charge.
6 *
7 * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
8 * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
9 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
10 *
11 * Sun source code is provided with no support and without any obligation on
12 * the part of Sun Microsystems, Inc. to assist in its use, correction,
13 * modification or enhancement.
14 *
15 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
16 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
17 * OR ANY PART THEREOF.
18 *
19 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
20 * or profits or other special, indirect and consequential damages, even if
21 * Sun has been advised of the possibility of such damages.
22 *
23 * Sun Microsystems, Inc.
24 * 2550 Garcia Avenue
25 * Mountain View, California 94043
26 */
27
28 /*
29 * g711.c
30 *
31 * u-law, A-law and linear PCM conversions.
32 */
33
34 /*
35 * January 28, 2018:
36 * Stripped out the direct tables again and made things static for
37 * use in syn123 for basic ulaw/alaw conversion support. Also changed
38 * to more explicit integer types.
39 * Thomas Orgis, thomas@orgis.org
40 *
41 */
42
43 /*
44 * December 30, 1994:
45 * Functions linear2alaw, linear2ulaw have been updated to correctly
46 * convert unquantized 16 bit values.
47 * Tables for direct u- to A-law and A- to u-law conversions have been
48 * corrected.
49 * Borge Lindberg, Center for PersonKommunikation, Aalborg University.
50 * bli@cpk.auc.dk
51 *
52 */
53
54 static const unsigned char sign_bit = 0x80; /* Sign bit for a A-law byte. */
55 static const unsigned char quant_mask = 0xf; /* Quantization field mask. */
56 static const unsigned char seg_shift = 4; /* Left shift for segment number. */
57 static const unsigned char seg_mask = 0x70; /* Segment field mask. */
58
59 static int16_t seg_aend[8] = {
60 0x01F, 0x03F, 0x07F, 0x0FF,
61 0x1FF, 0x3FF, 0x7FF, 0xFFF
62 };
63 static int16_t seg_uend[8] = {
64 0x03F, 0x07F, 0x0FF, 0x01FF,
65 0x3FF, 0x7FF, 0xFFF, 0x1FFF
66 };
67
search(int16_t val,int16_t * table,int size)68 static int search(int16_t val, int16_t *table, int size)
69 {
70 int i;
71
72 for (i = 0; i < size; i++) {
73 if (val <= *table++)
74 return (i);
75 }
76 return (size);
77 }
78
79 /*
80 * linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
81 *
82 * linear2alaw() accepts an 16-bit integer and encodes it as A-law data.
83 *
84 * Linear Input Code Compressed Code
85 * ------------------------ ---------------
86 * 0000000wxyza 000wxyz
87 * 0000001wxyza 001wxyz
88 * 000001wxyzab 010wxyz
89 * 00001wxyzabc 011wxyz
90 * 0001wxyzabcd 100wxyz
91 * 001wxyzabcde 101wxyz
92 * 01wxyzabcdef 110wxyz
93 * 1wxyzabcdefg 111wxyz
94 *
95 * For further information see John C. Bellamy's Digital Telephony, 1982,
96 * John Wiley & Sons, pps 98-111 and 472-476.
97 */
linear2alaw(int16_t pcm_val)98 static unsigned char linear2alaw(int16_t pcm_val)
99 {
100 int16_t mask;
101 int seg;
102 int aval; /* int is comfortable, even if bigger than needed */
103
104 pcm_val = pcm_val >> 3;
105
106 if (pcm_val >= 0) {
107 mask = 0xD5; /* sign (7th) bit = 1 */
108 } else {
109 mask = 0x55; /* sign bit = 0 */
110 pcm_val = -pcm_val - 1;
111 }
112
113 /* Convert the scaled magnitude to segment number. */
114 seg = search(pcm_val, seg_aend, 8);
115
116 /* Combine the sign, segment, and quantization bits. */
117
118 if (seg >= 8) /* out of range, return maximum value. */
119 return (unsigned char)(0x7F ^ mask);
120 else {
121 aval = seg << seg_shift;
122 if (seg < 2)
123 aval |= (pcm_val >> 1) & quant_mask;
124 else
125 aval |= (pcm_val >> seg) & quant_mask;
126 return (unsigned char)(aval ^ mask);
127 }
128 }
129
130 /*
131 * alaw2linear() - Convert an A-law value to 16-bit linear PCM
132 *
133 */
alaw2linear(unsigned char a_val)134 int16_t alaw2linear(unsigned char a_val)
135 {
136 int16_t t;
137 int seg;
138
139 a_val ^= 0x55;
140
141 t = (a_val & quant_mask) << 4;
142 seg = (a_val & seg_mask) >> seg_shift;
143 switch (seg) {
144 case 0:
145 t += 8;
146 break;
147 case 1:
148 t += 0x108;
149 break;
150 default:
151 t += 0x108;
152 t <<= seg - 1;
153 }
154 return ((a_val & sign_bit) ? t : -t);
155 }
156
157 static const int16_t bias = 0x84; /* Bias for linear code. */
158 static const int16_t clip = 8159;
159
160 /*
161 * linear2ulaw() - Convert a linear PCM value to u-law
162 *
163 * In order to simplify the encoding process, the original linear magnitude
164 * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
165 * (33 - 8191). The result can be seen in the following encoding table:
166 *
167 * Biased Linear Input Code Compressed Code
168 * ------------------------ ---------------
169 * 00000001wxyza 000wxyz
170 * 0000001wxyzab 001wxyz
171 * 000001wxyzabc 010wxyz
172 * 00001wxyzabcd 011wxyz
173 * 0001wxyzabcde 100wxyz
174 * 001wxyzabcdef 101wxyz
175 * 01wxyzabcdefg 110wxyz
176 * 1wxyzabcdefgh 111wxyz
177 *
178 * Each biased linear code has a leading 1 which identifies the segment
179 * number. The value of the segment number is equal to 7 minus the number
180 * of leading 0's. The quantization interval is directly available as the
181 * four bits wxyz. * The trailing bits (a - h) are ignored.
182 *
183 * Ordinarily the complement of the resulting code word is used for
184 * transmission, and so the code word is complemented before it is returned.
185 *
186 * For further information see John C. Bellamy's Digital Telephony, 1982,
187 * John Wiley & Sons, pps 98-111 and 472-476.
188 */
linear2ulaw(int16_t pcm_val)189 static unsigned char linear2ulaw(int16_t pcm_val)
190 {
191 int16_t mask;
192 int seg;
193 int uval;
194
195 /* Get the sign and the magnitude of the value. */
196 pcm_val = pcm_val >> 2;
197 if (pcm_val < 0) {
198 pcm_val = -pcm_val;
199 mask = 0x7F;
200 } else {
201 mask = 0xFF;
202 }
203 if ( pcm_val > clip ) pcm_val = clip; /* clip the magnitude */
204 pcm_val += (bias >> 2);
205
206 /* Convert the scaled magnitude to segment number. */
207 seg = search(pcm_val, seg_uend, 8);
208
209 /*
210 * Combine the sign, segment, quantization bits;
211 * and complement the code word.
212 */
213 if (seg >= 8) /* out of range, return maximum value. */
214 return (unsigned char)(0x7F ^ mask);
215 else {
216 uval = (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
217 return (unsigned char)(uval ^ mask);
218 }
219
220 }
221
222 /*
223 * ulaw2linear() - Convert a u-law value to 16-bit linear PCM
224 *
225 * First, a biased linear code is derived from the code word. An unbiased
226 * output can then be obtained by subtracting 33 from the biased code.
227 *
228 * Note that this function expects to be passed the complement of the
229 * original code word. This is in keeping with ISDN conventions.
230 */
ulaw2linear(unsigned char u_val)231 static int16_t ulaw2linear(unsigned char u_val)
232 {
233 int t;
234
235 /* Complement to obtain normal u-law value. */
236 u_val = ~u_val;
237
238 /*
239 * Extract and bias the quantization bits. Then
240 * shift up by the segment number and subtract out the bias.
241 */
242 t = ((u_val & quant_mask) << 3) + bias;
243 t <<= (u_val & seg_mask) >> seg_shift;
244
245 return ((u_val & sign_bit) ? (bias - t) : (t - bias));
246 }
247