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