206c8d5f7f4c089c53b203bcc65c7219732536db
[dragonfly.git] / usr.sbin / i4b / g711conv / g711conv.c
1 /*
2  *   Copyright (c) 1999 Hellmuth Michaelis. All rights reserved.
3  *
4  *   Redistribution and use in source and binary forms, with or without
5  *   modification, are permitted provided that the following conditions
6  *   are met:
7  *
8  *   1. Redistributions of source code must retain the above copyright
9  *      notice, this list of conditions and the following disclaimer.
10  *   2. Redistributions in binary form must reproduce the above copyright
11  *      notice, this list of conditions and the following disclaimer in the
12  *      documentation and/or other materials provided with the distribution.
13  *
14  *   THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  *   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  *   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  *   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  *   FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  *   OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  *   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  *   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  *   OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  *   SUCH DAMAGE.
25  *
26  *   ---
27  *
28  *   The A-law to u-law and u-law to A-law conversion routines and tables
29  *   were taken from the G.711 reference implementation from Sun and freely
30  *   available as http://www.itu.int/itudoc/itu-t/rec/g/g700-799/refimpl.txt.
31  *
32  *   Therefore for that part of the code, the following restrictions apply:
33  *
34  *
35  *   This source code is a product of Sun Microsystems, Inc. and is provided
36  *   for unrestricted use.  Users may copy or modify this source code without
37  *   charge.
38  *
39  *   SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
40  *   THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
41  *   PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
42  *
43  *   Sun source code is provided with no support and without any obligation on
44  *   the part of Sun Microsystems, Inc. to assist in its use, correction,
45  *   modification or enhancement.
46  *
47  *   SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
48  *   INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
49  *   OR ANY PART THEREOF.
50  *
51  *   In no event will Sun Microsystems, Inc. be liable for any lost revenue
52  *   or profits or other special, indirect and consequential damages, even if
53  *   Sun has been advised of the possibility of such damages.
54  *
55  *   Sun Microsystems, Inc.
56  *   2550 Garcia Avenue
57  *   Mountain View, California  94043
58  *
59  *   ---
60  *
61  *   The bitreverse table was contributed by Stefan Bethke.
62  *
63  *---------------------------------------------------------------------------
64  *
65  *      A-law / u-law conversions as specified in G.711
66  *      -----------------------------------------------
67  *
68  *      last edit-date: [Mon Dec 13 21:44:01 1999]
69  *
70  *      $Id: g711conv.c,v 1.5 1999/12/13 21:25:24 hm Exp $
71  *
72  * $FreeBSD: src/usr.sbin/i4b/g711conv/g711conv.c,v 1.4.2.1 2001/08/01 17:45:02 obrien Exp $
73  * $DragonFly: src/usr.sbin/i4b/g711conv/g711conv.c,v 1.2 2003/06/17 04:29:54 dillon Exp $
74  *
75  *---------------------------------------------------------------------------*/
76
77 #include <stdio.h>
78 #include <unistd.h>
79 #include <machine/i4b_ioctl.h>
80
81 /* copy from CCITT G.711 specifications */
82
83 /* u- to A-law conversions */
84
85 unsigned char _u2a[128] = {
86         1,      1,      2,      2,      3,      3,      4,      4,
87         5,      5,      6,      6,      7,      7,      8,      8,
88         9,      10,     11,     12,     13,     14,     15,     16,
89         17,     18,     19,     20,     21,     22,     23,     24,
90         25,     27,     29,     31,     33,     34,     35,     36,
91         37,     38,     39,     40,     41,     42,     43,     44,
92         46,     48,     49,     50,     51,     52,     53,     54,
93         55,     56,     57,     58,     59,     60,     61,     62,
94         64,     65,     66,     67,     68,     69,     70,     71,
95         72,     73,     74,     75,     76,     77,     78,     79,
96         81,     82,     83,     84,     85,     86,     87,     88,
97         89,     90,     91,     92,     93,     94,     95,     96,
98         97,     98,     99,     100,    101,    102,    103,    104,
99         105,    106,    107,    108,    109,    110,    111,    112,
100         113,    114,    115,    116,    117,    118,    119,    120,
101         121,    122,    123,    124,    125,    126,    127,    128
102 };
103
104 /* A- to u-law conversions */
105
106 unsigned char _a2u[128] = {
107         1,      3,      5,      7,      9,      11,     13,     15,
108         16,     17,     18,     19,     20,     21,     22,     23,
109         24,     25,     26,     27,     28,     29,     30,     31,
110         32,     32,     33,     33,     34,     34,     35,     35,
111         36,     37,     38,     39,     40,     41,     42,     43,
112         44,     45,     46,     47,     48,     48,     49,     49,
113         50,     51,     52,     53,     54,     55,     56,     57,
114         58,     59,     60,     61,     62,     63,     64,     64,
115         65,     66,     67,     68,     69,     70,     71,     72,
116         73,     74,     75,     76,     77,     78,     79,     79,
117         80,     81,     82,     83,     84,     85,     86,     87,
118         88,     89,     90,     91,     92,     93,     94,     95,
119         96,     97,     98,     99,     100,    101,    102,    103,
120         104,    105,    106,    107,    108,    109,    110,    111,
121         112,    113,    114,    115,    116,    117,    118,    119,
122         120,    121,    122,    123,    124,    125,    126,    127
123 };
124
125 /* reverse bits (7->0, 6->1, 5->2 etc) for tx to / rx from ISDN */
126
127 unsigned char bitreverse[256] = {
128         0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
129         0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
130         0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
131         0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
132         0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
133         0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 
134         0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
135         0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
136         0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
137         0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
138         0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
139         0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
140         0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
141         0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
142         0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
143         0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
144 };
145
146 /* A-law to u-law conversion */
147
148 unsigned char alaw2ulaw(unsigned char aval)
149 {
150         aval &= 0xff;
151         return ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) :
152                                 (0x7F ^ _a2u[aval ^ 0x55]));
153 }
154
155 /* u-law to A-law conversion */
156
157 unsigned char ulaw2alaw(unsigned char uval)
158 {
159         uval &= 0xff;
160         return ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)) :
161                                 (0x55 ^ (_u2a[0x7F ^ uval] - 1)));
162 }
163
164 void
165 usage(void)
166 {
167         fprintf(stderr, "\n");
168         fprintf(stderr, "g711conv - do conversions according to ITU G.711, (version %d.%d.%d)\n",VERSION, REL, STEP);
169         fprintf(stderr, "usage: g711conv -a -r -R -u -P\n");
170         fprintf(stderr, "       -a      A-law to u-law conversion\n");
171         fprintf(stderr, "       -r      reverse bits before conversion\n");
172         fprintf(stderr, "       -R      reverse bits after conversion\n");
173         fprintf(stderr, "       -u      u-law to A-law conversion\n");
174         fprintf(stderr, "       -P      print conversion table as C source\n"); 
175         fprintf(stderr, "\n");
176         exit(1);
177 }
178
179 int
180 main(int argc, char **argv)
181 {
182         int i;
183         int c;
184         int opt_a = 0;
185         int opt_u = 0;
186         int opt_r = 0;
187         int opt_P = 0;
188         int opt_R = 0;  
189         unsigned char uc;
190         
191         while ((c = getopt(argc, argv, "aurPR?")) != -1)
192         {
193                 switch(c)
194                 {
195                         case 'a':
196                                 opt_a = 1;
197                                 break;
198                                 
199                         case 'u':
200                                 opt_u = 1;
201                                 break;
202                                 
203                         case 'r':
204                                 opt_r = 1;
205                                 break;
206                                 
207                         case 'R':
208                                 opt_R = 1;
209                                 break;
210
211                         case 'P':
212                                 opt_P = 1;
213                                 break;
214
215                         case '?':
216                         default:
217                                 usage();
218                                 break;
219                 }
220         }
221
222         if((opt_a + opt_u) > 1)
223                 usage();
224
225         if(opt_P)
226         {               
227                 printf("\n/* ");
228                 
229                 if((opt_a + opt_u) == 0)
230                         printf("No Conversion");
231         
232                 if(opt_a)
233                         printf("A-law to u-law conversion");
234         
235                 if(opt_u)
236                         printf("u-law to A-law conversion");
237         
238                 if(opt_r)
239                         printf(", reverse bits BEFORE conversion");
240         
241                 if(opt_R)
242                         printf(", reverse bits AFTER conversion");
243
244                 if(opt_a)
245                 {
246                         printf(" */\n\nunsigned char a2u_tab[256] = {");
247                 }
248                 else if(opt_u)
249                 {
250                         printf(" */\n\nunsigned char u2a_tab[256] = {");
251                 }
252                 else
253                 {
254                         printf(" */\n\nunsigned char table[256] = {");
255                 }
256                 
257                 for(i=0; i < 256; i++)
258                 {
259                         uc = i;
260                         
261                         if(!(i % 8))
262                                 printf("\n/* %02x */\t", i);
263         
264                         if(opt_r)
265                                 uc = bitreverse[uc];
266         
267                         if(opt_u)
268                                 uc = ulaw2alaw(uc);
269         
270                         if(opt_a)
271                                 uc = alaw2ulaw(uc);
272                                 
273                         if(opt_R)
274                                 uc = bitreverse[uc];
275
276                         if(i == 255)    
277                                 printf("0x%02x", uc);
278                         else
279                                 printf("0x%02x, ", uc);
280                 }
281                 printf("\n};\n");
282         }
283         else
284         {
285                 unsigned char ib[1];
286                 
287                 while(fread(ib, 1, 1, stdin) == 1)
288                 {
289                         if(opt_r)
290                                 ib[0] = bitreverse[ib[0]];
291         
292                         if(opt_u)
293                                 ib[0] = ulaw2alaw(ib[0]);
294         
295                         if(opt_a)
296                                 ib[0] = alaw2ulaw(ib[0]);
297                                 
298                         if(opt_R)
299                                 ib[0] = bitreverse[ib[0]];
300         
301                         fwrite(ib, 1, 1, stdout);
302                 }
303         }       
304         return(0);
305 }
306
307 /* EOF */