source: trunk/third/audiofile/libaudiofile/g711.c @ 15366

Revision 15366, 7.5 KB checked in by ghudson, 24 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r15365, which included commits to RCS files with non-trunk default branches.
Line 
1/*
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
27#define SUPERCEDED
28
29/*
30 * g711.c
31 *
32 * u-law, A-law and linear PCM conversions.
33 */
34#define SIGN_BIT        (0x80)          /* Sign bit for a A-law byte. */
35#define QUANT_MASK      (0xf)           /* Quantization field mask. */
36#define NSEGS           (8)             /* Number of A-law segments. */
37#define SEG_SHIFT       (4)             /* Left shift for segment number. */
38#define SEG_MASK        (0x70)          /* Segment field mask. */
39
40/* copy from CCITT G.711 specifications */
41unsigned char _u2a[128] = {                     /* u- to A-law conversions */
42        1,      1,      2,      2,      3,      3,      4,      4,
43        5,      5,      6,      6,      7,      7,      8,      8,
44        9,      10,     11,     12,     13,     14,     15,     16,
45        17,     18,     19,     20,     21,     22,     23,     24,
46        25,     27,     29,     31,     33,     34,     35,     36,
47        37,     38,     39,     40,     41,     42,     43,     44,
48        46,     48,     49,     50,     51,     52,     53,     54,
49        55,     56,     57,     58,     59,     60,     61,     62,
50        64,     65,     66,     67,     68,     69,     70,     71,
51        72,     73,     74,     75,     76,     77,     78,     79,
52        81,     82,     83,     84,     85,     86,     87,     88,
53        89,     90,     91,     92,     93,     94,     95,     96,
54        97,     98,     99,     100,    101,    102,    103,    104,
55        105,    106,    107,    108,    109,    110,    111,    112,
56        113,    114,    115,    116,    117,    118,    119,    120,
57        121,    122,    123,    124,    125,    126,    127,    128};
58
59unsigned char _a2u[128] = {                     /* A- to u-law conversions */
60        1,      3,      5,      7,      9,      11,     13,     15,
61        16,     17,     18,     19,     20,     21,     22,     23,
62        24,     25,     26,     27,     28,     29,     30,     31,
63        32,     32,     33,     33,     34,     34,     35,     35,
64        36,     37,     38,     39,     40,     41,     42,     43,
65        44,     45,     46,     47,     48,     48,     49,     49,
66        50,     51,     52,     53,     54,     55,     56,     57,
67        58,     59,     60,     61,     62,     63,     64,     64,
68        65,     66,     67,     68,     69,     70,     71,     72,
69        73,     74,     75,     76,     77,     78,     79,     79,
70        80,     81,     82,     83,     84,     85,     86,     87,
71        88,     89,     90,     91,     92,     93,     94,     95,
72        96,     97,     98,     99,     100,    101,    102,    103,
73        104,    105,    106,    107,    108,    109,    110,    111,
74        112,    113,    114,    115,    116,    117,    118,    119,
75        120,    121,    122,    123,    124,    125,    126,    127};
76
77/* see libst.h */
78#ifdef  SUPERCEDED
79
80static short seg_end[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF,
81                            0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};
82
83static int
84search(val, table, size)
85        int             val;
86        short           *table;
87        int             size;
88{
89        int             i;
90
91        for (i = 0; i < size; i++) {
92                if (val <= *table++)
93                        return (i);
94        }
95        return (size);
96}
97
98/*
99 * linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
100 *
101 * linear2alaw() accepts an 16-bit integer and encodes it as A-law data.
102 *
103 *              Linear Input Code       Compressed Code
104 *      ------------------------        ---------------
105 *      0000000wxyza                    000wxyz
106 *      0000001wxyza                    001wxyz
107 *      000001wxyzab                    010wxyz
108 *      00001wxyzabc                    011wxyz
109 *      0001wxyzabcd                    100wxyz
110 *      001wxyzabcde                    101wxyz
111 *      01wxyzabcdef                    110wxyz
112 *      1wxyzabcdefg                    111wxyz
113 *
114 * For further information see John C. Bellamy's Digital Telephony, 1982,
115 * John Wiley & Sons, pps 98-111 and 472-476.
116 */
117unsigned char
118_af_linear2alaw(pcm_val)
119        int             pcm_val;        /* 2's complement (16-bit range) */
120{
121        int             mask;
122        int             seg;
123        unsigned char   aval;
124
125        if (pcm_val >= 0) {
126                mask = 0xD5;            /* sign (7th) bit = 1 */
127        } else {
128                mask = 0x55;            /* sign bit = 0 */
129                pcm_val = -pcm_val - 8;
130        }
131
132        /* Convert the scaled magnitude to segment number. */
133        seg = search(pcm_val, seg_end, 8);
134
135        /* Combine the sign, segment, and quantization bits. */
136
137        if (seg >= 8)           /* out of range, return maximum value. */
138                return (0x7F ^ mask);
139        else {
140                aval = seg << SEG_SHIFT;
141                if (seg < 2)
142                        aval |= (pcm_val >> 4) & QUANT_MASK;
143                else
144                        aval |= (pcm_val >> (seg + 3)) & QUANT_MASK;
145                return (aval ^ mask);
146        }
147}
148
149/*
150 * alaw2linear() - Convert an A-law value to 16-bit linear PCM
151 *
152 */
153int
154_af_alaw2linear(a_val)
155        unsigned char   a_val;
156{
157        int             t;
158        int             seg;
159
160        a_val ^= 0x55;
161
162        t = (a_val & QUANT_MASK) << 4;
163        seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
164        switch (seg) {
165        case 0:
166                t += 8;
167                break;
168        case 1:
169                t += 0x108;
170                break;
171        default:
172                t += 0x108;
173                t <<= seg - 1;
174        }
175        return ((a_val & SIGN_BIT) ? t : -t);
176}
177
178#define BIAS            (0x84)          /* Bias for linear code. */
179
180/*
181 * linear2ulaw() - Convert a linear PCM value to u-law
182 *
183 * In order to simplify the encoding process, the original linear magnitude
184 * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
185 * (33 - 8191). The result can be seen in the following encoding table:
186 *
187 *      Biased Linear Input Code        Compressed Code
188 *      ------------------------        ---------------
189 *      00000001wxyza                   000wxyz
190 *      0000001wxyzab                   001wxyz
191 *      000001wxyzabc                   010wxyz
192 *      00001wxyzabcd                   011wxyz
193 *      0001wxyzabcde                   100wxyz
194 *      001wxyzabcdef                   101wxyz
195 *      01wxyzabcdefg                   110wxyz
196 *      1wxyzabcdefgh                   111wxyz
197 *
198 * Each biased linear code has a leading 1 which identifies the segment
199 * number. The value of the segment number is equal to 7 minus the number
200 * of leading 0's. The quantization interval is directly available as the
201 * four bits wxyz.  * The trailing bits (a - h) are ignored.
202 *
203 * Ordinarily the complement of the resulting code word is used for
204 * transmission, and so the code word is complemented before it is returned.
205 *
206 * For further information see John C. Bellamy's Digital Telephony, 1982,
207 * John Wiley & Sons, pps 98-111 and 472-476.
208 */
209
210/* 2's complement (16-bit range) */
211unsigned char _af_linear2ulaw (int pcm_val)
212{
213        int             mask;
214        int             seg;
215        unsigned char   uval;
216
217        /* Get the sign and the magnitude of the value. */
218        if (pcm_val < 0) {
219                pcm_val = BIAS - pcm_val;
220                mask = 0x7F;
221        } else {
222                pcm_val += BIAS;
223                mask = 0xFF;
224        }
225
226        /* Convert the scaled magnitude to segment number. */
227        seg = search(pcm_val, seg_end, 8);
228
229        /*
230         * Combine the sign, segment, quantization bits;
231         * and complement the code word.
232         */
233        if (seg >= 8)           /* out of range, return maximum value. */
234                return (0x7F ^ mask);
235        else {
236                uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF);
237                return (uval ^ mask);
238        }
239
240}
241
242/*
243 * ulaw2linear() - Convert a u-law value to 16-bit linear PCM
244 *
245 * First, a biased linear code is derived from the code word. An unbiased
246 * output can then be obtained by subtracting 33 from the biased code.
247 *
248 * Note that this function expects to be passed the complement of the
249 * original code word. This is in keeping with ISDN conventions.
250 */
251int _af_ulaw2linear (unsigned char u_val)
252{
253        int             t;
254
255        /* Complement to obtain normal u-law value. */
256        u_val = ~u_val;
257
258        /*
259         * Extract and bias the quantization bits. Then
260         * shift up by the segment number and subtract out the bias.
261         */
262        t = ((u_val & QUANT_MASK) << 3) + BIAS;
263        t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
264
265        return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
266}
267
268#endif
269
270/* A-law to u-law conversion */
271unsigned char
272alaw2ulaw(aval)
273        unsigned char   aval;
274{
275        aval &= 0xff;
276        return ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) :
277            (0x7F ^ _a2u[aval ^ 0x55]));
278}
279
280/* u-law to A-law conversion */
281unsigned char
282ulaw2alaw(uval)
283        unsigned char   uval;
284{
285        uval &= 0xff;
286        return ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)) :
287            (0x55 ^ (_u2a[0x7F ^ uval] - 1)));
288}
Note: See TracBrowser for help on using the repository browser.