12024
|
1 /*
|
|
2 * PCM - A-Law conversion
|
|
3 * Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
|
|
4 *
|
|
5 * Wrapper for linphone Codec class by Simon Morlat <simon.morlat@free.fr>
|
|
6 */
|
|
7
|
|
8 static inline int val_seg(int val)
|
|
9 {
|
|
10 int r = 0;
|
|
11 val >>= 7;
|
|
12 if (val & 0xf0) {
|
|
13 val >>= 4;
|
|
14 r += 4;
|
|
15 }
|
|
16 if (val & 0x0c) {
|
|
17 val >>= 2;
|
|
18 r += 2;
|
|
19 }
|
|
20 if (val & 0x02)
|
|
21 r += 1;
|
|
22 return r;
|
|
23 }
|
|
24
|
|
25 /*
|
|
26 * s16_to_alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
|
|
27 *
|
|
28 * s16_to_alaw() accepts an 16-bit integer and encodes it as A-law data.
|
|
29 *
|
|
30 * Linear Input Code Compressed Code
|
|
31 * ------------------------ ---------------
|
|
32 * 0000000wxyza 000wxyz
|
|
33 * 0000001wxyza 001wxyz
|
|
34 * 000001wxyzab 010wxyz
|
|
35 * 00001wxyzabc 011wxyz
|
|
36 * 0001wxyzabcd 100wxyz
|
|
37 * 001wxyzabcde 101wxyz
|
|
38 * 01wxyzabcdef 110wxyz
|
|
39 * 1wxyzabcdefg 111wxyz
|
|
40 *
|
|
41 * For further information see John C. Bellamy's Digital Telephony, 1982,
|
|
42 * John Wiley & Sons, pps 98-111 and 472-476.
|
|
43 */
|
|
44
|
|
45 static inline unsigned char s16_to_alaw(int pcm_val)
|
|
46 {
|
|
47 int mask;
|
|
48 int seg;
|
|
49 unsigned char aval;
|
|
50
|
|
51 if (pcm_val >= 0) {
|
|
52 mask = 0xD5;
|
|
53 } else {
|
|
54 mask = 0x55;
|
|
55 pcm_val = -pcm_val;
|
|
56 if (pcm_val > 0x7fff)
|
|
57 pcm_val = 0x7fff;
|
|
58 }
|
|
59
|
|
60 if (pcm_val < 256)
|
|
61 aval = pcm_val >> 4;
|
|
62 else {
|
|
63 /* Convert the scaled magnitude to segment number. */
|
|
64 seg = val_seg(pcm_val);
|
|
65 aval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0x0f);
|
|
66 }
|
|
67 return aval ^ mask;
|
|
68 }
|
|
69
|
|
70 /*
|
|
71 * alaw_to_s16() - Convert an A-law value to 16-bit linear PCM
|
|
72 *
|
|
73 */
|
|
74 static inline int alaw_to_s16(unsigned char a_val)
|
|
75 {
|
|
76 int t;
|
|
77 int seg;
|
|
78
|
|
79 a_val ^= 0x55;
|
|
80 t = a_val & 0x7f;
|
|
81 if (t < 16)
|
|
82 t = (t << 4) + 8;
|
|
83 else {
|
|
84 seg = (t >> 4) & 0x07;
|
|
85 t = ((t & 0x0f) << 4) + 0x108;
|
|
86 t <<= seg -1;
|
|
87 }
|
|
88 return ((a_val & 0x80) ? t : -t);
|
|
89 }
|
|
90 /*
|
|
91 * s16_to_ulaw() - Convert a linear PCM value to u-law
|
|
92 *
|
|
93 * In order to simplify the encoding process, the original linear magnitude
|
|
94 * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
|
|
95 * (33 - 8191). The result can be seen in the following encoding table:
|
|
96 *
|
|
97 * Biased Linear Input Code Compressed Code
|
|
98 * ------------------------ ---------------
|
|
99 * 00000001wxyza 000wxyz
|
|
100 * 0000001wxyzab 001wxyz
|
|
101 * 000001wxyzabc 010wxyz
|
|
102 * 00001wxyzabcd 011wxyz
|
|
103 * 0001wxyzabcde 100wxyz
|
|
104 * 001wxyzabcdef 101wxyz
|
|
105 * 01wxyzabcdefg 110wxyz
|
|
106 * 1wxyzabcdefgh 111wxyz
|
|
107 *
|
|
108 * Each biased linear code has a leading 1 which identifies the segment
|
|
109 * number. The value of the segment number is equal to 7 minus the number
|
|
110 * of leading 0's. The quantization interval is directly available as the
|
|
111 * four bits wxyz. * The trailing bits (a - h) are ignored.
|
|
112 *
|
|
113 * Ordinarily the complement of the resulting code word is used for
|
|
114 * transmission, and so the code word is complemented before it is returned.
|
|
115 *
|
|
116 * For further information see John C. Bellamy's Digital Telephony, 1982,
|
|
117 * John Wiley & Sons, pps 98-111 and 472-476.
|
|
118 */
|
|
119
|
|
120 static inline unsigned char s16_to_ulaw(int pcm_val) /* 2's complement (16-bit range) */
|
|
121 {
|
|
122 int mask;
|
|
123 int seg;
|
|
124 unsigned char uval;
|
|
125
|
|
126 if (pcm_val < 0) {
|
|
127 pcm_val = 0x84 - pcm_val;
|
|
128 mask = 0x7f;
|
|
129 } else {
|
|
130 pcm_val += 0x84;
|
|
131 mask = 0xff;
|
|
132 }
|
|
133 if (pcm_val > 0x7fff)
|
|
134 pcm_val = 0x7fff;
|
|
135
|
|
136 /* Convert the scaled magnitude to segment number. */
|
|
137 seg = val_seg(pcm_val);
|
|
138
|
|
139 /*
|
|
140 * Combine the sign, segment, quantization bits;
|
|
141 * and complement the code word.
|
|
142 */
|
|
143 uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0x0f);
|
|
144 return uval ^ mask;
|
|
145 }
|
|
146
|
|
147 /*
|
|
148 * ulaw_to_s16() - Convert a u-law value to 16-bit linear PCM
|
|
149 *
|
|
150 * First, a biased linear code is derived from the code word. An unbiased
|
|
151 * output can then be obtained by subtracting 33 from the biased code.
|
|
152 *
|
|
153 * Note that this function expects to be passed the complement of the
|
|
154 * original code word. This is in keeping with ISDN conventions.
|
|
155 */
|
|
156 static inline int ulaw_to_s16(unsigned char u_val)
|
|
157 {
|
|
158 int t;
|
|
159
|
|
160 /* Complement to obtain normal u-law value. */
|
|
161 u_val = ~u_val;
|
|
162
|
|
163 /*
|
|
164 * Extract and bias the quantization bits. Then
|
|
165 * shift up by the segment number and subtract out the bias.
|
|
166 */
|
|
167 t = ((u_val & 0x0f) << 3) + 0x84;
|
|
168 t <<= (u_val & 0x70) >> 4;
|
|
169
|
|
170 return ((u_val & 0x80) ? (0x84 - t) : (t - 0x84));
|
|
171 }
|