1/*
2
3 * l1oip_codec.c  generic codec using lookup table
4 *  -> conversion from a-Law to u-Law
5 *  -> conversion from u-Law to a-Law
6 *  -> compression by reducing the number of sample resolution to 4
7 *
8 * NOTE: It is not compatible with any standard codec like ADPCM.
9 *
10 * Author	Andreas Eversberg (jolly@eversberg.eu)
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2, or (at your option)
15 * any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26 */
27
28/*
29
30  How the codec works:
31  --------------------
32
33  The volume is increased to increase the dynamic range of the audio signal.
34  Each sample is converted to a-LAW with only 16 steps of level resolution.
35  A pair of two samples are stored in one byte.
36
37  The first byte is stored in the upper bits, the second byte is stored in the
38  lower bits.
39
40  To speed up compression and decompression, two lookup tables are formed:
41
42  - 16 bits index for two samples (law encoded) with 8 bit compressed result.
43  - 8 bits index for one compressed data with 16 bits decompressed result.
44
45  NOTE: The bytes are handled as they are law-encoded.
46
47*/
48
49#include <linux/vmalloc.h>
50#include <linux/mISDNif.h>
51#include <linux/in.h>
52#include "core.h"
53#include "l1oip.h"
54
55/* definitions of codec. don't use calculations, code may run slower. */
56
57static u8 *table_com;
58static u16 *table_dec;
59
60
61/* alaw -> ulaw */
62static u8 alaw_to_ulaw[256] =
63{
64	0xab, 0x2b, 0xe3, 0x63, 0x8b, 0x0b, 0xc9, 0x49,
65	0xba, 0x3a, 0xf6, 0x76, 0x9b, 0x1b, 0xd7, 0x57,
66	0xa3, 0x23, 0xdd, 0x5d, 0x83, 0x03, 0xc1, 0x41,
67	0xb2, 0x32, 0xeb, 0x6b, 0x93, 0x13, 0xcf, 0x4f,
68	0xaf, 0x2f, 0xe7, 0x67, 0x8f, 0x0f, 0xcd, 0x4d,
69	0xbe, 0x3e, 0xfe, 0x7e, 0x9f, 0x1f, 0xdb, 0x5b,
70	0xa7, 0x27, 0xdf, 0x5f, 0x87, 0x07, 0xc5, 0x45,
71	0xb6, 0x36, 0xef, 0x6f, 0x97, 0x17, 0xd3, 0x53,
72	0xa9, 0x29, 0xe1, 0x61, 0x89, 0x09, 0xc7, 0x47,
73	0xb8, 0x38, 0xf2, 0x72, 0x99, 0x19, 0xd5, 0x55,
74	0xa1, 0x21, 0xdc, 0x5c, 0x81, 0x01, 0xbf, 0x3f,
75	0xb0, 0x30, 0xe9, 0x69, 0x91, 0x11, 0xce, 0x4e,
76	0xad, 0x2d, 0xe5, 0x65, 0x8d, 0x0d, 0xcb, 0x4b,
77	0xbc, 0x3c, 0xfa, 0x7a, 0x9d, 0x1d, 0xd9, 0x59,
78	0xa5, 0x25, 0xde, 0x5e, 0x85, 0x05, 0xc3, 0x43,
79	0xb4, 0x34, 0xed, 0x6d, 0x95, 0x15, 0xd1, 0x51,
80	0xac, 0x2c, 0xe4, 0x64, 0x8c, 0x0c, 0xca, 0x4a,
81	0xbb, 0x3b, 0xf8, 0x78, 0x9c, 0x1c, 0xd8, 0x58,
82	0xa4, 0x24, 0xde, 0x5e, 0x84, 0x04, 0xc2, 0x42,
83	0xb3, 0x33, 0xec, 0x6c, 0x94, 0x14, 0xd0, 0x50,
84	0xb0, 0x30, 0xe8, 0x68, 0x90, 0x10, 0xce, 0x4e,
85	0xbf, 0x3f, 0xfe, 0x7e, 0xa0, 0x20, 0xdc, 0x5c,
86	0xa8, 0x28, 0xe0, 0x60, 0x88, 0x08, 0xc6, 0x46,
87	0xb7, 0x37, 0xf0, 0x70, 0x98, 0x18, 0xd4, 0x54,
88	0xaa, 0x2a, 0xe2, 0x62, 0x8a, 0x0a, 0xc8, 0x48,
89	0xb9, 0x39, 0xf4, 0x74, 0x9a, 0x1a, 0xd6, 0x56,
90	0xa2, 0x22, 0xdd, 0x5d, 0x82, 0x02, 0xc0, 0x40,
91	0xb1, 0x31, 0xea, 0x6a, 0x92, 0x12, 0xcf, 0x4f,
92	0xae, 0x2e, 0xe6, 0x66, 0x8e, 0x0e, 0xcc, 0x4c,
93	0xbd, 0x3d, 0xfc, 0x7c, 0x9e, 0x1e, 0xda, 0x5a,
94	0xa6, 0x26, 0xdf, 0x5f, 0x86, 0x06, 0xc4, 0x44,
95	0xb5, 0x35, 0xee, 0x6e, 0x96, 0x16, 0xd2, 0x52
96};
97
98/* ulaw -> alaw */
99static u8 ulaw_to_alaw[256] =
100{
101	0xab, 0x55, 0xd5, 0x15, 0x95, 0x75, 0xf5, 0x35,
102	0xb5, 0x45, 0xc5, 0x05, 0x85, 0x65, 0xe5, 0x25,
103	0xa5, 0x5d, 0xdd, 0x1d, 0x9d, 0x7d, 0xfd, 0x3d,
104	0xbd, 0x4d, 0xcd, 0x0d, 0x8d, 0x6d, 0xed, 0x2d,
105	0xad, 0x51, 0xd1, 0x11, 0x91, 0x71, 0xf1, 0x31,
106	0xb1, 0x41, 0xc1, 0x01, 0x81, 0x61, 0xe1, 0x21,
107	0x59, 0xd9, 0x19, 0x99, 0x79, 0xf9, 0x39, 0xb9,
108	0x49, 0xc9, 0x09, 0x89, 0x69, 0xe9, 0x29, 0xa9,
109	0xd7, 0x17, 0x97, 0x77, 0xf7, 0x37, 0xb7, 0x47,
110	0xc7, 0x07, 0x87, 0x67, 0xe7, 0x27, 0xa7, 0xdf,
111	0x9f, 0x7f, 0xff, 0x3f, 0xbf, 0x4f, 0xcf, 0x0f,
112	0x8f, 0x6f, 0xef, 0x2f, 0x53, 0x13, 0x73, 0x33,
113	0xb3, 0x43, 0xc3, 0x03, 0x83, 0x63, 0xe3, 0x23,
114	0xa3, 0x5b, 0xdb, 0x1b, 0x9b, 0x7b, 0xfb, 0x3b,
115	0xbb, 0xbb, 0x4b, 0x4b, 0xcb, 0xcb, 0x0b, 0x0b,
116	0x8b, 0x8b, 0x6b, 0x6b, 0xeb, 0xeb, 0x2b, 0x2b,
117	0xab, 0x54, 0xd4, 0x14, 0x94, 0x74, 0xf4, 0x34,
118	0xb4, 0x44, 0xc4, 0x04, 0x84, 0x64, 0xe4, 0x24,
119	0xa4, 0x5c, 0xdc, 0x1c, 0x9c, 0x7c, 0xfc, 0x3c,
120	0xbc, 0x4c, 0xcc, 0x0c, 0x8c, 0x6c, 0xec, 0x2c,
121	0xac, 0x50, 0xd0, 0x10, 0x90, 0x70, 0xf0, 0x30,
122	0xb0, 0x40, 0xc0, 0x00, 0x80, 0x60, 0xe0, 0x20,
123	0x58, 0xd8, 0x18, 0x98, 0x78, 0xf8, 0x38, 0xb8,
124	0x48, 0xc8, 0x08, 0x88, 0x68, 0xe8, 0x28, 0xa8,
125	0xd6, 0x16, 0x96, 0x76, 0xf6, 0x36, 0xb6, 0x46,
126	0xc6, 0x06, 0x86, 0x66, 0xe6, 0x26, 0xa6, 0xde,
127	0x9e, 0x7e, 0xfe, 0x3e, 0xbe, 0x4e, 0xce, 0x0e,
128	0x8e, 0x6e, 0xee, 0x2e, 0x52, 0x12, 0x72, 0x32,
129	0xb2, 0x42, 0xc2, 0x02, 0x82, 0x62, 0xe2, 0x22,
130	0xa2, 0x5a, 0xda, 0x1a, 0x9a, 0x7a, 0xfa, 0x3a,
131	0xba, 0xba, 0x4a, 0x4a, 0xca, 0xca, 0x0a, 0x0a,
132	0x8a, 0x8a, 0x6a, 0x6a, 0xea, 0xea, 0x2a, 0x2a
133};
134
135/* alaw -> 4bit compression */
136static u8 alaw_to_4bit[256] = {
137	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
138	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
139	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
140	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
141	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
142	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
143	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
144	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
145	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
146	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
147	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0d, 0x02,
148	0x0e, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
149	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
150	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
151	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
152	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
153	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
154	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
155	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
156	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
157	0x0e, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
158	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x01, 0x0a, 0x05,
159	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
160	0x0d, 0x02, 0x09, 0x07, 0x0f, 0x00, 0x0b, 0x04,
161	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
162	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
163	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
164	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
165	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
166	0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
167	0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
168	0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
169};
170
171/* 4bit -> alaw decompression */
172static u8 _4bit_to_alaw[16] = {
173	0x5d, 0x51, 0xd9, 0xd7, 0x5f, 0x53, 0xa3, 0x4b,
174	0x2a, 0x3a, 0x22, 0x2e, 0x26, 0x56, 0x20, 0x2c,
175};
176
177/* ulaw -> 4bit compression */
178static u8 ulaw_to_4bit[256] = {
179	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
180	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
181	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
182	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
183	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
184	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
185	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
186	0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
187	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
188	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04,
189	0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
190	0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
191	0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
192	0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
193	0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
194	0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08,
195	0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
196	0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
197	0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
198	0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
199	0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
200	0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
201	0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
202	0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
203	0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
204	0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b,
205	0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
206	0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x0a,
207	0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
208	0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
209	0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
210	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
211};
212
213/* 4bit -> ulaw decompression */
214static u8 _4bit_to_ulaw[16] = {
215	0x11, 0x21, 0x31, 0x40, 0x4e, 0x5c, 0x68, 0x71,
216	0xfe, 0xef, 0xe7, 0xdb, 0xcd, 0xbf, 0xaf, 0x9f,
217};
218
219
220/*
221 * Compresses data to the result buffer
222 * The result size must be at least half of the input buffer.
223 * The number of samples also must be even!
224 */
225int
226l1oip_law_to_4bit(u8 *data, int len, u8 *result, u32 *state)
227{
228	int ii, i = 0, o = 0;
229
230	if (!len)
231		return 0;
232
233	/* send saved byte and first input byte */
234	if (*state) {
235		*result++ = table_com[(((*state) << 8) & 0xff00) | (*data++)];
236		len--;
237		o++;
238	}
239
240	ii = len >> 1;
241
242	while (i < ii) {
243		*result++ = table_com[(data[0]<<8) | (data[1])];
244		data += 2;
245		i++;
246		o++;
247	}
248
249	/* if len has an odd number, we save byte for next call */
250	if (len & 1)
251		*state = 0x100 + *data;
252	else
253		*state = 0;
254
255	return o;
256}
257
258/* Decompress data to the result buffer
259 * The result size must be the number of sample in packet. (2 * input data)
260 * The number of samples in the result are even!
261 */
262int
263l1oip_4bit_to_law(u8 *data, int len, u8 *result)
264{
265	int i = 0;
266	u16 r;
267
268	while (i < len) {
269		r = table_dec[*data++];
270		*result++ = r >> 8;
271		*result++ = r;
272		i++;
273	}
274
275	return len << 1;
276}
277
278
279/*
280 * law conversion
281 */
282int
283l1oip_alaw_to_ulaw(u8 *data, int len, u8 *result)
284{
285	int i = 0;
286
287	while (i < len) {
288		*result++ = alaw_to_ulaw[*data++];
289		i++;
290	}
291
292	return len;
293}
294
295int
296l1oip_ulaw_to_alaw(u8 *data, int len, u8 *result)
297{
298	int i = 0;
299
300	while (i < len) {
301		*result++ = ulaw_to_alaw[*data++];
302		i++;
303	}
304
305	return len;
306}
307
308
309/*
310 * generate/free compression and decompression table
311 */
312void
313l1oip_4bit_free(void)
314{
315	if (table_dec)
316		vfree(table_dec);
317	if (table_com)
318		vfree(table_com);
319	table_com = NULL;
320	table_dec = NULL;
321}
322
323int
324l1oip_4bit_alloc(int ulaw)
325{
326	int i1, i2, c, sample;
327
328	/* in case, it is called again */
329	if (table_dec)
330		return 0;
331
332	/* alloc conversion tables */
333	table_com = vzalloc(65536);
334	table_dec = vzalloc(512);
335	if (!table_com || !table_dec) {
336		l1oip_4bit_free();
337		return -ENOMEM;
338	}
339	/* generate compression table */
340	i1 = 0;
341	while (i1 < 256) {
342		if (ulaw)
343			c = ulaw_to_4bit[i1];
344		else
345			c = alaw_to_4bit[i1];
346		i2 = 0;
347		while (i2 < 256) {
348			table_com[(i1 << 8) | i2] |= (c << 4);
349			table_com[(i2 << 8) | i1] |= c;
350			i2++;
351		}
352		i1++;
353	}
354
355	/* generate decompression table */
356	i1 = 0;
357	while (i1 < 16) {
358		if (ulaw)
359			sample = _4bit_to_ulaw[i1];
360		else
361			sample = _4bit_to_alaw[i1];
362		i2 = 0;
363		while (i2 < 16) {
364			table_dec[(i1 << 4) | i2] |= (sample << 8);
365			table_dec[(i2 << 4) | i1] |= sample;
366			i2++;
367		}
368		i1++;
369	}
370
371	return 0;
372}
373