linux/drivers/isdn/mISDN/l1oip_codec.c
<<
>>
Prefs
   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