linux/drivers/isdn/mISDN/l1oip_codec.c
<<
>>
Prefs
   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
  30How the codec works:
  31--------------------
  32
  33The volume is increased to increase the dynamic range of the audio signal.
  34Each sample is converted to a-LAW with only 16 steps of level resolution.
  35A pair of two samples are stored in one byte.
  36
  37The first byte is stored in the upper bits, the second byte is stored in the
  38lower bits.
  39
  40To 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
  45NOTE: 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 = vmalloc(65536);
 334        table_dec = vmalloc(512);
 335        if (!table_com || !table_dec) {
 336                l1oip_4bit_free();
 337                return -ENOMEM;
 338        }
 339        memset(table_com, 0, 65536);
 340        memset(table_dec, 0, 512);
 341        /* generate compression table */
 342        i1 = 0;
 343        while (i1 < 256) {
 344                if (ulaw)
 345                        c = ulaw_to_4bit[i1];
 346                else
 347                        c = alaw_to_4bit[i1];
 348                i2 = 0;
 349                while (i2 < 256) {
 350                        table_com[(i1<<8) | i2] |= (c<<4);
 351                        table_com[(i2<<8) | i1] |= c;
 352                        i2++;
 353                }
 354                i1++;
 355        }
 356
 357        /* generate decompression table */
 358        i1 = 0;
 359        while (i1 < 16) {
 360                if (ulaw)
 361                        sample = _4bit_to_ulaw[i1];
 362                else
 363                        sample = _4bit_to_alaw[i1];
 364                i2 = 0;
 365                while (i2 < 16) {
 366                        table_dec[(i1<<4) | i2] |= (sample<<8);
 367                        table_dec[(i2<<4) | i1] |= sample;
 368                        i2++;
 369                }
 370                i1++;
 371        }
 372
 373        return 0;
 374}
 375
 376
 377