0be633c4c71beb1227f985ff5483a9b31d6a790c
[asterisk/asterisk.git] / main / ulaw.c
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 #include "asterisk.h"
27
28 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
29
30 #include "asterisk/ulaw.h"
31
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
40
41 #define BIAS 0x84   /*!< define the add-in bias for 16 bit samples */
42 #define CLIP 32635
43
44 #ifndef G711_NEW_ALGORITHM
45
46 unsigned char __ast_lin2mu[16384];
47 short __ast_mulaw[256];
48
49 static unsigned char linear2ulaw(short sample)
50 {
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;
70         
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 */
77         
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);
83         
84 #ifdef ZEROTRAP
85         if (ulawbyte == 0)
86                 ulawbyte = 0x02;   /* optional CCITT trap */
87 #endif
88         
89         return ulawbyte;
90 }
91
92 #else
93
94 unsigned char __ast_lin2mu[AST_ULAW_TAB_SIZE];
95 short __ast_mulaw[256];
96
97 static unsigned char linear2ulaw(short sample, int full_coding)
98 {
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;
118         
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 */
123         
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 */
129         
130         /* Convert from 16 bit linear to ulaw. */
131         mag += BIAS;
132         exponent = exp_lut[(mag >> 7) & 0xFF];
133         mantissa = (mag >> (exponent + 3)) & 0x0F;
134         
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;
145         }
146
147         return ulawbyte;
148 }
149         
150 static inline short ulaw2linear(unsigned char ulawbyte)
151 {
152         unsigned exponent, mantissa;
153         short sample;
154         static const short etab[]={0,132,396,924,1980,4092,8316,16764};
155         
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;
164 }
165 #endif
166
167 /*!
168  * \brief  Set up mu-law conversion table
169  */
170 void ast_ulaw_init(void)
171 {
172         int i;
173         
174         /*
175          *  Set up mu-law conversion table
176          */
177 #ifndef G711_NEW_ALGORITHM
178         for (i = 0;i < 256;i++) {
179                 short mu,e,f,y;
180                 static const short etab[]={0,132,396,924,1980,4092,8316,16764};
181                 
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;
189         }
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);
193         }
194 #else
195         
196         for (i = 0; i < 256; i++) {
197                 __ast_mulaw[i] = ulaw2linear(i);
198         }
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 */);
202         }
203 #endif
204         
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);
216                 
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);
220                 }
221         }
222         ast_log(LOG_NOTICE, "u-Law coding table test complete.\n");
223 #endif /* TEST_CODING_TABLES */
224         
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);
234                 
235                 if (i < 0 && e1 == 0x7f && e2 == 0xff && e3 == 0xff)
236                         continue; /* known and normal negative 0 case */
237                 
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);
241                 }
242         }
243         ast_log(LOG_NOTICE, "u-Law tandem transcoding test complete.\n");
244 #endif /* TEST_TANDEM_TRANSCODING */
245 }
246