blob: 0a14de87f6f7a9c20069be725f36b6f511fdcd9d [file] [log] [blame]
Tristan Matthews0a329cc2013-07-17 13:20:14 -04001/*
2 * This source code is a product of Sun Microsystems, Inc. and is provided
3 * for unrestricted use. Users may copy or modify this source code without
4 * charge.
5 *
6 * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
7 * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
8 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
9 *
10 * Sun source code is provided with no support and without any obligation on
11 * the part of Sun Microsystems, Inc. to assist in its use, correction,
12 * modification or enhancement.
13 *
14 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
15 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
16 * OR ANY PART THEREOF.
17 *
18 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
19 * or profits or other special, indirect and consequential damages, even if
20 * Sun has been advised of the possibility of such damages.
21 *
22 * Sun Microsystems, Inc.
23 * 2550 Garcia Avenue
24 * Mountain View, California 94043
25 */
26#include <pjmedia/alaw_ulaw.h>
27
28#if !defined(PJMEDIA_HAS_ALAW_ULAW_TABLE) || PJMEDIA_HAS_ALAW_ULAW_TABLE==0
29
30#ifdef _MSC_VER
31# pragma warning ( disable: 4244 ) /* Conversion from int to char etc */
32#endif
33
34/*
35 * g711.c
36 *
37 * u-law, A-law and linear PCM conversions.
38 */
39#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
40#define QUANT_MASK (0xf) /* Quantization field mask. */
41#define NSEGS (8) /* Number of A-law segments. */
42#define SEG_SHIFT (4) /* Left shift for segment number. */
43#define SEG_MASK (0x70) /* Segment field mask. */
44
45static short seg_end[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF,
46 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};
47
48/* copy from CCITT G.711 specifications */
49static unsigned char _u2a[128] = { /* u- to A-law conversions */
50 1, 1, 2, 2, 3, 3, 4, 4,
51 5, 5, 6, 6, 7, 7, 8, 8,
52 9, 10, 11, 12, 13, 14, 15, 16,
53 17, 18, 19, 20, 21, 22, 23, 24,
54 25, 27, 29, 31, 33, 34, 35, 36,
55 37, 38, 39, 40, 41, 42, 43, 44,
56 46, 48, 49, 50, 51, 52, 53, 54,
57 55, 56, 57, 58, 59, 60, 61, 62,
58 64, 65, 66, 67, 68, 69, 70, 71,
59 72, 73, 74, 75, 76, 77, 78, 79,
60 81, 82, 83, 84, 85, 86, 87, 88,
61 89, 90, 91, 92, 93, 94, 95, 96,
62 97, 98, 99, 100, 101, 102, 103, 104,
63 105, 106, 107, 108, 109, 110, 111, 112,
64 113, 114, 115, 116, 117, 118, 119, 120,
65 121, 122, 123, 124, 125, 126, 127, 128};
66
67static unsigned char _a2u[128] = { /* A- to u-law conversions */
68 1, 3, 5, 7, 9, 11, 13, 15,
69 16, 17, 18, 19, 20, 21, 22, 23,
70 24, 25, 26, 27, 28, 29, 30, 31,
71 32, 32, 33, 33, 34, 34, 35, 35,
72 36, 37, 38, 39, 40, 41, 42, 43,
73 44, 45, 46, 47, 48, 48, 49, 49,
74 50, 51, 52, 53, 54, 55, 56, 57,
75 58, 59, 60, 61, 62, 63, 64, 64,
76 65, 66, 67, 68, 69, 70, 71, 72,
77 73, 74, 75, 76, 77, 78, 79, 79,
78 80, 81, 82, 83, 84, 85, 86, 87,
79 88, 89, 90, 91, 92, 93, 94, 95,
80 96, 97, 98, 99, 100, 101, 102, 103,
81 104, 105, 106, 107, 108, 109, 110, 111,
82 112, 113, 114, 115, 116, 117, 118, 119,
83 120, 121, 122, 123, 124, 125, 126, 127};
84
85static int
86search(
87 int val,
88 short *table,
89 int size)
90{
91 int i;
92
93 for (i = 0; i < size; i++) {
94 if (val <= *table++)
95 return (i);
96 }
97 return (size);
98}
99
100/*
101 * linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
102 *
103 * linear2alaw() accepts an 16-bit integer and encodes it as A-law data.
104 *
105 * Linear Input Code Compressed Code
106 * ------------------------ ---------------
107 * 0000000wxyza 000wxyz
108 * 0000001wxyza 001wxyz
109 * 000001wxyzab 010wxyz
110 * 00001wxyzabc 011wxyz
111 * 0001wxyzabcd 100wxyz
112 * 001wxyzabcde 101wxyz
113 * 01wxyzabcdef 110wxyz
114 * 1wxyzabcdefg 111wxyz
115 *
116 * For further information see John C. Bellamy's Digital Telephony, 1982,
117 * John Wiley & Sons, pps 98-111 and 472-476.
118 */
119PJ_DEF(pj_uint8_t) pjmedia_linear2alaw(
120 int pcm_val) /* 2's complement (16-bit range) */
121{
122 int mask;
123 int seg;
124 unsigned char aval;
125
126 if (pcm_val >= 0) {
127 mask = 0xD5; /* sign (7th) bit = 1 */
128 } else {
129 mask = 0x55; /* sign bit = 0 */
130 pcm_val = -pcm_val - 8;
131
132 /* https://trac.pjsip.org/repos/ticket/1301
133 * Thank you K Johnson - Zetron - 27 May 2011
134 */
135 if (pcm_val < 0)
136 pcm_val = 0;
137 }
138
139 /* Convert the scaled magnitude to segment number. */
140 seg = search(pcm_val, seg_end, 8);
141
142 /* Combine the sign, segment, and quantization bits. */
143
144 if (seg >= 8) /* out of range, return maximum value. */
145 return (0x7F ^ mask);
146 else {
147 aval = seg << SEG_SHIFT;
148 if (seg < 2)
149 aval |= (pcm_val >> 4) & QUANT_MASK;
150 else
151 aval |= (pcm_val >> (seg + 3)) & QUANT_MASK;
152 return (aval ^ mask);
153 }
154}
155
156/*
157 * alaw2linear() - Convert an A-law value to 16-bit linear PCM
158 *
159 */
160PJ_DEF(int) pjmedia_alaw2linear(
161 unsigned a_val)
162{
163 int t;
164 int seg;
165
166 a_val ^= 0x55;
167
168 t = (a_val & QUANT_MASK) << 4;
169 seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
170 switch (seg) {
171 case 0:
172 t += 8;
173 break;
174 case 1:
175 t += 0x108;
176 break;
177 default:
178 t += 0x108;
179 t <<= seg - 1;
180 }
181 return ((a_val & SIGN_BIT) ? t : -t);
182}
183
184#define BIAS (0x84) /* Bias for linear code. */
185
186/*
187 * linear2ulaw() - Convert a linear PCM value to u-law
188 *
189 * In order to simplify the encoding process, the original linear magnitude
190 * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
191 * (33 - 8191). The result can be seen in the following encoding table:
192 *
193 * Biased Linear Input Code Compressed Code
194 * ------------------------ ---------------
195 * 00000001wxyza 000wxyz
196 * 0000001wxyzab 001wxyz
197 * 000001wxyzabc 010wxyz
198 * 00001wxyzabcd 011wxyz
199 * 0001wxyzabcde 100wxyz
200 * 001wxyzabcdef 101wxyz
201 * 01wxyzabcdefg 110wxyz
202 * 1wxyzabcdefgh 111wxyz
203 *
204 * Each biased linear code has a leading 1 which identifies the segment
205 * number. The value of the segment number is equal to 7 minus the number
206 * of leading 0's. The quantization interval is directly available as the
207 * four bits wxyz. * The trailing bits (a - h) are ignored.
208 *
209 * Ordinarily the complement of the resulting code word is used for
210 * transmission, and so the code word is complemented before it is returned.
211 *
212 * For further information see John C. Bellamy's Digital Telephony, 1982,
213 * John Wiley & Sons, pps 98-111 and 472-476.
214 */
215PJ_DEF(unsigned char) pjmedia_linear2ulaw(
216 int pcm_val) /* 2's complement (16-bit range) */
217{
218 int mask;
219 int seg;
220 unsigned char uval;
221
222 /* Get the sign and the magnitude of the value. */
223 if (pcm_val < 0) {
224 pcm_val = BIAS - pcm_val;
225 mask = 0x7F;
226 } else {
227 pcm_val += BIAS;
228 mask = 0xFF;
229 }
230
231 /* Convert the scaled magnitude to segment number. */
232 seg = search(pcm_val, seg_end, 8);
233
234 /*
235 * Combine the sign, segment, quantization bits;
236 * and complement the code word.
237 */
238 if (seg >= 8) /* out of range, return maximum value. */
239 return (0x7F ^ mask);
240 else {
241 uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF);
242 return (uval ^ mask);
243 }
244
245}
246
247/*
248 * ulaw2linear() - Convert a u-law value to 16-bit linear PCM
249 *
250 * First, a biased linear code is derived from the code word. An unbiased
251 * output can then be obtained by subtracting 33 from the biased code.
252 *
253 * Note that this function expects to be passed the complement of the
254 * original code word. This is in keeping with ISDN conventions.
255 */
256PJ_DEF(int) pjmedia_ulaw2linear(
257 unsigned char u_val)
258{
259 int t;
260
261 /* Shortcut: when input is zero, output is zero
262 * This will also make the VAD works harder.
263 * -bennylp
264 */
265 if (u_val == 0) return 0;
266
267 /* Complement to obtain normal u-law value. */
268 u_val = ~u_val;
269
270 /*
271 * Extract and bias the quantization bits. Then
272 * shift up by the segment number and subtract out the bias.
273 */
274 t = ((u_val & QUANT_MASK) << 3) + BIAS;
275 t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
276
277 return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
278}
279
280/* A-law to u-law conversion */
281PJ_DEF(unsigned char) pjmedia_alaw2ulaw(
282 unsigned char aval)
283{
284 aval &= 0xff;
285 return ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) :
286 (0x7F ^ _a2u[aval ^ 0x55]));
287}
288
289/* u-law to A-law conversion */
290PJ_DEF(unsigned char) pjmedia_ulaw2alaw(
291 unsigned char uval)
292{
293 uval &= 0xff;
294 return ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)) :
295 (0x55 ^ (_u2a[0x7F ^ uval] - 1)));
296}
297
298
299#endif /* PJMEDIA_HAS_ALAW_ULAW_TABLE */
300