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