Statistics
| Branch: | Tag: | Revision:

gnuradio / gr-vocoder / lib / g7xx / g711.c @ 877683e5

History | View | Annotate | Download (7.34 KB)

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
#define        SIGN_BIT        (0x80)                /* Sign bit for a A-law byte. */
33
#define        QUANT_MASK        (0xf)                /* Quantization field mask. */
34
#define        NSEGS                (8)                /* Number of A-law segments. */
35
#define        SEG_SHIFT        (4)                /* Left shift for segment number. */
36
#define        SEG_MASK        (0x70)                /* Segment field mask. */
37

38
static short seg_end[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF,
39
                            0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};
40

41
/* copy from CCITT G.711 specifications */
42
unsigned char _u2a[128] = {                        /* u- to A-law conversions */
43
        1,        1,        2,        2,        3,        3,        4,        4,
44
        5,        5,        6,        6,        7,        7,        8,        8,
45
        9,        10,        11,        12,        13,        14,        15,        16,
46
        17,        18,        19,        20,        21,        22,        23,        24,
47
        25,        27,        29,        31,        33,        34,        35,        36,
48
        37,        38,        39,        40,        41,        42,        43,        44,
49
        46,        48,        49,        50,        51,        52,        53,        54,
50
        55,        56,        57,        58,        59,        60,        61,        62,
51
        64,        65,        66,        67,        68,        69,        70,        71,
52
        72,        73,        74,        75,        76,        77,        78,        79,
53
        81,        82,        83,        84,        85,        86,        87,        88,
54
        89,        90,        91,        92,        93,        94,        95,        96,
55
        97,        98,        99,        100,        101,        102,        103,        104,
56
        105,        106,        107,        108,        109,        110,        111,        112,
57
        113,        114,        115,        116,        117,        118,        119,        120,
58
        121,        122,        123,        124,        125,        126,        127,        128};
59

60
unsigned char _a2u[128] = {                        /* A- to u-law conversions */
61
        1,        3,        5,        7,        9,        11,        13,        15,
62
        16,        17,        18,        19,        20,        21,        22,        23,
63
        24,        25,        26,        27,        28,        29,        30,        31,
64
        32,        32,        33,        33,        34,        34,        35,        35,
65
        36,        37,        38,        39,        40,        41,        42,        43,
66
        44,        45,        46,        47,        48,        48,        49,        49,
67
        50,        51,        52,        53,        54,        55,        56,        57,
68
        58,        59,        60,        61,        62,        63,        64,        64,
69
        65,        66,        67,        68,        69,        70,        71,        72,
70
        73,        74,        75,        76,        77,        78,        79,        79,
71
        80,        81,        82,        83,        84,        85,        86,        87,
72
        88,        89,        90,        91,        92,        93,        94,        95,
73
        96,        97,        98,        99,        100,        101,        102,        103,
74
        104,        105,        106,        107,        108,        109,        110,        111,
75
        112,        113,        114,        115,        116,        117,        118,        119,
76
        120,        121,        122,        123,        124,        125,        126,        127};
77

78
static int
79
search(
80
        int                val,
81
        short                *table,
82
        int                size)
83
{
84
        int                i;
85

86
        for (i = 0; i < size; i++) {
87
                if (val <= *table++)
88
                        return (i);
89
        }
90
        return (size);
91
}
92

93
/*
94
 * linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
95
 *
96
 * linear2alaw() accepts an 16-bit integer and encodes it as A-law data.
97
 *
98
 *                Linear Input Code        Compressed Code
99
 *        ------------------------        ---------------
100
 *        0000000wxyza                        000wxyz
101
 *        0000001wxyza                        001wxyz
102
 *        000001wxyzab                        010wxyz
103
 *        00001wxyzabc                        011wxyz
104
 *        0001wxyzabcd                        100wxyz
105
 *        001wxyzabcde                        101wxyz
106
 *        01wxyzabcdef                        110wxyz
107
 *        1wxyzabcdefg                        111wxyz
108
 *
109
 * For further information see John C. Bellamy's Digital Telephony, 1982,
110
 * John Wiley & Sons, pps 98-111 and 472-476.
111
 */
112
unsigned char
113
linear2alaw(
114
        int                pcm_val)        /* 2's complement (16-bit range) */
115
{
116
        int                mask;
117
        int                seg;
118
        unsigned char        aval;
119

120
        if (pcm_val >= 0) {
121
                mask = 0xD5;                /* sign (7th) bit = 1 */
122
        } else {
123
                mask = 0x55;                /* sign bit = 0 */
124
                pcm_val = -pcm_val - 8;
125
        }
126

127
        /* Convert the scaled magnitude to segment number. */
128
        seg = search(pcm_val, seg_end, 8);
129

130
        /* Combine the sign, segment, and quantization bits. */
131

132
        if (seg >= 8)                /* out of range, return maximum value. */
133
                return (0x7F ^ mask);
134
        else {
135
                aval = seg << SEG_SHIFT;
136
                if (seg < 2)
137
                        aval |= (pcm_val >> 4) & QUANT_MASK;
138
                else
139
                        aval |= (pcm_val >> (seg + 3)) & QUANT_MASK;
140
                return (aval ^ mask);
141
        }
142
}
143

