Asterisk - The Open Source Telephony Project GIT-master-7e7a603
ulaw.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 1999 - 2005, Digium, Inc.
5 *
6 * Mark Spencer <markster@digium.com>
7 *
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.
13 *
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.
17 */
18
19/*! \file
20 *
21 * \brief u-Law to Signed linear conversion
22 *
23 * \author Mark Spencer <markster@digium.com>
24 */
25
26/*** MODULEINFO
27 <support_level>core</support_level>
28 ***/
29
30#include "asterisk.h"
31
32#include "asterisk/ulaw.h"
33#include "asterisk/logger.h"
34
35#if 0
36/* ZEROTRAP is the military recommendation to improve the encryption
37 * of u-Law traffic. It is irrelevant with modern encryption systems
38 * like AES, and will simply degrade the signal quality.
39 * ZEROTRAP is not implemented in AST_LIN2MU and so the coding table
40 * tests will fail if you use it */
41#define ZEROTRAP /*!< turn on the trap as per the MIL-STD */
42#endif
43
44#define BIAS 0x84 /*!< define the add-in bias for 16 bit samples */
45#define CLIP 32635
46
47#ifndef G711_NEW_ALGORITHM
48
49unsigned char __ast_lin2mu[16384];
50short __ast_mulaw[256];
51
52static unsigned char linear2ulaw(short sample)
53{
54 static int exp_lut[256] = {
55 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
56 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
57 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
58 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
59 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
60 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
61 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
62 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
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 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
69 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
70 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 };
71 int sign, exponent, mantissa;
72 unsigned char ulawbyte;
73
74 /* Get the sample into sign-magnitude. */
75 sign = (sample >> 8) & 0x80; /* set aside the sign */
76 if (sign != 0)
77 sample = -sample; /* get magnitude */
78 if (sample > CLIP)
79 sample = CLIP; /* clip the magnitude */
80
81 /* Convert from 16 bit linear to ulaw. */
82 sample = sample + BIAS;
83 exponent = exp_lut[(sample >> 7) & 0xFF];
84 mantissa = (sample >> (exponent + 3)) & 0x0F;
85 ulawbyte = ~(sign | (exponent << 4) | mantissa);
86
87#ifdef ZEROTRAP
88 if (ulawbyte == 0)
89 ulawbyte = 0x02; /* optional CCITT trap */
90#endif
91
92 return ulawbyte;
93}
94
95#else
96
97unsigned char __ast_lin2mu[AST_ULAW_TAB_SIZE];
98short __ast_mulaw[256];
99
100static unsigned char linear2ulaw(short sample, int full_coding)
101{
102 static const unsigned exp_lut[256] = {
103 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
104 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
105 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
106 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
107 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
108 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
109 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
110 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
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 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
117 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
118 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 };
119 unsigned sign, exponent, mantissa, mag;
120 unsigned char ulawbyte;
121
122 /* Get the sample into sign-magnitude. */
123 ast_ulaw_get_sign_mag(sample, &sign, &mag);
124 if (mag > CLIP)
125 mag = CLIP; /* clip the magnitude */
126
127 sign = (sample >> 8) & 0x80; /* set aside the sign */
128 if (sign != 0)
129 sample = -sample; /* get magnitude */
130 if (sample > CLIP)
131 sample = CLIP; /* clip the magnitude */
132
133 /* Convert from 16 bit linear to ulaw. */
134 mag += BIAS;
135 exponent = exp_lut[(mag >> 7) & 0xFF];
136 mantissa = (mag >> (exponent + 3)) & 0x0F;
137
138 if (full_coding) {
139 /* full encoding, with sign and xform */
140 ulawbyte = ~(sign | (exponent << 4) | mantissa);
141#ifdef ZEROTRAP
142 if (ulawbyte == 0)
143 ulawbyte = 0x02; /* optional CCITT trap */
144#endif
145 } else {
146 /* half-cooked coding -- mantissa+exponent only (for lookup tab) */
147 ulawbyte = (exponent << 4) | mantissa;
148 }
149
150 return ulawbyte;
151}
152
153static inline short ulaw2linear(unsigned char ulawbyte)
154{
155 unsigned exponent, mantissa;
156 short sample;
157 static const short etab[]={0,132,396,924,1980,4092,8316,16764};
158
159 ulawbyte = ~ulawbyte;
160 exponent = (ulawbyte & 0x70) >> 4;
161 mantissa = ulawbyte & 0x0f;
162 sample = mantissa << (exponent + 3);
163 sample += etab[exponent];
164 if (ulawbyte & 0x80)
165 sample = -sample;
166 return sample;
167}
168#endif
169
170/*!
171 * \brief Set up mu-law conversion table
172 */
174{
175 int i;
176
177 /*
178 * Set up mu-law conversion table
179 */
180#ifndef G711_NEW_ALGORITHM
181 for (i = 0;i < 256;i++) {
182 short mu,e,f,y;
183 static const short etab[]={0,132,396,924,1980,4092,8316,16764};
184
185 mu = 255-i;
186 e = (mu & 0x70)/16;
187 f = mu & 0x0f;
188 y = f * (1 << (e + 3));
189 y += etab[e];
190 if (mu & 0x80) y = -y;
191 __ast_mulaw[i] = y;
192 }
193 /* set up the reverse (mu-law) conversion table */
194 for (i = -32768; i < 32768; i++) {
195 __ast_lin2mu[((unsigned short)i) >> 2] = linear2ulaw(i);
196 }
197#else
198
199 for (i = 0; i < 256; i++) {
200 __ast_mulaw[i] = ulaw2linear(i);
201 }
202 /* set up the reverse (mu-law) conversion table */
203 for (i = 0; i <= 32768; i += AST_ULAW_STEP) {
204 AST_LIN2MU_LOOKUP(i) = linear2ulaw(i, 0 /* half-cooked */);
205 }
206#endif
207
208#ifdef TEST_CODING_TABLES
209 for (i = -32768; i < 32768; ++i) {
210#ifndef G711_NEW_ALGORITHM
211 unsigned char e1 = linear2ulaw(i);
212#else
213 unsigned char e1 = linear2ulaw(i, 1);
214#endif
215 short d1 = ulaw2linear(e1);
216 unsigned char e2 = AST_LIN2MU(i);
217 short d2 = ulaw2linear(e2);
218 short d3 = AST_MULAW(e1);
219
220 if (e1 != e2 || d1 != d3 || d2 != d3) {
221 ast_log(LOG_WARNING, "u-Law coding tables test failed on %d: e1=%u, e2=%u, d1=%d, d2=%d\n",
222 i, (unsigned)e1, (unsigned)e2, (int)d1, (int)d2);
223 }
224 }
225 ast_log(LOG_NOTICE, "u-Law coding table test complete.\n");
226#endif /* TEST_CODING_TABLES */
227
228#ifdef TEST_TANDEM_TRANSCODING
229 /* tandem transcoding test */
230 for (i = -32768; i < 32768; ++i) {
231 unsigned char e1 = AST_LIN2MU(i);
232 short d1 = AST_MULAW(e1);
233 unsigned char e2 = AST_LIN2MU(d1);
234 short d2 = AST_MULAW(e2);
235 unsigned char e3 = AST_LIN2MU(d2);
236 short d3 = AST_MULAW(e3);
237
238 if (i < 0 && e1 == 0x7f && e2 == 0xff && e3 == 0xff)
239 continue; /* known and normal negative 0 case */
240
241 if (e1 != e2 || e2 != e3 || d1 != d2 || d2 != d3) {
242 ast_log(LOG_WARNING, "u-Law tandem transcoding test failed on %d: e1=%u, e2=%u, d1=%d, d2=%d, d3=%d\n",
243 i, (unsigned)e1, (unsigned)e2, (int)d1, (int)d2, (int)d3);
244 }
245 }
246 ast_log(LOG_NOTICE, "u-Law tandem transcoding test complete.\n");
247#endif /* TEST_TANDEM_TRANSCODING */
248}
Asterisk main include file. File version handling, generic pbx functions.
#define ast_log
Definition: astobj2.c:42
Support for logging to various files, console and syslog Configuration in file logger....
#define LOG_NOTICE
#define LOG_WARNING
static unsigned char linear2ulaw(short sample)
Definition: ulaw.c:52
short __ast_mulaw[256]
Definition: ulaw.c:50
void ast_ulaw_init(void)
Set up mu-law conversion table.
Definition: ulaw.c:173
unsigned char __ast_lin2mu[16384]
converts signed linear to mulaw
Definition: ulaw.c:49
#define BIAS
Definition: ulaw.c:44
#define CLIP
Definition: ulaw.c:45
u-Law to Signed linear conversion
#define AST_MULAW(a)
Definition: ulaw.h:85
#define AST_LIN2MU(a)
Definition: ulaw.h:49
#define AST_ULAW_STEP
Definition: ulaw.h:33
#define AST_ULAW_TAB_SIZE
Definition: ulaw.h:34