Merge "BuildSystem: Invoke install not in GNU but POSIX style."
[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 /*** 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 }