linux/drivers/isdn/mISDN/dsp_audio.c
<<
>>
Prefs
   1/*
   2 * Audio support data for mISDN_dsp.
   3 *
   4 * Copyright 2002/2003 by Andreas Eversberg (jolly@eversberg.eu)
   5 * Rewritten by Peter
   6 *
   7 * This software may be used and distributed according to the terms
   8 * of the GNU General Public License, incorporated herein by reference.
   9 *
  10 */
  11
  12#include <linux/delay.h>
  13#include <linux/mISDNif.h>
  14#include <linux/mISDNdsp.h>
  15#include <linux/export.h>
  16#include "core.h"
  17#include "dsp.h"
  18
  19/* ulaw[unsigned char] -> signed 16-bit */
  20s32 dsp_audio_ulaw_to_s32[256];
  21/* alaw[unsigned char] -> signed 16-bit */
  22s32 dsp_audio_alaw_to_s32[256];
  23
  24s32 *dsp_audio_law_to_s32;
  25EXPORT_SYMBOL(dsp_audio_law_to_s32);
  26
  27/* signed 16-bit -> law */
  28u8 dsp_audio_s16_to_law[65536];
  29EXPORT_SYMBOL(dsp_audio_s16_to_law);
  30
  31/* alaw -> ulaw */
  32u8 dsp_audio_alaw_to_ulaw[256];
  33/* ulaw -> alaw */
  34static u8 dsp_audio_ulaw_to_alaw[256];
  35u8 dsp_silence;
  36
  37
  38/*****************************************************
  39 * generate table for conversion of s16 to alaw/ulaw *
  40 *****************************************************/
  41
  42#define AMI_MASK 0x55
  43
  44static inline unsigned char linear2alaw(short int linear)
  45{
  46        int mask;
  47        int seg;
  48        int pcm_val;
  49        static int seg_end[8] = {
  50                0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF
  51        };
  52
  53        pcm_val = linear;
  54        if (pcm_val >= 0) {
  55                /* Sign (7th) bit = 1 */
  56                mask = AMI_MASK | 0x80;
  57        } else {
  58                /* Sign bit = 0 */
  59                mask = AMI_MASK;
  60                pcm_val = -pcm_val;
  61        }
  62
  63        /* Convert the scaled magnitude to segment number. */
  64        for (seg = 0; seg < 8; seg++) {
  65                if (pcm_val <= seg_end[seg])
  66                        break;
  67        }
  68        /* Combine the sign, segment, and quantization bits. */
  69        return  ((seg << 4) |
  70                 ((pcm_val >> ((seg)  ?  (seg + 3)  :  4)) & 0x0F)) ^ mask;
  71}
  72
  73
  74static inline short int alaw2linear(unsigned char alaw)
  75{
  76        int i;
  77        int seg;
  78
  79        alaw ^= AMI_MASK;
  80        i = ((alaw & 0x0F) << 4) + 8 /* rounding error */;
  81        seg = (((int) alaw & 0x70) >> 4);
  82        if (seg)
  83                i = (i + 0x100) << (seg - 1);
  84        return (short int) ((alaw & 0x80)  ?  i  :  -i);
  85}
  86
  87static inline short int ulaw2linear(unsigned char ulaw)
  88{
  89        short mu, e, f, y;
  90        static short etab[] = {0, 132, 396, 924, 1980, 4092, 8316, 16764};
  91
  92        mu = 255 - ulaw;
  93        e = (mu & 0x70) / 16;
  94        f = mu & 0x0f;
  95        y = f * (1 << (e + 3));
  96        y += etab[e];
  97        if (mu & 0x80)
  98                y = -y;
  99        return y;
 100}
 101
 102#define BIAS 0x84   /*!< define the add-in bias for 16 bit samples */
 103
 104static unsigned char linear2ulaw(short sample)
 105{
 106        static int exp_lut[256] = {
 107                0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
 108                4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
 109                5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
 110                5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
 111                6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
 112                6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
 113                6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
 114                6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
 115                7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 116                7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 117                7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 118                7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 119                7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 120                7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 121                7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 122                7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7};
 123        int sign, exponent, mantissa;
 124        unsigned char ulawbyte;
 125
 126        /* Get the sample into sign-magnitude. */
 127        sign = (sample >> 8) & 0x80;      /* set aside the sign */
 128        if (sign != 0)
 129                sample = -sample;             /* get magnitude */
 130
 131        /* Convert from 16 bit linear to ulaw. */
 132        sample = sample + BIAS;
 133        exponent = exp_lut[(sample >> 7) & 0xFF];
 134        mantissa = (sample >> (exponent + 3)) & 0x0F;
 135        ulawbyte = ~(sign | (exponent << 4) | mantissa);
 136
 137        return ulawbyte;
 138}
 139
 140static int reverse_bits(int i)
 141{
 142        int z, j;
 143        z = 0;
 144
 145        for (j = 0; j < 8; j++) {
 146                if ((i & (1 << j)) != 0)
 147                        z |= 1 << (7 - j);
 148        }
 149        return z;
 150}
 151
 152
 153void dsp_audio_generate_law_tables(void)
 154{
 155        int i;
 156        for (i = 0; i < 256; i++)
 157                dsp_audio_alaw_to_s32[i] = alaw2linear(reverse_bits(i));
 158
 159        for (i = 0; i < 256; i++)
 160                dsp_audio_ulaw_to_s32[i] = ulaw2linear(reverse_bits(i));
 161
 162        for (i = 0; i < 256; i++) {
 163                dsp_audio_alaw_to_ulaw[i] =
 164                        linear2ulaw(dsp_audio_alaw_to_s32[i]);
 165                dsp_audio_ulaw_to_alaw[i] =
 166                        linear2alaw(dsp_audio_ulaw_to_s32[i]);
 167        }
 168}
 169
 170void
 171dsp_audio_generate_s2law_table(void)
 172{
 173        int i;
 174
 175        if (dsp_options & DSP_OPT_ULAW) {
 176                /* generating ulaw-table */
 177                for (i = -32768; i < 32768; i++) {
 178                        dsp_audio_s16_to_law[i & 0xffff] =
 179                                reverse_bits(linear2ulaw(i));
 180                }
 181        } else {
 182                /* generating alaw-table */
 183                for (i = -32768; i < 32768; i++) {
 184                        dsp_audio_s16_to_law[i & 0xffff] =
 185                                reverse_bits(linear2alaw(i));
 186                }
 187        }
 188}
 189
 190
 191/*
 192 * the seven bit sample is the number of every second alaw-sample ordered by
 193 * aplitude. 0x00 is negative, 0x7f is positive amplitude.
 194 */
 195u8 dsp_audio_seven2law[128];
 196u8 dsp_audio_law2seven[256];
 197
 198/********************************************************************
 199 * generate table for conversion law from/to 7-bit alaw-like sample *
 200 ********************************************************************/
 201
 202void
 203dsp_audio_generate_seven(void)
 204{
 205        int i, j, k;
 206        u8 spl;
 207        u8 sorted_alaw[256];
 208
 209        /* generate alaw table, sorted by the linear value */
 210        for (i = 0; i < 256; i++) {
 211                j = 0;
 212                for (k = 0; k < 256; k++) {
 213                        if (dsp_audio_alaw_to_s32[k]
 214                            < dsp_audio_alaw_to_s32[i])
 215                                j++;
 216                }
 217                sorted_alaw[j] = i;
 218        }
 219
 220        /* generate tabels */
 221        for (i = 0; i < 256; i++) {
 222                /* spl is the source: the law-sample (converted to alaw) */
 223                spl = i;
 224                if (dsp_options & DSP_OPT_ULAW)
 225                        spl = dsp_audio_ulaw_to_alaw[i];
 226                /* find the 7-bit-sample */
 227                for (j = 0; j < 256; j++) {
 228                        if (sorted_alaw[j] == spl)
 229                                break;
 230                }
 231                /* write 7-bit audio value */
 232                dsp_audio_law2seven[i] = j >> 1;
 233        }
 234        for (i = 0; i < 128; i++) {
 235                spl = sorted_alaw[i << 1];
 236                if (dsp_options & DSP_OPT_ULAW)
 237                        spl = dsp_audio_alaw_to_ulaw[spl];
 238                dsp_audio_seven2law[i] = spl;
 239        }
 240}
 241
 242
 243/* mix 2*law -> law */
 244u8 dsp_audio_mix_law[65536];
 245
 246/******************************************************
 247 * generate mix table to mix two law samples into one *
 248 ******************************************************/
 249
 250void
 251dsp_audio_generate_mix_table(void)
 252{
 253        int i, j;
 254        s32 sample;
 255
 256        i = 0;
 257        while (i < 256) {
 258                j = 0;
 259                while (j < 256) {
 260                        sample = dsp_audio_law_to_s32[i];
 261                        sample += dsp_audio_law_to_s32[j];
 262                        if (sample > 32767)
 263                                sample = 32767;
 264                        if (sample < -32768)
 265                                sample = -32768;
 266                        dsp_audio_mix_law[(i << 8) | j] =
 267                                dsp_audio_s16_to_law[sample & 0xffff];
 268                        j++;
 269                }
 270                i++;
 271        }
 272}
 273
 274
 275/*************************************
 276 * generate different volume changes *
 277 *************************************/
 278
 279static u8 dsp_audio_reduce8[256];
 280static u8 dsp_audio_reduce7[256];
 281static u8 dsp_audio_reduce6[256];
 282static u8 dsp_audio_reduce5[256];
 283static u8 dsp_audio_reduce4[256];
 284static u8 dsp_audio_reduce3[256];
 285static u8 dsp_audio_reduce2[256];
 286static u8 dsp_audio_reduce1[256];
 287static u8 dsp_audio_increase1[256];
 288static u8 dsp_audio_increase2[256];
 289static u8 dsp_audio_increase3[256];
 290static u8 dsp_audio_increase4[256];
 291static u8 dsp_audio_increase5[256];
 292static u8 dsp_audio_increase6[256];
 293static u8 dsp_audio_increase7[256];
 294static u8 dsp_audio_increase8[256];
 295
 296static u8 *dsp_audio_volume_change[16] = {
 297        dsp_audio_reduce8,
 298        dsp_audio_reduce7,
 299        dsp_audio_reduce6,
 300        dsp_audio_reduce5,
 301        dsp_audio_reduce4,
 302        dsp_audio_reduce3,
 303        dsp_audio_reduce2,
 304        dsp_audio_reduce1,
 305        dsp_audio_increase1,
 306        dsp_audio_increase2,
 307        dsp_audio_increase3,
 308        dsp_audio_increase4,
 309        dsp_audio_increase5,
 310        dsp_audio_increase6,
 311        dsp_audio_increase7,
 312        dsp_audio_increase8,
 313};
 314
 315void
 316dsp_audio_generate_volume_changes(void)
 317{
 318        register s32 sample;
 319        int i;
 320        int num[]   = { 110, 125, 150, 175, 200, 300, 400, 500 };
 321        int denum[] = { 100, 100, 100, 100, 100, 100, 100, 100 };
 322
 323        i = 0;
 324        while (i < 256) {
 325                dsp_audio_reduce8[i] = dsp_audio_s16_to_law[
 326                        (dsp_audio_law_to_s32[i] * denum[7] / num[7]) & 0xffff];
 327                dsp_audio_reduce7[i] = dsp_audio_s16_to_law[
 328                        (dsp_audio_law_to_s32[i] * denum[6] / num[6]) & 0xffff];
 329                dsp_audio_reduce6[i] = dsp_audio_s16_to_law[
 330                        (dsp_audio_law_to_s32[i] * denum[5] / num[5]) & 0xffff];
 331                dsp_audio_reduce5[i] = dsp_audio_s16_to_law[
 332                        (dsp_audio_law_to_s32[i] * denum[4] / num[4]) & 0xffff];
 333                dsp_audio_reduce4[i] = dsp_audio_s16_to_law[
 334                        (dsp_audio_law_to_s32[i] * denum[3] / num[3]) & 0xffff];
 335                dsp_audio_reduce3[i] = dsp_audio_s16_to_law[
 336                        (dsp_audio_law_to_s32[i] * denum[2] / num[2]) & 0xffff];
 337                dsp_audio_reduce2[i] = dsp_audio_s16_to_law[
 338                        (dsp_audio_law_to_s32[i] * denum[1] / num[1]) & 0xffff];
 339                dsp_audio_reduce1[i] = dsp_audio_s16_to_law[
 340                        (dsp_audio_law_to_s32[i] * denum[0] / num[0]) & 0xffff];
 341                sample = dsp_audio_law_to_s32[i] * num[0] / denum[0];
 342                if (sample < -32768)
 343                        sample = -32768;
 344                else if (sample > 32767)
 345                        sample = 32767;
 346                dsp_audio_increase1[i] = dsp_audio_s16_to_law[sample & 0xffff];
 347                sample = dsp_audio_law_to_s32[i] * num[1] / denum[1];
 348                if (sample < -32768)
 349                        sample = -32768;
 350                else if (sample > 32767)
 351                        sample = 32767;
 352                dsp_audio_increase2[i] = dsp_audio_s16_to_law[sample & 0xffff];
 353                sample = dsp_audio_law_to_s32[i] * num[2] / denum[2];
 354                if (sample < -32768)
 355                        sample = -32768;
 356                else if (sample > 32767)
 357                        sample = 32767;
 358                dsp_audio_increase3[i] = dsp_audio_s16_to_law[sample & 0xffff];
 359                sample = dsp_audio_law_to_s32[i] * num[3] / denum[3];
 360                if (sample < -32768)
 361                        sample = -32768;
 362                else if (sample > 32767)
 363                        sample = 32767;
 364                dsp_audio_increase4[i] = dsp_audio_s16_to_law[sample & 0xffff];
 365                sample = dsp_audio_law_to_s32[i] * num[4] / denum[4];
 366                if (sample < -32768)
 367                        sample = -32768;
 368                else if (sample > 32767)
 369                        sample = 32767;
 370                dsp_audio_increase5[i] = dsp_audio_s16_to_law[sample & 0xffff];
 371                sample = dsp_audio_law_to_s32[i] * num[5] / denum[5];
 372                if (sample < -32768)
 373                        sample = -32768;
 374                else if (sample > 32767)
 375                        sample = 32767;
 376                dsp_audio_increase6[i] = dsp_audio_s16_to_law[sample & 0xffff];
 377                sample = dsp_audio_law_to_s32[i] * num[6] / denum[6];
 378                if (sample < -32768)
 379                        sample = -32768;
 380                else if (sample > 32767)
 381                        sample = 32767;
 382                dsp_audio_increase7[i] = dsp_audio_s16_to_law[sample & 0xffff];
 383                sample = dsp_audio_law_to_s32[i] * num[7] / denum[7];
 384                if (sample < -32768)
 385                        sample = -32768;
 386                else if (sample > 32767)
 387                        sample = 32767;
 388                dsp_audio_increase8[i] = dsp_audio_s16_to_law[sample & 0xffff];
 389
 390                i++;
 391        }
 392}
 393
 394
 395/**************************************
 396 * change the volume of the given skb *
 397 **************************************/
 398
 399/* this is a helper function for changing volume of skb. the range may be
 400 * -8 to 8, which is a shift to the power of 2. 0 == no volume, 3 == volume*8
 401 */
 402void
 403dsp_change_volume(struct sk_buff *skb, int volume)
 404{
 405        u8 *volume_change;
 406        int i, ii;
 407        u8 *p;
 408        int shift;
 409
 410        if (volume == 0)
 411                return;
 412
 413        /* get correct conversion table */
 414        if (volume < 0) {
 415                shift = volume + 8;
 416                if (shift < 0)
 417                        shift = 0;
 418        } else {
 419                shift = volume + 7;
 420                if (shift > 15)
 421                        shift = 15;
 422        }
 423        volume_change = dsp_audio_volume_change[shift];
 424        i = 0;
 425        ii = skb->len;
 426        p = skb->data;
 427        /* change volume */
 428        while (i < ii) {
 429                *p = volume_change[*p];
 430                p++;
 431                i++;
 432        }
 433}
 434