Asterisk - The Open Source Telephony Project  18.5.0
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 <[email protected]>
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 <[email protected]>
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 
49 unsigned char __ast_lin2mu[16384];
50 short __ast_mulaw[256];
51 
52 static 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 
97 unsigned char __ast_lin2mu[AST_ULAW_TAB_SIZE];
98 short __ast_mulaw[256];
99 
100 static 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 
153 static 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  */
173 void ast_ulaw_init(void)
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.
static unsigned char linear2ulaw(short sample)
Definition: ulaw.c:52
#define LOG_WARNING
Definition: logger.h:274
short __ast_mulaw[256]
Definition: ulaw.c:50
#define BIAS
Definition: ulaw.c:44
#define CLIP
Definition: ulaw.c:45
#define ast_log
Definition: astobj2.c:42
u-Law to Signed linear conversion
#define AST_MULAW(a)
Definition: ulaw.h:85
void ast_ulaw_init(void)
Set up mu-law conversion table.
Definition: ulaw.c:173
#define AST_ULAW_STEP
Definition: ulaw.h:33
unsigned char __ast_lin2mu[16384]
converts signed linear to mulaw
Definition: ulaw.c:49
#define LOG_NOTICE
Definition: logger.h:263
struct ast_frame f[16]
Definition: udptl.c:159
Support for logging to various files, console and syslog Configuration in file logger.conf.
#define AST_ULAW_TAB_SIZE
Definition: ulaw.h:34
#define AST_LIN2MU(a)
Definition: ulaw.h:49