root/drivers/isdn/mISDN/l1oip_codec.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. l1oip_law_to_4bit
  2. l1oip_4bit_to_law
  3. l1oip_alaw_to_ulaw
  4. l1oip_ulaw_to_alaw
  5. l1oip_4bit_free
  6. l1oip_4bit_alloc

   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 
  45 static u8 *table_com;
  46 static u16 *table_dec;
  47 
  48 
  49 /* alaw -> ulaw */
  50 static 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 */
  87 static 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 */
 124 static 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 */
 160 static 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 */
 166 static 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 */
 202 static 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  */
 213 int
 214 l1oip_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  */
 250 int
 251 l1oip_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  */
 270 int
 271 l1oip_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 
 283 int
 284 l1oip_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  */
 300 void
 301 l1oip_4bit_free(void)
 302 {
 303         vfree(table_dec);
 304         vfree(table_com);
 305         table_com = NULL;
 306         table_dec = NULL;
 307 }
 308 
 309 int
 310 l1oip_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 }

/* [<][>][^][v][top][bottom][index][help] */