144
/*
145
 * alaw2linear() - Convert an A-law value to 16-bit linear PCM
146
 *
147
 */
148
int
149
alaw2linear(
150
        unsigned char        a_val)
151
{
152
        int                t;
153
        int                seg;
154

155
        a_val ^= 0x55;
156

157
        t = (a_val & QUANT_MASK) << 4;
158
        seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
159
        switch (seg) {
160
        case 0:
161
                t += 8;
162
                break;
163
        case 1:
164
                t += 0x108;
165
                break;
166
        default:
167
                t += 0x108;
168
                t <<= seg - 1;
169
        }
170
        return ((a_val & SIGN_BIT) ? t : -t);
171
}
172

173
#define        BIAS                (0x84)                /* Bias for linear code. */
174

175
/*
176
 * linear2ulaw() - Convert a linear PCM value to u-law
177
 *
178
 * In order to simplify the encoding process, the original linear magnitude
179
 * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
180
 * (33 - 8191). The result can be seen in the following encoding table:
181
 *
182
 *        Biased Linear Input Code        Compressed Code
183
 *        ------------------------        ---------------
184
 *        00000001wxyza                        000wxyz
185
 *        0000001wxyzab                        001wxyz
186
 *        000001wxyzabc                        010wxyz
187
 *        00001wxyzabcd                        011wxyz
188
 *        0001wxyzabcde                        100wxyz
189
 *        001wxyzabcdef                        101wxyz
190
 *        01wxyzabcdefg                        110wxyz
191
 *        1wxyzabcdefgh                        111wxyz
192
 *
193
 * Each biased linear code has a leading 1 which identifies the segment
194
 * number. The value of the segment number is equal to 7 minus the number
195
 * of leading 0's. The quantization interval is directly available as the
196
 * four bits wxyz.  * The trailing bits (a - h) are ignored.
197
 *
198
 * Ordinarily the complement of the resulting code word is used for
199
 * transmission, and so the code word is complemented before it is returned.
200
 *
201
 * For further information see John C. Bellamy's Digital Telephony, 1982,
202
 * John Wiley & Sons, pps 98-111 and 472-476.
203
 */
204
unsigned char
205
linear2ulaw(
206
        int                pcm_val)        /* 2's complement (16-bit range) */
207
{
208
        int                mask;
209
        int                seg;
210
        unsigned char        uval;
211

212
        /* Get the sign and the magnitude of the value. */
213
        if (pcm_val < 0) {
214
                pcm_val = BIAS - pcm_val;
215
                mask = 0x7F;
216
        } else {
217
                pcm_val += BIAS;
218
                mask = 0xFF;
219
        }
220

221
        /* Convert the scaled magnitude to segment number. */
222
        seg = search(pcm_val, seg_end, 8);
223

224
        /*
225
         * Combine the sign, segment, quantization bits;
226
         * and complement the code word.
227
         */
228
        if (seg >= 8)                /* out of range, return maximum value. */
229
                return (0x7F ^ mask);
230
        else {
231
                uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF);
232
                return (uval ^ mask);
233
        }
234

235
}
236

237
/*
238
 * ulaw2linear() - Convert a u-law value to 16-bit linear PCM
239
 *
240
 * First, a biased linear code is derived from the code word. An unbiased
241
 * output can then be obtained by subtracting 33 from the biased code.
242
 *
243
 * Note that this function expects to be passed the complement of the
244
 * original code word. This is in keeping with ISDN conventions.
245
 */
246
int
247
ulaw2linear(
248
        unsigned char        u_val)
249
{
250
        int                t;
251

252
        /* Complement to obtain normal u-law value. */
253
        u_val = ~u_val;
254

255
        /*
256
         * Extract and bias the quantization bits. Then
257
         * shift up by the segment number and subtract out the bias.
258
         */
259
        t = ((u_val & QUANT_MASK) << 3) + BIAS;
260
        t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
261

262
        return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
263
}
264

265
/* A-law to u-law conversion */
266
unsigned char
267
alaw2ulaw(
268
        unsigned char        aval)
269
{
270
        aval &= 0xff;
271
        return ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) :
272
            (0x7F ^ _a2u[aval ^ 0x55]));
273
}
274

275
/* u-law to A-law conversion */
276
unsigned char
277
ulaw2alaw(
278
        unsigned char        uval)
279
{
280
        uval &= 0xff;
281
        return ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)) :
282
            (0x55 ^ (_u2a[0x7F ^ uval] - 1)));
283
}