Wed Jan 8 2020 09:49:51

Asterisk developer's documentation


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