xref: /openbmc/linux/drivers/isdn/mISDN/l1oip_codec.c (revision a5355c27d26001865a5ac32c868c82a523c275d3)
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>
51*a5355c27SAndreas Eversberg #include <linux/in.h>
523712b42dSKarsten Keil #include "core.h"
535b834354SHannes Eder #include "l1oip.h"
543712b42dSKarsten Keil 
553712b42dSKarsten Keil /* definitions of codec. don't use calculations, code may run slower. */
563712b42dSKarsten Keil 
573712b42dSKarsten Keil static u8 *table_com;
583712b42dSKarsten Keil static u16 *table_dec;
593712b42dSKarsten Keil 
603712b42dSKarsten Keil 
613712b42dSKarsten Keil /* alaw -> ulaw */
623712b42dSKarsten Keil static u8 alaw_to_ulaw[256] =
633712b42dSKarsten Keil {
643712b42dSKarsten Keil 	0xab, 0x2b, 0xe3, 0x63, 0x8b, 0x0b, 0xc9, 0x49,
653712b42dSKarsten Keil 	0xba, 0x3a, 0xf6, 0x76, 0x9b, 0x1b, 0xd7, 0x57,
663712b42dSKarsten Keil 	0xa3, 0x23, 0xdd, 0x5d, 0x83, 0x03, 0xc1, 0x41,
673712b42dSKarsten Keil 	0xb2, 0x32, 0xeb, 0x6b, 0x93, 0x13, 0xcf, 0x4f,
683712b42dSKarsten Keil 	0xaf, 0x2f, 0xe7, 0x67, 0x8f, 0x0f, 0xcd, 0x4d,
693712b42dSKarsten Keil 	0xbe, 0x3e, 0xfe, 0x7e, 0x9f, 0x1f, 0xdb, 0x5b,
703712b42dSKarsten Keil 	0xa7, 0x27, 0xdf, 0x5f, 0x87, 0x07, 0xc5, 0x45,
713712b42dSKarsten Keil 	0xb6, 0x36, 0xef, 0x6f, 0x97, 0x17, 0xd3, 0x53,
723712b42dSKarsten Keil 	0xa9, 0x29, 0xe1, 0x61, 0x89, 0x09, 0xc7, 0x47,
733712b42dSKarsten Keil 	0xb8, 0x38, 0xf2, 0x72, 0x99, 0x19, 0xd5, 0x55,
743712b42dSKarsten Keil 	0xa1, 0x21, 0xdc, 0x5c, 0x81, 0x01, 0xbf, 0x3f,
753712b42dSKarsten Keil 	0xb0, 0x30, 0xe9, 0x69, 0x91, 0x11, 0xce, 0x4e,
763712b42dSKarsten Keil 	0xad, 0x2d, 0xe5, 0x65, 0x8d, 0x0d, 0xcb, 0x4b,
773712b42dSKarsten Keil 	0xbc, 0x3c, 0xfa, 0x7a, 0x9d, 0x1d, 0xd9, 0x59,
783712b42dSKarsten Keil 	0xa5, 0x25, 0xde, 0x5e, 0x85, 0x05, 0xc3, 0x43,
793712b42dSKarsten Keil 	0xb4, 0x34, 0xed, 0x6d, 0x95, 0x15, 0xd1, 0x51,
803712b42dSKarsten Keil 	0xac, 0x2c, 0xe4, 0x64, 0x8c, 0x0c, 0xca, 0x4a,
813712b42dSKarsten Keil 	0xbb, 0x3b, 0xf8, 0x78, 0x9c, 0x1c, 0xd8, 0x58,
823712b42dSKarsten Keil 	0xa4, 0x24, 0xde, 0x5e, 0x84, 0x04, 0xc2, 0x42,
833712b42dSKarsten Keil 	0xb3, 0x33, 0xec, 0x6c, 0x94, 0x14, 0xd0, 0x50,
843712b42dSKarsten Keil 	0xb0, 0x30, 0xe8, 0x68, 0x90, 0x10, 0xce, 0x4e,
853712b42dSKarsten Keil 	0xbf, 0x3f, 0xfe, 0x7e, 0xa0, 0x20, 0xdc, 0x5c,
863712b42dSKarsten Keil 	0xa8, 0x28, 0xe0, 0x60, 0x88, 0x08, 0xc6, 0x46,
873712b42dSKarsten Keil 	0xb7, 0x37, 0xf0, 0x70, 0x98, 0x18, 0xd4, 0x54,
883712b42dSKarsten Keil 	0xaa, 0x2a, 0xe2, 0x62, 0x8a, 0x0a, 0xc8, 0x48,
893712b42dSKarsten Keil 	0xb9, 0x39, 0xf4, 0x74, 0x9a, 0x1a, 0xd6, 0x56,
903712b42dSKarsten Keil 	0xa2, 0x22, 0xdd, 0x5d, 0x82, 0x02, 0xc0, 0x40,
913712b42dSKarsten Keil 	0xb1, 0x31, 0xea, 0x6a, 0x92, 0x12, 0xcf, 0x4f,
923712b42dSKarsten Keil 	0xae, 0x2e, 0xe6, 0x66, 0x8e, 0x0e, 0xcc, 0x4c,
933712b42dSKarsten Keil 	0xbd, 0x3d, 0xfc, 0x7c, 0x9e, 0x1e, 0xda, 0x5a,
943712b42dSKarsten Keil 	0xa6, 0x26, 0xdf, 0x5f, 0x86, 0x06, 0xc4, 0x44,
953712b42dSKarsten Keil 	0xb5, 0x35, 0xee, 0x6e, 0x96, 0x16, 0xd2, 0x52
963712b42dSKarsten Keil };
973712b42dSKarsten Keil 
983712b42dSKarsten Keil /* ulaw -> alaw */
993712b42dSKarsten Keil static u8 ulaw_to_alaw[256] =
1003712b42dSKarsten Keil {
1013712b42dSKarsten Keil 	0xab, 0x55, 0xd5, 0x15, 0x95, 0x75, 0xf5, 0x35,
1023712b42dSKarsten Keil 	0xb5, 0x45, 0xc5, 0x05, 0x85, 0x65, 0xe5, 0x25,
1033712b42dSKarsten Keil 	0xa5, 0x5d, 0xdd, 0x1d, 0x9d, 0x7d, 0xfd, 0x3d,
1043712b42dSKarsten Keil 	0xbd, 0x4d, 0xcd, 0x0d, 0x8d, 0x6d, 0xed, 0x2d,
1053712b42dSKarsten Keil 	0xad, 0x51, 0xd1, 0x11, 0x91, 0x71, 0xf1, 0x31,
1063712b42dSKarsten Keil 	0xb1, 0x41, 0xc1, 0x01, 0x81, 0x61, 0xe1, 0x21,
1073712b42dSKarsten Keil 	0x59, 0xd9, 0x19, 0x99, 0x79, 0xf9, 0x39, 0xb9,
1083712b42dSKarsten Keil 	0x49, 0xc9, 0x09, 0x89, 0x69, 0xe9, 0x29, 0xa9,
1093712b42dSKarsten Keil 	0xd7, 0x17, 0x97, 0x77, 0xf7, 0x37, 0xb7, 0x47,
1103712b42dSKarsten Keil 	0xc7, 0x07, 0x87, 0x67, 0xe7, 0x27, 0xa7, 0xdf,
1113712b42dSKarsten Keil 	0x9f, 0x7f, 0xff, 0x3f, 0xbf, 0x4f, 0xcf, 0x0f,
1123712b42dSKarsten Keil 	0x8f, 0x6f, 0xef, 0x2f, 0x53, 0x13, 0x73, 0x33,
1133712b42dSKarsten Keil 	0xb3, 0x43, 0xc3, 0x03, 0x83, 0x63, 0xe3, 0x23,
1143712b42dSKarsten Keil 	0xa3, 0x5b, 0xdb, 0x1b, 0x9b, 0x7b, 0xfb, 0x3b,
1153712b42dSKarsten Keil 	0xbb, 0xbb, 0x4b, 0x4b, 0xcb, 0xcb, 0x0b, 0x0b,
1163712b42dSKarsten Keil 	0x8b, 0x8b, 0x6b, 0x6b, 0xeb, 0xeb, 0x2b, 0x2b,
1173712b42dSKarsten Keil 	0xab, 0x54, 0xd4, 0x14, 0x94, 0x74, 0xf4, 0x34,
1183712b42dSKarsten Keil 	0xb4, 0x44, 0xc4, 0x04, 0x84, 0x64, 0xe4, 0x24,
1193712b42dSKarsten Keil 	0xa4, 0x5c, 0xdc, 0x1c, 0x9c, 0x7c, 0xfc, 0x3c,
1203712b42dSKarsten Keil 	0xbc, 0x4c, 0xcc, 0x0c, 0x8c, 0x6c, 0xec, 0x2c,
1213712b42dSKarsten Keil 	0xac, 0x50, 0xd0, 0x10, 0x90, 0x70, 0xf0, 0x30,
1223712b42dSKarsten Keil 	0xb0, 0x40, 0xc0, 0x00, 0x80, 0x60, 0xe0, 0x20,
1233712b42dSKarsten Keil 	0x58, 0xd8, 0x18, 0x98, 0x78, 0xf8, 0x38, 0xb8,
1243712b42dSKarsten Keil 	0x48, 0xc8, 0x08, 0x88, 0x68, 0xe8, 0x28, 0xa8,
1253712b42dSKarsten Keil 	0xd6, 0x16, 0x96, 0x76, 0xf6, 0x36, 0xb6, 0x46,
1263712b42dSKarsten Keil 	0xc6, 0x06, 0x86, 0x66, 0xe6, 0x26, 0xa6, 0xde,
1273712b42dSKarsten Keil 	0x9e, 0x7e, 0xfe, 0x3e, 0xbe, 0x4e, 0xce, 0x0e,
1283712b42dSKarsten Keil 	0x8e, 0x6e, 0xee, 0x2e, 0x52, 0x12, 0x72, 0x32,
1293712b42dSKarsten Keil 	0xb2, 0x42, 0xc2, 0x02, 0x82, 0x62, 0xe2, 0x22,
1303712b42dSKarsten Keil 	0xa2, 0x5a, 0xda, 0x1a, 0x9a, 0x7a, 0xfa, 0x3a,
1313712b42dSKarsten Keil 	0xba, 0xba, 0x4a, 0x4a, 0xca, 0xca, 0x0a, 0x0a,
1323712b42dSKarsten Keil 	0x8a, 0x8a, 0x6a, 0x6a, 0xea, 0xea, 0x2a, 0x2a
1333712b42dSKarsten Keil };
1343712b42dSKarsten Keil 
1353712b42dSKarsten Keil /* alaw -> 4bit compression */
1363712b42dSKarsten Keil static u8 alaw_to_4bit[256] = {
1373712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1383712b42dSKarsten Keil 	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
1393712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1403712b42dSKarsten Keil 	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
1413712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1423712b42dSKarsten Keil 	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
1433712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1443712b42dSKarsten Keil 	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
1453712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1463712b42dSKarsten Keil 	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
1473712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0d, 0x02,
1483712b42dSKarsten Keil 	0x0e, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
1493712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1503712b42dSKarsten Keil 	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
1513712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1523712b42dSKarsten Keil 	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
1533712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1543712b42dSKarsten Keil 	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
1553712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1563712b42dSKarsten Keil 	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
1573712b42dSKarsten Keil 	0x0e, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
1583712b42dSKarsten Keil 	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x01, 0x0a, 0x05,
1593712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1603712b42dSKarsten Keil 	0x0d, 0x02, 0x09, 0x07, 0x0f, 0x00, 0x0b, 0x04,
1613712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1623712b42dSKarsten Keil 	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
1633712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1643712b42dSKarsten Keil 	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
1653712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1663712b42dSKarsten Keil 	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
1673712b42dSKarsten Keil 	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
1683712b42dSKarsten Keil 	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
1693712b42dSKarsten Keil };
1703712b42dSKarsten Keil 
1713712b42dSKarsten Keil /* 4bit -> alaw decompression */
1723712b42dSKarsten Keil static u8 _4bit_to_alaw[16] = {
1733712b42dSKarsten Keil 	0x5d, 0x51, 0xd9, 0xd7, 0x5f, 0x53, 0xa3, 0x4b,
1743712b42dSKarsten Keil 	0x2a, 0x3a, 0x22, 0x2e, 0x26, 0x56, 0x20, 0x2c,
1753712b42dSKarsten Keil };
1763712b42dSKarsten Keil 
1773712b42dSKarsten Keil /* ulaw -> 4bit compression */
1783712b42dSKarsten Keil static u8 ulaw_to_4bit[256] = {
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 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1833712b42dSKarsten Keil 	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
1843712b42dSKarsten Keil 	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
1853712b42dSKarsten Keil 	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
1863712b42dSKarsten Keil 	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
1873712b42dSKarsten Keil 	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
1883712b42dSKarsten Keil 	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04,
1893712b42dSKarsten Keil 	0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
1903712b42dSKarsten Keil 	0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
1913712b42dSKarsten Keil 	0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
1923712b42dSKarsten Keil 	0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
1933712b42dSKarsten Keil 	0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
1943712b42dSKarsten Keil 	0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08,
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, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
1993712b42dSKarsten Keil 	0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
2003712b42dSKarsten Keil 	0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
2013712b42dSKarsten Keil 	0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
2023712b42dSKarsten Keil 	0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
2033712b42dSKarsten Keil 	0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
2043712b42dSKarsten Keil 	0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b,
2053712b42dSKarsten Keil 	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
2063712b42dSKarsten Keil 	0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x0a,
2073712b42dSKarsten Keil 	0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
2083712b42dSKarsten Keil 	0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
2093712b42dSKarsten Keil 	0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
2103712b42dSKarsten Keil 	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
2113712b42dSKarsten Keil };
2123712b42dSKarsten Keil 
2133712b42dSKarsten Keil /* 4bit -> ulaw decompression */
2143712b42dSKarsten Keil static u8 _4bit_to_ulaw[16] = {
2153712b42dSKarsten Keil 	0x11, 0x21, 0x31, 0x40, 0x4e, 0x5c, 0x68, 0x71,
2163712b42dSKarsten Keil 	0xfe, 0xef, 0xe7, 0xdb, 0xcd, 0xbf, 0xaf, 0x9f,
2173712b42dSKarsten Keil };
2183712b42dSKarsten Keil 
2193712b42dSKarsten Keil 
2203712b42dSKarsten Keil /*
2213712b42dSKarsten Keil  * Compresses data to the result buffer
2223712b42dSKarsten Keil  * The result size must be at least half of the input buffer.
2233712b42dSKarsten Keil  * The number of samples also must be even!
2243712b42dSKarsten Keil  */
2253712b42dSKarsten Keil int
2263712b42dSKarsten Keil l1oip_law_to_4bit(u8 *data, int len, u8 *result, u32 *state)
2273712b42dSKarsten Keil {
2283712b42dSKarsten Keil 	int ii, i = 0, o = 0;
2293712b42dSKarsten Keil 
2303712b42dSKarsten Keil 	if (!len)
2313712b42dSKarsten Keil 		return 0;
2323712b42dSKarsten Keil 
2333712b42dSKarsten Keil 	/* send saved byte and first input byte */
2343712b42dSKarsten Keil 	if (*state) {
2353712b42dSKarsten Keil 		*result++ = table_com[(((*state)<<8)&0xff00) | (*data++)];
2363712b42dSKarsten Keil 		len--;
2373712b42dSKarsten Keil 		o++;
2383712b42dSKarsten Keil 	}
2393712b42dSKarsten Keil 
2403712b42dSKarsten Keil 	ii = len >> 1;
2413712b42dSKarsten Keil 
2423712b42dSKarsten Keil 	while (i < ii) {
2433712b42dSKarsten Keil 		*result++ = table_com[(data[0]<<8) | (data[1])];
2443712b42dSKarsten Keil 		data += 2;
2453712b42dSKarsten Keil 		i++;
2463712b42dSKarsten Keil 		o++;
2473712b42dSKarsten Keil 	}
2483712b42dSKarsten Keil 
2493712b42dSKarsten Keil 	/* if len has an odd number, we save byte for next call */
2503712b42dSKarsten Keil 	if (len & 1)
2513712b42dSKarsten Keil 		*state = 0x100 + *data;
2523712b42dSKarsten Keil 	else
2533712b42dSKarsten Keil 		*state = 0;
2543712b42dSKarsten Keil 
2553712b42dSKarsten Keil 	return o;
2563712b42dSKarsten Keil }
2573712b42dSKarsten Keil 
2583712b42dSKarsten Keil /* Decompress data to the result buffer
2593712b42dSKarsten Keil  * The result size must be the number of sample in packet. (2 * input data)
2603712b42dSKarsten Keil  * The number of samples in the result are even!
2613712b42dSKarsten Keil  */
2623712b42dSKarsten Keil int
2633712b42dSKarsten Keil l1oip_4bit_to_law(u8 *data, int len, u8 *result)
2643712b42dSKarsten Keil {
2653712b42dSKarsten Keil 	int i = 0;
2663712b42dSKarsten Keil 	u16 r;
2673712b42dSKarsten Keil 
2683712b42dSKarsten Keil 	while (i < len) {
2693712b42dSKarsten Keil 		r = table_dec[*data++];
2703712b42dSKarsten Keil 		*result++ = r>>8;
2713712b42dSKarsten Keil 		*result++ = r;
2723712b42dSKarsten Keil 		i++;
2733712b42dSKarsten Keil 	}
2743712b42dSKarsten Keil 
2753712b42dSKarsten Keil 	return len << 1;
2763712b42dSKarsten Keil }
2773712b42dSKarsten Keil 
2783712b42dSKarsten Keil 
2793712b42dSKarsten Keil /*
2803712b42dSKarsten Keil  * law conversion
2813712b42dSKarsten Keil  */
2823712b42dSKarsten Keil int
2833712b42dSKarsten Keil l1oip_alaw_to_ulaw(u8 *data, int len, u8 *result)
2843712b42dSKarsten Keil {
2853712b42dSKarsten Keil 	int i = 0;
2863712b42dSKarsten Keil 
2873712b42dSKarsten Keil 	while (i < len) {
2883712b42dSKarsten Keil 		*result++ = alaw_to_ulaw[*data++];
2893712b42dSKarsten Keil 		i++;
2903712b42dSKarsten Keil 	}
2913712b42dSKarsten Keil 
2923712b42dSKarsten Keil 	return len;
2933712b42dSKarsten Keil }
2943712b42dSKarsten Keil 
2953712b42dSKarsten Keil int
2963712b42dSKarsten Keil l1oip_ulaw_to_alaw(u8 *data, int len, u8 *result)
2973712b42dSKarsten Keil {
2983712b42dSKarsten Keil 	int i = 0;
2993712b42dSKarsten Keil 
3003712b42dSKarsten Keil 	while (i < len) {
3013712b42dSKarsten Keil 		*result++ = ulaw_to_alaw[*data++];
3023712b42dSKarsten Keil 		i++;
3033712b42dSKarsten Keil 	}
3043712b42dSKarsten Keil 
3053712b42dSKarsten Keil 	return len;
3063712b42dSKarsten Keil }
3073712b42dSKarsten Keil 
3083712b42dSKarsten Keil 
3093712b42dSKarsten Keil /*
3103712b42dSKarsten Keil  * generate/free compression and decompression table
3113712b42dSKarsten Keil  */
3123712b42dSKarsten Keil void
3133712b42dSKarsten Keil l1oip_4bit_free(void)
3143712b42dSKarsten Keil {
3153712b42dSKarsten Keil 	if (table_dec)
3163712b42dSKarsten Keil 		vfree(table_dec);
3173712b42dSKarsten Keil 	if (table_com)
3183712b42dSKarsten Keil 		vfree(table_com);
3193712b42dSKarsten Keil 	table_com = NULL;
3203712b42dSKarsten Keil 	table_dec = NULL;
3213712b42dSKarsten Keil }
3223712b42dSKarsten Keil 
3233712b42dSKarsten Keil int
3243712b42dSKarsten Keil l1oip_4bit_alloc(int ulaw)
3253712b42dSKarsten Keil {
3263712b42dSKarsten Keil 	int i1, i2, c, sample;
3273712b42dSKarsten Keil 
3283712b42dSKarsten Keil 	/* in case, it is called again */
3293712b42dSKarsten Keil 	if (table_dec)
3303712b42dSKarsten Keil 		return 0;
3313712b42dSKarsten Keil 
3323712b42dSKarsten Keil 	/* alloc conversion tables */
3333712b42dSKarsten Keil 	table_com = vmalloc(65536);
3343712b42dSKarsten Keil 	table_dec = vmalloc(512);
33524ec68fbSAlexey Zaytsev 	if (!table_com || !table_dec) {
3363712b42dSKarsten Keil 		l1oip_4bit_free();
3373712b42dSKarsten Keil 		return -ENOMEM;
3383712b42dSKarsten Keil 	}
3393712b42dSKarsten Keil 	memset(table_com, 0, 65536);
3403712b42dSKarsten Keil 	memset(table_dec, 0, 512);
3413712b42dSKarsten Keil 	/* generate compression table */
3423712b42dSKarsten Keil 	i1 = 0;
3433712b42dSKarsten Keil 	while (i1 < 256) {
3443712b42dSKarsten Keil 		if (ulaw)
3453712b42dSKarsten Keil 			c = ulaw_to_4bit[i1];
3463712b42dSKarsten Keil 		else
3473712b42dSKarsten Keil 			c = alaw_to_4bit[i1];
3483712b42dSKarsten Keil 		i2 = 0;
3493712b42dSKarsten Keil 		while (i2 < 256) {
3503712b42dSKarsten Keil 			table_com[(i1<<8) | i2] |= (c<<4);
3513712b42dSKarsten Keil 			table_com[(i2<<8) | i1] |= c;
3523712b42dSKarsten Keil 			i2++;
3533712b42dSKarsten Keil 		}
3543712b42dSKarsten Keil 		i1++;
3553712b42dSKarsten Keil 	}
3563712b42dSKarsten Keil 
3573712b42dSKarsten Keil 	/* generate decompression table */
3583712b42dSKarsten Keil 	i1 = 0;
3593712b42dSKarsten Keil 	while (i1 < 16) {
3603712b42dSKarsten Keil 		if (ulaw)
3613712b42dSKarsten Keil 			sample = _4bit_to_ulaw[i1];
3623712b42dSKarsten Keil 		else
3633712b42dSKarsten Keil 			sample = _4bit_to_alaw[i1];
3643712b42dSKarsten Keil 		i2 = 0;
3653712b42dSKarsten Keil 		while (i2 < 16) {
3663712b42dSKarsten Keil 			table_dec[(i1<<4) | i2] |= (sample<<8);
3673712b42dSKarsten Keil 			table_dec[(i2<<4) | i1] |= sample;
3683712b42dSKarsten Keil 			i2++;
3693712b42dSKarsten Keil 		}
3703712b42dSKarsten Keil 		i1++;
3713712b42dSKarsten Keil 	}
3723712b42dSKarsten Keil 
3733712b42dSKarsten Keil 	return 0;
3743712b42dSKarsten Keil }
3753712b42dSKarsten Keil 
3763712b42dSKarsten Keil 
377