2
* PCM - A-Law conversion
3
* Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
5
* Wrapper for linphone Codec class by Simon Morlat <simon.morlat@linphone.org>
8
static inline int val_seg(int val)
11
val >>= 7; /*7 = 4 + 3*/
26
* s16_to_alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
28
* s16_to_alaw() accepts an 16-bit integer and encodes it as A-law data.
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
41
* For further information see John C. Bellamy's Digital Telephony, 1982,
42
* John Wiley & Sons, pps 98-111 and 472-476.
43
* G711 is designed for 13 bits input signal, this function add extra shifting to take this into account.
46
static inline unsigned char s16_to_alaw(int pcm_val)
61
if (pcm_val < 256) /*256 = 32 << 3*/
62
aval = pcm_val >> 4; /*4 = 1 + 3*/
64
/* Convert the scaled magnitude to segment number. */
65
seg = val_seg(pcm_val);
66
aval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0x0f);
72
* alaw_to_s16() - Convert an A-law value to 16-bit linear PCM
75
static inline int alaw_to_s16(unsigned char a_val)
85
seg = (t >> 4) & 0x07;
86
t = ((t & 0x0f) << 4) + 0x108;
89
return ((a_val & 0x80) ? t : -t);
92
* s16_to_ulaw() - Convert a linear PCM value to u-law
94
* In order to simplify the encoding process, the original linear magnitude
95
* is biased by adding 33 which shifts the encoding range from (0 - 8158) to
96
* (33 - 8191). The result can be seen in the following encoding table:
98
* Biased Linear Input Code Compressed Code
99
* ------------------------ ---------------
100
* 00000001wxyza 000wxyz
101
* 0000001wxyzab 001wxyz
102
* 000001wxyzabc 010wxyz
103
* 00001wxyzabcd 011wxyz
104
* 0001wxyzabcde 100wxyz
105
* 001wxyzabcdef 101wxyz
106
* 01wxyzabcdefg 110wxyz
107
* 1wxyzabcdefgh 111wxyz
109
* Each biased linear code has a leading 1 which identifies the segment
110
* number. The value of the segment number is equal to 7 minus the number
111
* of leading 0's. The quantization interval is directly available as the
112
* four bits wxyz. * The trailing bits (a - h) are ignored.
114
* Ordinarily the complement of the resulting code word is used for
115
* transmission, and so the code word is complemented before it is returned.
117
* For further information see John C. Bellamy's Digital Telephony, 1982,
118
* John Wiley & Sons, pps 98-111 and 472-476.
121
static inline unsigned char s16_to_ulaw(int pcm_val) /* 2's complement (16-bit range) */
128
pcm_val = 0x84 - pcm_val;
134
if (pcm_val > 0x7fff)
137
/* Convert the scaled magnitude to segment number. */
138
seg = val_seg(pcm_val);
141
* Combine the sign, segment, quantization bits;
142
* and complement the code word.
144
uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0x0f);
149
* ulaw_to_s16() - Convert a u-law value to 16-bit linear PCM
151
* First, a biased linear code is derived from the code word. An unbiased
152
* output can then be obtained by subtracting 33 from the biased code.
154
* Note that this function expects to be passed the complement of the
155
* original code word. This is in keeping with ISDN conventions.
157
static inline int ulaw_to_s16(unsigned char u_val)
161
/* Complement to obtain normal u-law value. */
165
* Extract and bias the quantization bits. Then
166
* shift up by the segment number and subtract out the bias.
168
t = ((u_val & 0x0f) << 3) + 0x84;
169
t <<= (u_val & 0x70) >> 4;
171
return ((u_val & 0x80) ? (0x84 - t) : (t - 0x84));