xref: /openbmc/linux/drivers/isdn/mISDN/l1oip_codec.c (revision 5b8343540a3d27f87a4d9d72bb39b7d4cc3dd95e)
13712b42dSKarsten Keil /*
23712b42dSKarsten Keil 
33712b42dSKarsten Keil  * l1oip_codec.c  generic codec using lookup table
43712b42dSKarsten Keil  *  -> conversion from a-Law to u-Law
53712b42dSKarsten Keil  *  -> conversion from u-Law to a-Law
63712b42dSKarsten Keil  *  -> compression by reducing the number of sample resolution to 4
73712b42dSKarsten Keil  *
83712b42dSKarsten Keil  * NOTE: It is not compatible with any standard codec like ADPCM.
93712b42dSKarsten Keil  *
103712b42dSKarsten Keil  * Author	Andreas Eversberg (jolly@eversberg.eu)
113712b42dSKarsten Keil  *
123712b42dSKarsten Keil  * This program is free software; you can redistribute it and/or modify
133712b42dSKarsten Keil  * it under the terms of the GNU General Public License as published by
143712b42dSKarsten Keil  * the Free Software Foundation; either version 2, or (at your option)
153712b42dSKarsten Keil  * any later version.
163712b42dSKarsten Keil  *
173712b42dSKarsten Keil  * This program is distributed in the hope that it will be useful,
183712b42dSKarsten Keil  * but WITHOUT ANY WARRANTY; without even the implied warranty of
193712b42dSKarsten Keil  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
203712b42dSKarsten Keil  * GNU General Public License for more details.
213712b42dSKarsten Keil  *
223712b42dSKarsten Keil  * You should have received a copy of the GNU General Public License
233712b42dSKarsten Keil  * along with this program; if not, write to the Free Software
243712b42dSKarsten Keil  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
253712b42dSKarsten Keil 
263712b42dSKarsten Keil  */
273712b42dSKarsten Keil 
283712b42dSKarsten Keil /*
293712b42dSKarsten Keil 
303712b42dSKarsten Keil How the codec works:
313712b42dSKarsten Keil --------------------
323712b42dSKarsten Keil 
333712b42dSKarsten Keil The volume is increased to increase the dynamic range of the audio signal.
343712b42dSKarsten Keil Each sample is converted to a-LAW with only 16 steps of level resolution.
353712b42dSKarsten Keil A pair of two samples are stored in one byte.
363712b42dSKarsten Keil 
373712b42dSKarsten Keil The first byte is stored in the upper bits, the second byte is stored in the
383712b42dSKarsten Keil lower bits.
393712b42dSKarsten Keil 
403712b42dSKarsten Keil To speed up compression and decompression, two lookup tables are formed:
413712b42dSKarsten Keil 
423712b42dSKarsten Keil - 16 bits index for two samples (law encoded) with 8 bit compressed result.
433712b42dSKarsten Keil - 8 bits index for one compressed data with 16 bits decompressed result.
443712b42dSKarsten Keil 
453712b42dSKarsten Keil NOTE: The bytes are handled as they are law-encoded.
463712b42dSKarsten Keil 
473712b42dSKarsten Keil */
483712b42dSKarsten Keil 
493712b42dSKarsten Keil #include <linux/vmalloc.h>
503712b42dSKarsten Keil #include <linux/mISDNif.h>
513712b42dSKarsten Keil #include "core.h"
52*5b834354SHannes Eder #include "l1oip.h"
533712b42dSKarsten Keil 
543712b42dSKarsten Keil /* definitions of codec. don't use calculations, code may run slower. */
553712b42dSKarsten Keil 
563712b42dSKarsten Keil static u8 *table_com;
573712b42dSKarsten Keil static u16 *table_dec;
583712b42dSKarsten Keil 
593712b42dSKarsten Keil 
603712b42dSKarsten Keil /* alaw -> ulaw */
613712b42dSKarsten Keil static u8 alaw_to_ulaw[256] =
623712b42dSKarsten Keil {
633712b42dSKarsten Keil 	0xab, 0x2b, 0xe3, 0x63, 0x8b, 0x0b, 0xc9, 0x49,
643712b42dSKarsten Keil 	0xba, 0x3a, 0xf6, 0x76, 0x9b, 0x1b, 0xd7, 0x57,
653712b42dSKarsten Keil 	0xa3, 0x23, 0xdd, 0x5d, 0x83, 0x03, 0xc1, 0x41,
663712b42dSKarsten Keil 	0xb2, 0x32, 0xeb, 0x6b, 0x93, 0x13, 0xcf, 0x4f,
673712b42dSKarsten Keil 	0xaf, 0x2f, 0xe7, 0x67, 0x8f, 0x0f, 0xcd, 0x4d,
683712b42dSKarsten Keil 	0xbe, 0x3e, 0xfe, 0x7e, 0x9f, 0x1f, 0xdb, 0x5b,
693712b42dSKarsten Keil 	0xa7, 0x27, 0xdf, 0x5f, 0x87, 0x07, 0xc5, 0x45,
703712b42dSKarsten Keil 	0xb6, 0x36, 0xef, 0x6f, 0x97, 0x17, 0xd3, 0x53,
713712b42dSKarsten Keil 	0xa9, 0x29, 0xe1, 0x61, 0x89, 0x09, 0xc7, 0x47,
723712b42dSKarsten Keil 	0xb8, 0x38, 0xf2, 0x72, 0x99, 0x19, 0xd5, 0x55,
733712b42dSKarsten Keil 	0xa1, 0x21, 0xdc, 0x5c, 0x81, 0x01, 0xbf, 0x3f,
743712b42dSKarsten Keil 	0xb0, 0x30, 0xe9, 0x69, 0x91, 0x11, 0xce, 0x4e,
753712b42dSKarsten Keil 	0xad, 0x2d, 0xe5, 0x65, 0x8d, 0x0d, 0xcb, 0x4b,
763712b42dSKarsten Keil 	0xbc, 0x3c, 0xfa, 0x7a, 0x9d, 0x1d, 0xd9, 0x59,
773712b42dSKarsten Keil 	0xa5, 0x25, 0xde, 0x5e, 0x85, 0x05, 0xc3, 0x43,
783712b42dSKarsten Keil 	0xb4, 0x34, 0xed, 0x6d, 0x95, 0x15, 0xd1, 0x51,
793712b42dSKarsten Keil 	0xac, 0x2c, 0xe4, 0x64, 0x8c, 0x0c, 0xca, 0x4a,
803712b42dSKarsten Keil 	0xbb, 0x3b, 0xf8, 0x78, 0x9c, 0x1c, 0xd8, 0x58,
813712b42dSKarsten Keil 	0xa4, 0x24, 0xde, 0x5e, 0x84, 0x04, 0xc2, 0x42,
823712b42dSKarsten Keil 	0xb3, 0x33, 0xec, 0x6c, 0x94, 0x14, 0xd0, 0x50,
833712b42dSKarsten Keil 	0xb0, 0x30, 0xe8, 0x68, 0x90, 0x10, 0xce, 0x4e,
843712b42dSKarsten Keil 	0xbf, 0x3f, 0xfe, 0x7e, 0xa0, 0x20, 0xdc, 0x5c,
853712b42dSKarsten Keil 	0xa8, 0x28, 0xe0, 0x60, 0x88, 0x08, 0xc6, 0x46,
863712b42dSKarsten Keil 	0xb7, 0x37, 0xf0, 0x70, 0x98, 0x18, 0xd4, 0x54,
873712b42dSKarsten Keil 	0xaa, 0x2a, 0xe2, 0x62, 0x8a, 0x0a, 0xc8, 0x48,
883712b42dSKarsten Keil 	0xb9, 0x39, 0xf4, 0x74, 0x9a, 0x1a, 0xd6, 0x56,
893712b42dSKarsten Keil 	0xa2, 0x22, 0xdd, 0x5d, 0x82, 0x02, 0xc0, 0x40,
903712b42dSKarsten Keil 	0xb1, 0x31, 0xea, 0x6a, 0x92, 0x12, 0xcf, 0x4f,
913712b42dSKarsten Keil 	0xae, 0x2e, 0xe6, 0x66, 0x8e, 0x0e, 0xcc, 0x4c,
923712b42dSKarsten Keil 	0xbd, 0x3d, 0xfc, 0x7c, 0x9e, 0x1e, 0xda, 0x5a,
933712b42dSKarsten Keil 	0xa6, 0x26, 0xdf, 0x5f, 0x86, 0x06, 0xc4, 0x44,
943712b42dSKarsten Keil 	0xb5, 0x35, 0xee, 0x6e, 0x96, 0x16, 0xd2, 0x52
953712b42dSKarsten Keil };
963712b42dSKarsten Keil 
973712b42dSKarsten Keil /* ulaw -> alaw */
983712b42dSKarsten Keil static u8 ulaw_to_alaw[256] =
993712b42dSKarsten Keil {
1003712b42dSKarsten Keil 	0xab, 0x55, 0xd5, 0x15, 0x95, 0x75, 0xf5, 0x35,
1013712b42dSKarsten Keil 	0xb5, 0x45, 0xc5, 0x05, 0x85, 0x65, 0xe5, 0x25,
1023712b42dSKarsten Keil 	0xa5, 0x5d, 0xdd, 0x1d, 0x9d, 0x7d, 0xfd, 0x3d,
1033712b42dSKarsten Keil 	0xbd, 0x4d, 0xcd, 0x0d, 0x8d, 0x6d, 0xed, 0x2d,
1043712b42dSKarsten Keil 	0xad, 0x51, 0xd1, 0x11, 0x91, 0x71, 0xf1, 0x31,
1053712b42dSKarsten Keil 	0xb1, 0x41, 0xc1, 0x01, 0x81, 0x61, 0xe1, 0x21,
1063712b42dSKarsten Keil 	0x59, 0xd9, 0x19, 0x99, 0x79, 0xf9, 0x39, 0xb9,
1073712b42dSKarsten Keil 	0x49, 0xc9, 0x09, 0x89, 0x69, 0xe9, 0x29, 0xa9,
1083712b42dSKarsten Keil 	0xd7, 0x17, 0x97, 0x77, 0xf7, 0x37, 0xb7, 0x47,
1093712b42dSKarsten Keil 	0xc7, 0x07, 0x87, 0x67, 0xe7, 0x27, 0xa7, 0xdf,
1103712b42dSKarsten Keil 	0x9f, 0x7f, 0xff, 0x3f, 0xbf, 0x4f, 0xcf, 0x0f,
1113712b42dSKarsten Keil 	0x8f, 0x6f, 0xef, 0x2f, 0x53, 0x13, 0x73, 0x33,
1123712b42dSKarsten Keil 	0xb3, 0x43, 0xc3, 0x03, 0x83, 0x63, 0xe3, 0x23,
1133712b42dSKarsten Keil 	0xa3, 0x5b, 0xdb, 0x1b, 0x9b, 0x7b, 0xfb, 0x3b,
1143712b42dSKarsten Keil 	0xbb, 0xbb, 0x4b, 0x4b, 0xcb, 0xcb, 0x0b, 0x0b,
1153712b42dSKarsten Keil 	0x8b, 0x8b, 0x6b, 0x6b, 0xeb, 0xeb, 0x2b, 0x2b,
1163712b42dSKarsten Keil 	0xab, 0x54, 0xd4, 0x14, 0x94, 0x74, 0xf4, 0x34,
1173712b42dSKarsten Keil 	0xb4, 0x44, 0xc4, 0x04, 0x84, 0x64, 0xe4, 0x24,
1183712b42dSKarsten Keil 	0xa4, 0x5c, 0xdc, 0x1c, 0x9c, 0x7c, 0xfc, 0x3c,
1193712b42dSKarsten Keil 	0xbc, 0x4c, 0xcc, 0x0c, 0x8c, 0x6c, 0xec, 0x2c,
1203712b42dSKarsten Keil 	0xac, 0x50, 0xd0, 0x10, 0x90, 0x70, 0xf0, 0x30,
1213712b42dSKarsten Keil 	0xb0, 0x40, 0xc0, 0x00, 0x80, 0x60, 0xe0, 0x20,
1223712b42dSKarsten Keil 	0x58, 0xd8, 0x18, 0x98, 0x78, 0xf8, 0x38, 0xb8,
1233712b42dSKarsten Keil 	0x48, 0xc8, 0x08, 0x88, 0x68, 0xe8, 0x28, 0xa8,
1243712b42dSKarsten Keil 	0xd6, 0x16, 0x96, 0x76, 0xf6, 0x36, 0xb6, 0x46,
1253712b42dSKarsten Keil 	0xc6, 0x06, 0x86, 0x66, 0xe6, 0x26, 0xa6, 0xde,
1263712b42dSKarsten Keil 	0x9e, 0x7e, 0xfe, 0x3e, 0xbe, 0x4e, 0xce, 0x0e,
1273712b42dSKarsten Keil 	0x8e, 0x6e, 0xee, 0x2e, 0x52, 0x12, 0x72, 0x32,
1283712b42dSKarsten Keil 	0xb2, 0x42, 0xc2, 0x02, 0x82, 0x62, 0xe2, 0x22,
1293712b42dSKarsten Keil 	0xa2, 0x5a, 0xda, 0x1a, 0x9a, 0x7a, 0xfa, 0x3a,
1303712b42dSKarsten Keil 	0xba, 0xba, 0x4a, 0x4a, 0xca, 0xca, 0x0a, 0x0a,
1313712b42dSKarsten Keil 	0x8a, 0x8a, 0x6a, 0x6a, 0xea, 0xea, 0x2a, 0x2a
1323712b42dSKarsten Keil };
1333712b42dSKarsten Keil 
1343712b42dSKarsten Keil /* alaw -> 4bit compression */
1353712b42dSKarsten Keil static u8 alaw_to_4bit[256] = {
1363712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1373712b42dSKarsten Keil 	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
1383712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1393712b42dSKarsten Keil 	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
1403712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1413712b42dSKarsten Keil 	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
1423712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1433712b42dSKarsten Keil 	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
1443712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1453712b42dSKarsten Keil 	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
1463712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0d, 0x02,
1473712b42dSKarsten Keil 	0x0e, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
1483712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1493712b42dSKarsten Keil 	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
1503712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1513712b42dSKarsten Keil 	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
1523712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1533712b42dSKarsten Keil 	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
1543712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1553712b42dSKarsten Keil 	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
1563712b42dSKarsten Keil 	0x0e, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
1573712b42dSKarsten Keil 	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x01, 0x0a, 0x05,
1583712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1593712b42dSKarsten Keil 	0x0d, 0x02, 0x09, 0x07, 0x0f, 0x00, 0x0b, 0x04,
1603712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1613712b42dSKarsten Keil 	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
1623712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1633712b42dSKarsten Keil 	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
1643712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1653712b42dSKarsten Keil 	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
1663712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1673712b42dSKarsten Keil 	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
1683712b42dSKarsten Keil };
1693712b42dSKarsten Keil 
1703712b42dSKarsten Keil /* 4bit -> alaw decompression */
1713712b42dSKarsten Keil static u8 _4bit_to_alaw[16] = {
1723712b42dSKarsten Keil 	0x5d, 0x51, 0xd9, 0xd7, 0x5f, 0x53, 0xa3, 0x4b,
1733712b42dSKarsten Keil 	0x2a, 0x3a, 0x22, 0x2e, 0x26, 0x56, 0x20, 0x2c,
1743712b42dSKarsten Keil };
1753712b42dSKarsten Keil 
1763712b42dSKarsten Keil /* ulaw -> 4bit compression */
1773712b42dSKarsten Keil static u8 ulaw_to_4bit[256] = {
1783712b42dSKarsten Keil 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1793712b42dSKarsten Keil 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1803712b42dSKarsten Keil 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1813712b42dSKarsten Keil 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1823712b42dSKarsten Keil 	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
1833712b42dSKarsten Keil 	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
1843712b42dSKarsten Keil 	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
1853712b42dSKarsten Keil 	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
1863712b42dSKarsten Keil 	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
1873712b42dSKarsten Keil 	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04,
1883712b42dSKarsten Keil 	0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
1893712b42dSKarsten Keil 	0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
1903712b42dSKarsten Keil 	0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
1913712b42dSKarsten Keil 	0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
1923712b42dSKarsten Keil 	0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
1933712b42dSKarsten Keil 	0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08,
1943712b42dSKarsten Keil 	0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
1953712b42dSKarsten Keil 	0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
1963712b42dSKarsten Keil 	0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
1973712b42dSKarsten Keil 	0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
1983712b42dSKarsten Keil 	0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
1993712b42dSKarsten Keil 	0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
2003712b42dSKarsten Keil 	0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
2013712b42dSKarsten Keil 	0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
2023712b42dSKarsten Keil 	0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
2033712b42dSKarsten Keil 	0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b,
2043712b42dSKarsten Keil 	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
2053712b42dSKarsten Keil 	0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x0a,
2063712b42dSKarsten Keil 	0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
2073712b42dSKarsten Keil 	0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
2083712b42dSKarsten Keil 	0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
2093712b42dSKarsten Keil 	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
2103712b42dSKarsten Keil };
2113712b42dSKarsten Keil 
2123712b42dSKarsten Keil /* 4bit -> ulaw decompression */
2133712b42dSKarsten Keil static u8 _4bit_to_ulaw[16] = {
2143712b42dSKarsten Keil 	0x11, 0x21, 0x31, 0x40, 0x4e, 0x5c, 0x68, 0x71,
2153712b42dSKarsten Keil 	0xfe, 0xef, 0xe7, 0xdb, 0xcd, 0xbf, 0xaf, 0x9f,
2163712b42dSKarsten Keil };
2173712b42dSKarsten Keil 
2183712b42dSKarsten Keil 
2193712b42dSKarsten Keil /*
2203712b42dSKarsten Keil  * Compresses data to the result buffer
2213712b42dSKarsten Keil  * The result size must be at least half of the input buffer.
2223712b42dSKarsten Keil  * The number of samples also must be even!
2233712b42dSKarsten Keil  */
2243712b42dSKarsten Keil int
2253712b42dSKarsten Keil l1oip_law_to_4bit(u8 *data, int len, u8 *result, u32 *state)
2263712b42dSKarsten Keil {
2273712b42dSKarsten Keil 	int ii, i = 0, o = 0;
2283712b42dSKarsten Keil 
2293712b42dSKarsten Keil 	if (!len)
2303712b42dSKarsten Keil 		return 0;
2313712b42dSKarsten Keil 
2323712b42dSKarsten Keil 	/* send saved byte and first input byte */
2333712b42dSKarsten Keil 	if (*state) {
2343712b42dSKarsten Keil 		*result++ = table_com[(((*state)<<8)&0xff00) | (*data++)];
2353712b42dSKarsten Keil 		len--;
2363712b42dSKarsten Keil 		o++;
2373712b42dSKarsten Keil 	}
2383712b42dSKarsten Keil 
2393712b42dSKarsten Keil 	ii = len >> 1;
2403712b42dSKarsten Keil 
2413712b42dSKarsten Keil 	while (i < ii) {
2423712b42dSKarsten Keil 		*result++ = table_com[(data[0]<<8) | (data[1])];
2433712b42dSKarsten Keil 		data += 2;
2443712b42dSKarsten Keil 		i++;
2453712b42dSKarsten Keil 		o++;
2463712b42dSKarsten Keil 	}
2473712b42dSKarsten Keil 
2483712b42dSKarsten Keil 	/* if len has an odd number, we save byte for next call */
2493712b42dSKarsten Keil 	if (len & 1)
2503712b42dSKarsten Keil 		*state = 0x100 + *data;
2513712b42dSKarsten Keil 	else
2523712b42dSKarsten Keil 		*state = 0;
2533712b42dSKarsten Keil 
2543712b42dSKarsten Keil 	return o;
2553712b42dSKarsten Keil }
2563712b42dSKarsten Keil 
2573712b42dSKarsten Keil /* Decompress data to the result buffer
2583712b42dSKarsten Keil  * The result size must be the number of sample in packet. (2 * input data)
2593712b42dSKarsten Keil  * The number of samples in the result are even!
2603712b42dSKarsten Keil  */
2613712b42dSKarsten Keil int
2623712b42dSKarsten Keil l1oip_4bit_to_law(u8 *data, int len, u8 *result)
2633712b42dSKarsten Keil {
2643712b42dSKarsten Keil 	int i = 0;
2653712b42dSKarsten Keil 	u16 r;
2663712b42dSKarsten Keil 
2673712b42dSKarsten Keil 	while (i < len) {
2683712b42dSKarsten Keil 		r = table_dec[*data++];
2693712b42dSKarsten Keil 		*result++ = r>>8;
2703712b42dSKarsten Keil 		*result++ = r;
2713712b42dSKarsten Keil 		i++;
2723712b42dSKarsten Keil 	}
2733712b42dSKarsten Keil 
2743712b42dSKarsten Keil 	return len << 1;
2753712b42dSKarsten Keil }
2763712b42dSKarsten Keil 
2773712b42dSKarsten Keil 
2783712b42dSKarsten Keil /*
2793712b42dSKarsten Keil  * law conversion
2803712b42dSKarsten Keil  */
2813712b42dSKarsten Keil int
2823712b42dSKarsten Keil l1oip_alaw_to_ulaw(u8 *data, int len, u8 *result)
2833712b42dSKarsten Keil {
2843712b42dSKarsten Keil 	int i = 0;
2853712b42dSKarsten Keil 
2863712b42dSKarsten Keil 	while (i < len) {
2873712b42dSKarsten Keil 		*result++ = alaw_to_ulaw[*data++];
2883712b42dSKarsten Keil 		i++;
2893712b42dSKarsten Keil 	}
2903712b42dSKarsten Keil 
2913712b42dSKarsten Keil 	return len;
2923712b42dSKarsten Keil }
2933712b42dSKarsten Keil 
2943712b42dSKarsten Keil int
2953712b42dSKarsten Keil l1oip_ulaw_to_alaw(u8 *data, int len, u8 *result)
2963712b42dSKarsten Keil {
2973712b42dSKarsten Keil 	int i = 0;
2983712b42dSKarsten Keil 
2993712b42dSKarsten Keil 	while (i < len) {
3003712b42dSKarsten Keil 		*result++ = ulaw_to_alaw[*data++];
3013712b42dSKarsten Keil 		i++;
3023712b42dSKarsten Keil 	}
3033712b42dSKarsten Keil 
3043712b42dSKarsten Keil 	return len;
3053712b42dSKarsten Keil }
3063712b42dSKarsten Keil 
3073712b42dSKarsten Keil 
3083712b42dSKarsten Keil /*
3093712b42dSKarsten Keil  * generate/free compression and decompression table
3103712b42dSKarsten Keil  */
3113712b42dSKarsten Keil void
3123712b42dSKarsten Keil l1oip_4bit_free(void)
3133712b42dSKarsten Keil {
3143712b42dSKarsten Keil 	if (table_dec)
3153712b42dSKarsten Keil 		vfree(table_dec);
3163712b42dSKarsten Keil 	if (table_com)
3173712b42dSKarsten Keil 		vfree(table_com);
3183712b42dSKarsten Keil 	table_com = NULL;
3193712b42dSKarsten Keil 	table_dec = NULL;
3203712b42dSKarsten Keil }
3213712b42dSKarsten Keil 
3223712b42dSKarsten Keil int
3233712b42dSKarsten Keil l1oip_4bit_alloc(int ulaw)
3243712b42dSKarsten Keil {
3253712b42dSKarsten Keil 	int i1, i2, c, sample;
3263712b42dSKarsten Keil 
3273712b42dSKarsten Keil 	/* in case, it is called again */
3283712b42dSKarsten Keil 	if (table_dec)
3293712b42dSKarsten Keil 		return 0;
3303712b42dSKarsten Keil 
3313712b42dSKarsten Keil 	/* alloc conversion tables */
3323712b42dSKarsten Keil 	table_com = vmalloc(65536);
3333712b42dSKarsten Keil 	table_dec = vmalloc(512);
3343712b42dSKarsten Keil 	if (!table_com | !table_dec) {
3353712b42dSKarsten Keil 		l1oip_4bit_free();
3363712b42dSKarsten Keil 		return -ENOMEM;
3373712b42dSKarsten Keil 	}
3383712b42dSKarsten Keil 	memset(table_com, 0, 65536);
3393712b42dSKarsten Keil 	memset(table_dec, 0, 512);
3403712b42dSKarsten Keil 	/* generate compression table */
3413712b42dSKarsten Keil 	i1 = 0;
3423712b42dSKarsten Keil 	while (i1 < 256) {
3433712b42dSKarsten Keil 		if (ulaw)
3443712b42dSKarsten Keil 			c = ulaw_to_4bit[i1];
3453712b42dSKarsten Keil 		else
3463712b42dSKarsten Keil 			c = alaw_to_4bit[i1];
3473712b42dSKarsten Keil 		i2 = 0;
3483712b42dSKarsten Keil 		while (i2 < 256) {
3493712b42dSKarsten Keil 			table_com[(i1<<8) | i2] |= (c<<4);
3503712b42dSKarsten Keil 			table_com[(i2<<8) | i1] |= c;
3513712b42dSKarsten Keil 			i2++;
3523712b42dSKarsten Keil 		}
3533712b42dSKarsten Keil 		i1++;
3543712b42dSKarsten Keil 	}
3553712b42dSKarsten Keil 
3563712b42dSKarsten Keil 	/* generate decompression table */
3573712b42dSKarsten Keil 	i1 = 0;
3583712b42dSKarsten Keil 	while (i1 < 16) {
3593712b42dSKarsten Keil 		if (ulaw)
3603712b42dSKarsten Keil 			sample = _4bit_to_ulaw[i1];
3613712b42dSKarsten Keil 		else
3623712b42dSKarsten Keil 			sample = _4bit_to_alaw[i1];
3633712b42dSKarsten Keil 		i2 = 0;
3643712b42dSKarsten Keil 		while (i2 < 16) {
3653712b42dSKarsten Keil 			table_dec[(i1<<4) | i2] |= (sample<<8);
3663712b42dSKarsten Keil 			table_dec[(i2<<4) | i1] |= sample;
3673712b42dSKarsten Keil 			i2++;
3683712b42dSKarsten Keil 		}
3693712b42dSKarsten Keil 		i1++;
3703712b42dSKarsten Keil 	}
3713712b42dSKarsten Keil 
3723712b42dSKarsten Keil 	return 0;
3733712b42dSKarsten Keil }
3743712b42dSKarsten Keil 
3753712b42dSKarsten Keil 
376