root/rat/trunk/codec_g711.c @ 2262

Revision 2262, 14.2 KB (checked in by ucaccsp, 15 years ago)

Fix typos in codec descriptions

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
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/*
28 * g711.c
29 *
30 * u-law, A-law and linear PCM conversions.
31 */
32
33#define SIGN_BIT        (0x80)          /* Sign bit for a A-law byte. */
34#define QUANT_MASK      (0xf)           /* Quantization field mask. */
35#define NSEGS           (8)             /* Number of A-law segments. */
36#define SEG_SHIFT       (4)             /* Left shift for segment number. */
37#define SEG_MASK        (0x70)          /* Segment field mask. */
38
39static short seg_end[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF,
40                            0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};
41
42/* copy from CCITT G.711 specifications */
43unsigned char _u2a[128] = {                     /* u- to A-law conversions */
44        1,      1,      2,      2,      3,      3,      4,      4,
45        5,      5,      6,      6,      7,      7,      8,      8,
46        9,      10,     11,     12,     13,     14,     15,     16,
47        17,     18,     19,     20,     21,     22,     23,     24,
48        25,     27,     29,     31,     33,     34,     35,     36,
49        37,     38,     39,     40,     41,     42,     43,     44,
50        46,     48,     49,     50,     51,     52,     53,     54,
51        55,     56,     57,     58,     59,     60,     61,     62,
52        64,     65,     66,     67,     68,     69,     70,     71,
53        72,     73,     74,     75,     76,     77,     78,     79,
54        81,     82,     83,     84,     85,     86,     87,     88,
55        89,     90,     91,     92,     93,     94,     95,     96,
56        97,     98,     99,     100,    101,    102,    103,    104,
57        105,    106,    107,    108,    109,    110,    111,    112,
58        113,    114,    115,    116,    117,    118,    119,    120,
59        121,    122,    123,    124,    125,    126,    127,    128};
60
61unsigned char _a2u[128] = {                     /* A- to u-law conversions */
62        1,      3,      5,      7,      9,      11,     13,     15,
63        16,     17,     18,     19,     20,     21,     22,     23,
64        24,     25,     26,     27,     28,     29,     30,     31,
65        32,     32,     33,     33,     34,     34,     35,     35,
66        36,     37,     38,     39,     40,     41,     42,     43,
67        44,     45,     46,     47,     48,     48,     49,     49,
68        50,     51,     52,     53,     54,     55,     56,     57,
69        58,     59,     60,     61,     62,     63,     64,     64,
70        65,     66,     67,     68,     69,     70,     71,     72,
71        73,     74,     75,     76,     77,     78,     79,     79,
72        80,     81,     82,     83,     84,     85,     86,     87,
73        88,     89,     90,     91,     92,     93,     94,     95,
74        96,     97,     98,     99,     100,    101,    102,    103,
75        104,    105,    106,    107,    108,    109,    110,    111,
76        112,    113,    114,    115,    116,    117,    118,    119,
77        120,    121,    122,    123,    124,    125,    126,    127};
78
79static int
80search(
81        int             val,
82        short           *table,
83        int             size)
84{
85        int             i;
86
87        for (i = 0; i < size; i++) {
88                if (val <= *table++)
89                        return (i);
90        }
91        return (size);
92}
93
94/*
95 * linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
96 *
97 * linear2alaw() accepts an 16-bit integer and encodes it as A-law data.
98 *
99 *              Linear Input Code       Compressed Code
100 *      ------------------------        ---------------
101 *      0000000wxyza                    000wxyz
102 *      0000001wxyza                    001wxyz
103 *      000001wxyzab                    010wxyz
104 *      00001wxyzabc                    011wxyz
105 *      0001wxyzabcd                    100wxyz
106 *      001wxyzabcde                    101wxyz
107 *      01wxyzabcdef                    110wxyz
108 *      1wxyzabcdefg                    111wxyz
109 *
110 * For further information see John C. Bellamy's Digital Telephony, 1982,
111 * John Wiley & Sons, pps 98-111 and 472-476.
112 */
113static unsigned char
114linear2alaw(
115        int             pcm_val)        /* 2's complement (16-bit range) */
116{
117        int             mask;
118        int             seg;
119        unsigned char   aval;
120
121        if (pcm_val >= 0) {
122                mask = 0xD5;            /* sign (7th) bit = 1 */
123        } else {
124                mask = 0x55;            /* sign bit = 0 */
125                pcm_val = -pcm_val - 8;
126        }
127
128        /* Convert the scaled magnitude to segment number. */
129        seg = search(pcm_val, seg_end, 8);
130
131        /* Combine the sign, segment, and quantization bits. */
132
133        if (seg >= 8)           /* out of range, return maximum value. */
134                return (0x7F ^ mask);
135        else {
136                aval = seg << SEG_SHIFT;
137                if (seg < 2)
138                        aval |= (pcm_val >> 4) & QUANT_MASK;
139                else
140                        aval |= (pcm_val >> (seg + 3)) & QUANT_MASK;
141                return (aval ^ mask);
142        }
143}
144
145/*
146 * alaw2linear() - Convert an A-law value to 16-bit linear PCM
147 *
148 */
149static int
150alaw2linear(
151        unsigned char   a_val)
152{
153        int             t;
154        int             seg;
155
156        a_val ^= 0x55;
157
158        t = (a_val & QUANT_MASK) << 4;
159        seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
160        switch (seg) {
161        case 0:
162                t += 8;
163                break;
164        case 1:
165                t += 0x108;
166                break;
167        default:
168                t += 0x108;
169                t <<= seg - 1;
170        }
171        return ((a_val & SIGN_BIT) ? t : -t);
172}
173
174#define BIAS            (0x84)          /* Bias for linear code. */
175
176/*
177 * linear2ulaw() - Convert a linear PCM value to u-law
178 *
179 * In order to simplify the encoding process, the original linear magnitude
180 * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
181 * (33 - 8191). The result can be seen in the following encoding table:
182 *
183 *      Biased Linear Input Code        Compressed Code
184 *      ------------------------        ---------------
185 *      00000001wxyza                   000wxyz
186 *      0000001wxyzab                   001wxyz
187 *      000001wxyzabc                   010wxyz
188 *      00001wxyzabcd                   011wxyz
189 *      0001wxyzabcde                   100wxyz
190 *      001wxyzabcdef                   101wxyz
191 *      01wxyzabcdefg                   110wxyz
192 *      1wxyzabcdefgh                   111wxyz
193 *
194 * Each biased linear code has a leading 1 which identifies the segment
195 * number. The value of the segment number is equal to 7 minus the number
196 * of leading 0's. The quantization interval is directly available as the
197 * four bits wxyz.  * The trailing bits (a - h) are ignored.
198 *
199 * Ordinarily the complement of the resulting code word is used for
200 * transmission, and so the code word is complemented before it is returned.
201 *
202 * For further information see John C. Bellamy's Digital Telephony, 1982,
203 * John Wiley & Sons, pps 98-111 and 472-476.
204 */
205static unsigned char
206linear2ulaw(
207        int             pcm_val)        /* 2's complement (16-bit range) */
208{
209        int             mask;
210        int             seg;
211        unsigned char   uval;
212
213        /* Get the sign and the magnitude of the value. */
214        if (pcm_val < 0) {
215                pcm_val = BIAS - pcm_val;
216                mask = 0x7F;
217        } else {
218                pcm_val += BIAS;
219                mask = 0xFF;
220        }
221
222        /* Convert the scaled magnitude to segment number. */
223        seg = search(pcm_val, seg_end, 8);
224
225        /*
226         * Combine the sign, segment, quantization bits;
227         * and complement the code word.
228         */
229        if (seg >= 8)           /* out of range, return maximum value. */
230                return (0x7F ^ mask);
231        else {
232                uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF);
233                return (uval ^ mask);
234        }
235
236}
237
238/*
239 * ulaw2linear() - Convert a u-law value to 16-bit linear PCM
240 *
241 * First, a biased linear code is derived from the code word. An unbiased
242 * output can then be obtained by subtracting 33 from the biased code.
243 *
244 * Note that this function expects to be passed the complement of the
245 * original code word. This is in keeping with ISDN conventions.
246 */
247static int
248ulaw2linear(
249        unsigned char   u_val)
250{
251        int             t;
252
253        /* Complement to obtain normal u-law value. */
254        u_val = ~u_val;
255
256        /*
257         * Extract and bias the quantization bits. Then
258         * shift up by the segment number and subtract out the bias.
259         */
260        t = ((u_val & QUANT_MASK) << 3) + BIAS;
261        t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
262
263        return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
264}
265
266#ifdef INTER_LAW_CONVERSION
267/* A-law to u-law conversion */
268static unsigned char
269alaw2ulaw(
270        unsigned char   aval)
271{
272        aval &= 0xff;
273        return ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) :
274            (0x7F ^ _a2u[aval ^ 0x55]));
275}
276
277/* u-law to A-law conversion */
278static unsigned char
279ulaw2alaw(
280        unsigned char   uval)
281{
282        uval &= 0xff;
283        return ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)) :
284            (0x55 ^ (_u2a[0x7F ^ uval] - 1)));
285}
286
287#endif /* INTER_LAW_CONVERSION */
288
289/****************************************************************************/
290/* RAT specific interface (Orion Hodson, November 1998)                     */
291/****************************************************************************/
292
293#include "config_unix.h"
294#include "config_win32.h"
295#include "memory.h"
296#include "util.h"
297#include "debug.h"
298#include "audio_types.h"
299#include "codec_types.h"
300#include "codec_g711.h"
301
302short         mulawtolin[256];
303unsigned char lintomulaw[65536];
304
305short         alawtolin[256];
306unsigned char lintoalaw[8192];
307
308void 
309g711_init()
310{
311        int i;
312       
313        for(i = 0; i < 256; i++)
314                mulawtolin[i] = ulaw2linear((unsigned char)i);
315
316        for(i = -32767; i < 32768; i++)
317                lintomulaw[(unsigned short)i] = linear2ulaw(i);
318
319        for(i = 0; i < 256; i++)
320                alawtolin[i] = alaw2linear((unsigned char)i);
321
322        for(i = -32767; i < 32768; i+= 8)
323                lintoalaw[(unsigned short)i>>3] = linear2alaw(i);
324
325}
326
327#define PAYLOAD(x)    (x)
328#define STATE_SIZE(x) (x)
329#define FRAME_SIZE(x) (x)
330
331static codec_format_t cs[] = {
332/* 8kHz */
333        {"Mu-law", "PCMU-8K-Mono",
334         "ITU G.711 Mu-law codec.  Sun Microsystems public implementation.",
335         PAYLOAD(0), STATE_SIZE(0), FRAME_SIZE(160), /* 20 ms */
336         {DEV_S16, 8000, 16, 1, 160 * BYTES_PER_SAMPLE}},
337        {"Mu-law", "PCMU-8K-Stereo",
338         "ITU G.711 Mu-law codec.  Sun Microsystems public implementation.",
339         CODEC_PAYLOAD_DYNAMIC, STATE_SIZE(0), FRAME_SIZE(320), /* 20 ms */
340         {DEV_S16, 8000, 16, 2, 2 * 160 * BYTES_PER_SAMPLE}},
341/* 16kHz */
342        {"Mu-law", "PCMU-16K-Mono",
343         "ITU G.711 Mu-law codec.  Sun Microsystems public implementation.",
344         CODEC_PAYLOAD_DYNAMIC, STATE_SIZE(0), FRAME_SIZE(160), /* 10 ms */
345         {DEV_S16, 16000, 16, 1, 160 * BYTES_PER_SAMPLE}},
346        {"Mu-law", "PCMU-16K-Stereo",
347         "ITU G.711 Mu-law codec.  Sun Microsystems public implementation.",
348         CODEC_PAYLOAD_DYNAMIC, STATE_SIZE(0), FRAME_SIZE(320), /* 10 ms */
349         {DEV_S16, 16000, 16, 2, 2 * 160 * BYTES_PER_SAMPLE}},
350/* 32kHz */
351        {"Mu-law", "PCMU-32K-Mono",
352         "ITU G.711 Mu-law codec.  Sun Microsystems public implementation.",
353         CODEC_PAYLOAD_DYNAMIC, STATE_SIZE(0), FRAME_SIZE(160), /* 5 ms */
354         {DEV_S16, 32000, 16, 1, 160 * BYTES_PER_SAMPLE}},
355        {"Mu-law", "PCMU-32K-Stereo",
356         "ITU G.711 Mu-law codec.  Sun Microsystems public implementation.",
357         CODEC_PAYLOAD_DYNAMIC, STATE_SIZE(0), FRAME_SIZE(320), /* 5 ms */
358         {DEV_S16, 32000, 16, 2, 2 * 160 * BYTES_PER_SAMPLE}},
359/* 48kHz */               
360        {"Mu-law", "PCMU-48K-Mono",
361         "ITU G.711 Mu-law codec.  Sun Microsystems public implementation.",
362         CODEC_PAYLOAD_DYNAMIC, STATE_SIZE(0), FRAME_SIZE(160), /* 3.333... ms */
363         {DEV_S16, 48000, 16, 1, 160 * BYTES_PER_SAMPLE}},
364        {"Mu-law", "PCMU-48K-Stereo",
365         "ITU G.711 Mu-law codec.  Sun Microsystems public implementation.",
366         CODEC_PAYLOAD_DYNAMIC, STATE_SIZE(0), FRAME_SIZE(320), /* 3.333... ms */
367         {DEV_S16, 48000, 16, 2, 2 * 160 * BYTES_PER_SAMPLE}},
368/* 8kHz */
369        {"A-law", "PCMA-8K-Mono",
370         "ITU G.711 A-law codec.  Sun Microsystems public implementation.",
371         PAYLOAD(8), STATE_SIZE(0), FRAME_SIZE(160), /* 20 ms */
372         {DEV_S16, 8000, 16, 1, 160 * BYTES_PER_SAMPLE}},
373        {"A-law", "PCMA-8K-Stereo",
374         "ITU G.711 A-law codec.  Sun Microsystems public implementation.",
375         CODEC_PAYLOAD_DYNAMIC, STATE_SIZE(0), FRAME_SIZE(320), /* 20 ms */
376         {DEV_S16, 8000, 16, 2, 2 * 160 * BYTES_PER_SAMPLE}},
377/* 16kHz */
378        {"A-law", "PCMA-16K-Mono",
379         "ITU G.711 A-law codec.  Sun Microsystems public implementation.",
380         CODEC_PAYLOAD_DYNAMIC, STATE_SIZE(0), FRAME_SIZE(160), /* 10 ms */
381         {DEV_S16, 16000, 16, 1, 160 * BYTES_PER_SAMPLE}},
382        {"A-law", "PCMA-16K-Stereo",
383         "ITU G.711 A-law codec.  Sun Microsystems public implementation.",
384         CODEC_PAYLOAD_DYNAMIC, STATE_SIZE(0), FRAME_SIZE(320), /* 10 ms */
385         {DEV_S16, 16000, 16, 2, 2 * 160 * BYTES_PER_SAMPLE}},
386/* 32kHz */
387        {"A-law", "PCMA-32K-Mono",
388         "ITU G.711 A-law codec.  Sun Microsystems public implementation.",
389         CODEC_PAYLOAD_DYNAMIC, STATE_SIZE(0), FRAME_SIZE(160), /* 5 ms */
390         {DEV_S16, 32000, 16, 1, 160 * BYTES_PER_SAMPLE}},
391        {"A-law", "PCMA-32K-Stereo",
392         "ITU G.711 A-law codec.  Sun Microsystems public implementation.",
393         CODEC_PAYLOAD_DYNAMIC, STATE_SIZE(0), FRAME_SIZE(320), /* 5 ms */
394         {DEV_S16, 32000, 16, 2, 2 * 160 * BYTES_PER_SAMPLE}},
395/* 48kHz */
396        {"A-law", "PCMA-48K-Mono",
397         "ITU G.711 A-law codec.  Sun Microsystems public implementation.",
398         CODEC_PAYLOAD_DYNAMIC, STATE_SIZE(0), FRAME_SIZE(160), /* 3.333... ms */
399         {DEV_S16, 48000, 16, 1, 160 * BYTES_PER_SAMPLE}},
400        {"A-law", "PCMA-48K-Stereo",
401         "ITU G.711 A-law codec.  Sun Microsystems public implementation.",
402         CODEC_PAYLOAD_DYNAMIC, STATE_SIZE(0), FRAME_SIZE(320), /* 3.333... ms */
403         {DEV_S16, 48000, 16, 2, 2 * 160 * BYTES_PER_SAMPLE}},
404};
405
406#define G711_NUM_FORMATS (sizeof(cs) / sizeof (codec_format_t))
407#define G711_IS_MULAW(idx)  (idx < (G711_NUM_FORMATS / 2))
408
409u_int16
410g711_get_formats_count()
411{
412        return (u_int16) G711_NUM_FORMATS;
413}
414
415const codec_format_t*
416g711_get_format(u_int16 idx)
417{
418        assert(idx < G711_NUM_FORMATS);
419        return &cs[idx];
420}
421
422int
423g711_encode (u_int16 idx, u_char *state, sample *in, coded_unit *out)
424{
425        int len, remain;
426        u_char *p;
427
428        assert(idx < G711_NUM_FORMATS);
429        UNUSED(state);
430
431        /* No difference between A-law and U-law sizes */
432        remain = len = cs[idx].mean_coded_frame_size;
433       
434        out->state     = NULL;
435        out->state_len = 0;
436        out->data      = (u_char*)block_alloc(len);
437        out->data_len  = len;
438
439        p = out->data;
440        if (G711_IS_MULAW(idx)) {
441                while(remain--) {
442                        *p = s2u(*in);
443                        p++; in++;
444                }
445        } else {
446                while(remain--) {
447                        *p = s2a(*in);
448                        p++; in++;
449                }
450        }
451       
452        return len;
453}
454
455int
456g711_decode(u_int16 idx, u_char *state, coded_unit *in, sample *out)
457{
458        int len, remain;
459        u_char *p;
460
461        assert(idx < G711_NUM_FORMATS);
462        UNUSED(state);
463
464        len = remain = cs[idx].mean_coded_frame_size;
465
466        p = in->data;
467        if (G711_IS_MULAW(idx)) {
468                while(remain--) {
469                        *out = u2s(*p);
470                        out++; p++;
471                }
472        } else {
473                while(remain--) {
474                        *out = a2s(*p);
475                        out++; p++;
476                }
477        }
478
479        return len;
480}
Note: See TracBrowser for help on using the browser.