Fix DEBUG_THREADS when lock is acquired in __constructor__
[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 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
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