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(addr: table_dec);
304 vfree(addr: 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(size: 65536);
320 table_dec = vzalloc(size: 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

source code of linux/drivers/isdn/mISDN/l1oip_codec.c