Fix some tex errors
[asterisk-bristuff.git] / main / ulaw.c
blob18a118f60db07343d245af1a9c1bc08edba003a5
1 /*
2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2005, Digium, Inc.
6 * Mark Spencer <markster@digium.com>
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
19 /*! \file
21 * \brief u-Law to Signed linear conversion
23 * \author Mark Spencer <markster@digium.com>
26 #include "asterisk.h"
28 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
30 #include "asterisk/ulaw.h"
32 #if 0
33 /* ZEROTRAP is the military recommendation to improve the encryption
34 * of u-Law traffic. It is irrelevant with modern encryption systems
35 * like AES, and will simply degrade the signal quality.
36 * ZEROTRAP is not implemented in AST_LIN2MU and so the coding table
37 * tests will fail if you use it */
38 #define ZEROTRAP /*!< turn on the trap as per the MIL-STD */
39 #endif
41 #define BIAS 0x84 /*!< define the add-in bias for 16 bit samples */
42 #define CLIP 32635
44 #ifndef G711_NEW_ALGORITHM
46 unsigned char __ast_lin2mu[16384];
47 short __ast_mulaw[256];
49 static unsigned char linear2ulaw(short sample)
51 static int exp_lut[256] = {
52 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
53 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
54 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
55 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
56 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
57 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
58 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
59 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
60 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
61 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
62 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
63 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
64 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
65 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
66 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
67 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 };
68 int sign, exponent, mantissa;
69 unsigned char ulawbyte;
71 /* Get the sample into sign-magnitude. */
72 sign = (sample >> 8) & 0x80; /* set aside the sign */
73 if (sign != 0)
74 sample = -sample; /* get magnitude */
75 if (sample > CLIP)
76 sample = CLIP; /* clip the magnitude */
78 /* Convert from 16 bit linear to ulaw. */
79 sample = sample + BIAS;
80 exponent = exp_lut[(sample >> 7) & 0xFF];
81 mantissa = (sample >> (exponent + 3)) & 0x0F;
82 ulawbyte = ~(sign | (exponent << 4) | mantissa);
84 #ifdef ZEROTRAP
85 if (ulawbyte == 0)
86 ulawbyte = 0x02; /* optional CCITT trap */
87 #endif
89 return ulawbyte;
92 #else
94 unsigned char __ast_lin2mu[AST_ULAW_TAB_SIZE];
95 short __ast_mulaw[256];
97 static unsigned char linear2ulaw(short sample, int full_coding)
99 static const unsigned exp_lut[256] = {
100 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
101 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
102 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
103 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
104 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
105 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
106 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
107 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
108 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
109 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
110 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
111 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
112 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
113 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
114 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
115 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 };
116 unsigned sign, exponent, mantissa, mag;
117 unsigned char ulawbyte;
119 /* Get the sample into sign-magnitude. */
120 ast_ulaw_get_sign_mag(sample, &sign, &mag);
121 if (mag > CLIP)
122 mag = CLIP; /* clip the magnitude */
124 sign = (sample >> 8) & 0x80; /* set aside the sign */
125 if (sign != 0)
126 sample = -sample; /* get magnitude */
127 if (sample > CLIP)
128 sample = CLIP; /* clip the magnitude */
130 /* Convert from 16 bit linear to ulaw. */
131 mag += BIAS;
132 exponent = exp_lut[(mag >> 7) & 0xFF];
133 mantissa = (mag >> (exponent + 3)) & 0x0F;
135 if (full_coding) {
136 /* full encoding, with sign and xform */
137 ulawbyte = ~(sign | (exponent << 4) | mantissa);
138 #ifdef ZEROTRAP
139 if (ulawbyte == 0)
140 ulawbyte = 0x02; /* optional CCITT trap */
141 #endif
142 } else {
143 /* half-cooked coding -- mantissa+exponent only (for lookup tab) */
144 ulawbyte = (exponent << 4) | mantissa;
147 return ulawbyte;
150 static inline short ulaw2linear(unsigned char ulawbyte)
152 unsigned exponent, mantissa;
153 short sample;
154 static const short etab[]={0,132,396,924,1980,4092,8316,16764};
156 ulawbyte = ~ulawbyte;
157 exponent = (ulawbyte & 0x70) >> 4;
158 mantissa = ulawbyte & 0x0f;
159 sample = mantissa << (exponent + 3);
160 sample += etab[exponent];
161 if (ulawbyte & 0x80)
162 sample = -sample;
163 return sample;
165 #endif
168 * \brief Set up mu-law conversion table
170 void ast_ulaw_init(void)
172 int i;
175 * Set up mu-law conversion table
177 #ifndef G711_NEW_ALGORITHM
178 for (i = 0;i < 256;i++) {
179 short mu,e,f,y;
180 static short etab[]={0,132,396,924,1980,4092,8316,16764};
182 mu = 255-i;
183 e = (mu & 0x70)/16;
184 f = mu & 0x0f;
185 y = f * (1 << (e + 3));
186 y += etab[e];
187 if (mu & 0x80) y = -y;
188 __ast_mulaw[i] = y;
190 /* set up the reverse (mu-law) conversion table */
191 for (i = -32768; i < 32768; i++) {
192 __ast_lin2mu[((unsigned short)i) >> 2] = linear2ulaw(i);
194 #else
196 for (i = 0; i < 256; i++) {
197 __ast_mulaw[i] = ulaw2linear(i);
199 /* set up the reverse (mu-law) conversion table */
200 for (i = 0; i <= 32768; i += AST_ULAW_STEP) {
201 AST_LIN2MU_LOOKUP(i) = linear2ulaw(i, 0 /* half-cooked */);
203 #endif
205 #ifdef TEST_CODING_TABLES
206 for (i = -32768; i < 32768; ++i) {
207 #ifndef G711_NEW_ALGORITHM
208 unsigned char e1 = linear2ulaw(i);
209 #else
210 unsigned char e1 = linear2ulaw(i, 1);
211 #endif
212 short d1 = ulaw2linear(e1);
213 unsigned char e2 = AST_LIN2MU(i);
214 short d2 = ulaw2linear(e2);
215 short d3 = AST_MULAW(e1);
217 if (e1 != e2 || d1 != d3 || d2 != d3) {
218 ast_log(LOG_WARNING, "u-Law coding tables test failed on %d: e1=%u, e2=%u, d1=%d, d2=%d\n",
219 i, (unsigned)e1, (unsigned)e2, (int)d1, (int)d2);
222 ast_log(LOG_NOTICE, "u-Law coding table test complete.\n");
223 #endif /* TEST_CODING_TABLES */
225 #ifdef TEST_TANDEM_TRANSCODING
226 /* tandem transcoding test */
227 for (i = -32768; i < 32768; ++i) {
228 unsigned char e1 = AST_LIN2MU(i);
229 short d1 = AST_MULAW(e1);
230 unsigned char e2 = AST_LIN2MU(d1);
231 short d2 = AST_MULAW(e2);
232 unsigned char e3 = AST_LIN2MU(d2);
233 short d3 = AST_MULAW(e3);
235 if (i < 0 && e1 == 0x7f && e2 == 0xff && e3 == 0xff)
236 continue; /* known and normal negative 0 case */
238 if (e1 != e2 || e2 != e3 || d1 != d2 || d2 != d3) {
239 ast_log(LOG_WARNING, "u-Law tandem transcoding test failed on %d: e1=%u, e2=%u, d1=%d, d2=%d, d3=%d\n",
240 i, (unsigned)e1, (unsigned)e2, (int)d1, (int)d2, (int)d3);
243 ast_log(LOG_NOTICE, "u-Law tandem transcoding test complete.\n");
244 #endif /* TEST_TANDEM_TRANSCODING */