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.
21 * \brief u-Law to Signed linear conversion
23 * \author Mark Spencer <markster@digium.com>
28 ASTERISK_FILE_VERSION(__FILE__
, "$Revision$")
30 #include "asterisk/ulaw.h"
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 */
41 #define BIAS 0x84 /*!< define the add-in bias for 16 bit samples */
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 */
74 sample
= -sample
; /* get magnitude */
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
);
86 ulawbyte
= 0x02; /* optional CCITT trap */
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
);
122 mag
= CLIP
; /* clip the magnitude */
124 sign
= (sample
>> 8) & 0x80; /* set aside the sign */
126 sample
= -sample
; /* get magnitude */
128 sample
= CLIP
; /* clip the magnitude */
130 /* Convert from 16 bit linear to ulaw. */
132 exponent
= exp_lut
[(mag
>> 7) & 0xFF];
133 mantissa
= (mag
>> (exponent
+ 3)) & 0x0F;
136 /* full encoding, with sign and xform */
137 ulawbyte
= ~(sign
| (exponent
<< 4) | mantissa
);
140 ulawbyte
= 0x02; /* optional CCITT trap */
143 /* half-cooked coding -- mantissa+exponent only (for lookup tab) */
144 ulawbyte
= (exponent
<< 4) | mantissa
;
150 static inline short ulaw2linear(unsigned char ulawbyte
)
152 unsigned exponent
, mantissa
;
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
];
168 * \brief Set up mu-law conversion table
170 void ast_ulaw_init(void)
175 * Set up mu-law conversion table
177 #ifndef G711_NEW_ALGORITHM
178 for (i
= 0;i
< 256;i
++) {
180 static short etab
[]={0,132,396,924,1980,4092,8316,16764};
185 y
= f
* (1 << (e
+ 3));
187 if (mu
& 0x80) y
= -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
);
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 */);
205 #ifdef TEST_CODING_TABLES
206 for (i
= -32768; i
< 32768; ++i
) {
207 #ifndef G711_NEW_ALGORITHM
208 unsigned char e1
= linear2ulaw(i
);
210 unsigned char e1
= linear2ulaw(i
, 1);
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 */