1 /* $Id: isdn_audio.c,v 1.1.2.2 2004/01/12 22:37:18 keil Exp $
 
   3  * Linux ISDN subsystem, audio conversion and compression (linklevel).
 
   5  * Copyright 1994-1999 by Fritz Elfert (fritz@isdn4linux.de)
 
   6  * DTMF code (c) 1996 by Christian Mock (cm@kukuruz.ping.at)
 
   7  * Silence detection (c) 1998 by Armin Schindler (mac@gismo.telekom.de)
 
   9  * This software may be used and distributed according to the terms
 
  10  * of the GNU General Public License, incorporated herein by reference.
 
  14 #include <linux/isdn.h>
 
  15 #include "isdn_audio.h"
 
  16 #include "isdn_common.h"
 
  18 char *isdn_audio_revision = "$Revision: 1.1.2.2 $";
 
  21  * Misc. lookup-tables.
 
  24 /* ulaw -> signed 16-bit */
 
  25 static short isdn_audio_ulaw_to_s16[] =
 
  27         0x8284, 0x8684, 0x8a84, 0x8e84, 0x9284, 0x9684, 0x9a84, 0x9e84,
 
  28         0xa284, 0xa684, 0xaa84, 0xae84, 0xb284, 0xb684, 0xba84, 0xbe84,
 
  29         0xc184, 0xc384, 0xc584, 0xc784, 0xc984, 0xcb84, 0xcd84, 0xcf84,
 
  30         0xd184, 0xd384, 0xd584, 0xd784, 0xd984, 0xdb84, 0xdd84, 0xdf84,
 
  31         0xe104, 0xe204, 0xe304, 0xe404, 0xe504, 0xe604, 0xe704, 0xe804,
 
  32         0xe904, 0xea04, 0xeb04, 0xec04, 0xed04, 0xee04, 0xef04, 0xf004,
 
  33         0xf0c4, 0xf144, 0xf1c4, 0xf244, 0xf2c4, 0xf344, 0xf3c4, 0xf444,
 
  34         0xf4c4, 0xf544, 0xf5c4, 0xf644, 0xf6c4, 0xf744, 0xf7c4, 0xf844,
 
  35         0xf8a4, 0xf8e4, 0xf924, 0xf964, 0xf9a4, 0xf9e4, 0xfa24, 0xfa64,
 
  36         0xfaa4, 0xfae4, 0xfb24, 0xfb64, 0xfba4, 0xfbe4, 0xfc24, 0xfc64,
 
  37         0xfc94, 0xfcb4, 0xfcd4, 0xfcf4, 0xfd14, 0xfd34, 0xfd54, 0xfd74,
 
  38         0xfd94, 0xfdb4, 0xfdd4, 0xfdf4, 0xfe14, 0xfe34, 0xfe54, 0xfe74,
 
  39         0xfe8c, 0xfe9c, 0xfeac, 0xfebc, 0xfecc, 0xfedc, 0xfeec, 0xfefc,
 
  40         0xff0c, 0xff1c, 0xff2c, 0xff3c, 0xff4c, 0xff5c, 0xff6c, 0xff7c,
 
  41         0xff88, 0xff90, 0xff98, 0xffa0, 0xffa8, 0xffb0, 0xffb8, 0xffc0,
 
  42         0xffc8, 0xffd0, 0xffd8, 0xffe0, 0xffe8, 0xfff0, 0xfff8, 0x0000,
 
  43         0x7d7c, 0x797c, 0x757c, 0x717c, 0x6d7c, 0x697c, 0x657c, 0x617c,
 
  44         0x5d7c, 0x597c, 0x557c, 0x517c, 0x4d7c, 0x497c, 0x457c, 0x417c,
 
  45         0x3e7c, 0x3c7c, 0x3a7c, 0x387c, 0x367c, 0x347c, 0x327c, 0x307c,
 
  46         0x2e7c, 0x2c7c, 0x2a7c, 0x287c, 0x267c, 0x247c, 0x227c, 0x207c,
 
  47         0x1efc, 0x1dfc, 0x1cfc, 0x1bfc, 0x1afc, 0x19fc, 0x18fc, 0x17fc,
 
  48         0x16fc, 0x15fc, 0x14fc, 0x13fc, 0x12fc, 0x11fc, 0x10fc, 0x0ffc,
 
  49         0x0f3c, 0x0ebc, 0x0e3c, 0x0dbc, 0x0d3c, 0x0cbc, 0x0c3c, 0x0bbc,
 
  50         0x0b3c, 0x0abc, 0x0a3c, 0x09bc, 0x093c, 0x08bc, 0x083c, 0x07bc,
 
  51         0x075c, 0x071c, 0x06dc, 0x069c, 0x065c, 0x061c, 0x05dc, 0x059c,
 
  52         0x055c, 0x051c, 0x04dc, 0x049c, 0x045c, 0x041c, 0x03dc, 0x039c,
 
  53         0x036c, 0x034c, 0x032c, 0x030c, 0x02ec, 0x02cc, 0x02ac, 0x028c,
 
  54         0x026c, 0x024c, 0x022c, 0x020c, 0x01ec, 0x01cc, 0x01ac, 0x018c,
 
  55         0x0174, 0x0164, 0x0154, 0x0144, 0x0134, 0x0124, 0x0114, 0x0104,
 
  56         0x00f4, 0x00e4, 0x00d4, 0x00c4, 0x00b4, 0x00a4, 0x0094, 0x0084,
 
  57         0x0078, 0x0070, 0x0068, 0x0060, 0x0058, 0x0050, 0x0048, 0x0040,
 
  58         0x0038, 0x0030, 0x0028, 0x0020, 0x0018, 0x0010, 0x0008, 0x0000
 
  61 /* alaw -> signed 16-bit */
 
  62 static short isdn_audio_alaw_to_s16[] =
 
  64         0x13fc, 0xec04, 0x0144, 0xfebc, 0x517c, 0xae84, 0x051c, 0xfae4,
 
  65         0x0a3c, 0xf5c4, 0x0048, 0xffb8, 0x287c, 0xd784, 0x028c, 0xfd74,
 
  66         0x1bfc, 0xe404, 0x01cc, 0xfe34, 0x717c, 0x8e84, 0x071c, 0xf8e4,
 
  67         0x0e3c, 0xf1c4, 0x00c4, 0xff3c, 0x387c, 0xc784, 0x039c, 0xfc64,
 
  68         0x0ffc, 0xf004, 0x0104, 0xfefc, 0x417c, 0xbe84, 0x041c, 0xfbe4,
 
  69         0x083c, 0xf7c4, 0x0008, 0xfff8, 0x207c, 0xdf84, 0x020c, 0xfdf4,
 
  70         0x17fc, 0xe804, 0x018c, 0xfe74, 0x617c, 0x9e84, 0x061c, 0xf9e4,
 
  71         0x0c3c, 0xf3c4, 0x0084, 0xff7c, 0x307c, 0xcf84, 0x030c, 0xfcf4,
 
  72         0x15fc, 0xea04, 0x0164, 0xfe9c, 0x597c, 0xa684, 0x059c, 0xfa64,
 
  73         0x0b3c, 0xf4c4, 0x0068, 0xff98, 0x2c7c, 0xd384, 0x02cc, 0xfd34,
 
  74         0x1dfc, 0xe204, 0x01ec, 0xfe14, 0x797c, 0x8684, 0x07bc, 0xf844,
 
  75         0x0f3c, 0xf0c4, 0x00e4, 0xff1c, 0x3c7c, 0xc384, 0x03dc, 0xfc24,
 
  76         0x11fc, 0xee04, 0x0124, 0xfedc, 0x497c, 0xb684, 0x049c, 0xfb64,
 
  77         0x093c, 0xf6c4, 0x0028, 0xffd8, 0x247c, 0xdb84, 0x024c, 0xfdb4,
 
  78         0x19fc, 0xe604, 0x01ac, 0xfe54, 0x697c, 0x9684, 0x069c, 0xf964,
 
  79         0x0d3c, 0xf2c4, 0x00a4, 0xff5c, 0x347c, 0xcb84, 0x034c, 0xfcb4,
 
  80         0x12fc, 0xed04, 0x0134, 0xfecc, 0x4d7c, 0xb284, 0x04dc, 0xfb24,
 
  81         0x09bc, 0xf644, 0x0038, 0xffc8, 0x267c, 0xd984, 0x026c, 0xfd94,
 
  82         0x1afc, 0xe504, 0x01ac, 0xfe54, 0x6d7c, 0x9284, 0x06dc, 0xf924,
 
  83         0x0dbc, 0xf244, 0x00b4, 0xff4c, 0x367c, 0xc984, 0x036c, 0xfc94,
 
  84         0x0f3c, 0xf0c4, 0x00f4, 0xff0c, 0x3e7c, 0xc184, 0x03dc, 0xfc24,
 
  85         0x07bc, 0xf844, 0x0008, 0xfff8, 0x1efc, 0xe104, 0x01ec, 0xfe14,
 
  86         0x16fc, 0xe904, 0x0174, 0xfe8c, 0x5d7c, 0xa284, 0x05dc, 0xfa24,
 
  87         0x0bbc, 0xf444, 0x0078, 0xff88, 0x2e7c, 0xd184, 0x02ec, 0xfd14,
 
  88         0x14fc, 0xeb04, 0x0154, 0xfeac, 0x557c, 0xaa84, 0x055c, 0xfaa4,
 
  89         0x0abc, 0xf544, 0x0058, 0xffa8, 0x2a7c, 0xd584, 0x02ac, 0xfd54,
 
  90         0x1cfc, 0xe304, 0x01cc, 0xfe34, 0x757c, 0x8a84, 0x075c, 0xf8a4,
 
  91         0x0ebc, 0xf144, 0x00d4, 0xff2c, 0x3a7c, 0xc584, 0x039c, 0xfc64,
 
  92         0x10fc, 0xef04, 0x0114, 0xfeec, 0x457c, 0xba84, 0x045c, 0xfba4,
 
  93         0x08bc, 0xf744, 0x0018, 0xffe8, 0x227c, 0xdd84, 0x022c, 0xfdd4,
 
  94         0x18fc, 0xe704, 0x018c, 0xfe74, 0x657c, 0x9a84, 0x065c, 0xf9a4,
 
  95         0x0cbc, 0xf344, 0x0094, 0xff6c, 0x327c, 0xcd84, 0x032c, 0xfcd4
 
  99 static char isdn_audio_alaw_to_ulaw[] =
 
 101         0xab, 0x2b, 0xe3, 0x63, 0x8b, 0x0b, 0xc9, 0x49,
 
 102         0xba, 0x3a, 0xf6, 0x76, 0x9b, 0x1b, 0xd7, 0x57,
 
 103         0xa3, 0x23, 0xdd, 0x5d, 0x83, 0x03, 0xc1, 0x41,
 
 104         0xb2, 0x32, 0xeb, 0x6b, 0x93, 0x13, 0xcf, 0x4f,
 
 105         0xaf, 0x2f, 0xe7, 0x67, 0x8f, 0x0f, 0xcd, 0x4d,
 
 106         0xbe, 0x3e, 0xfe, 0x7e, 0x9f, 0x1f, 0xdb, 0x5b,
 
 107         0xa7, 0x27, 0xdf, 0x5f, 0x87, 0x07, 0xc5, 0x45,
 
 108         0xb6, 0x36, 0xef, 0x6f, 0x97, 0x17, 0xd3, 0x53,
 
 109         0xa9, 0x29, 0xe1, 0x61, 0x89, 0x09, 0xc7, 0x47,
 
 110         0xb8, 0x38, 0xf2, 0x72, 0x99, 0x19, 0xd5, 0x55,
 
 111         0xa1, 0x21, 0xdc, 0x5c, 0x81, 0x01, 0xbf, 0x3f,
 
 112         0xb0, 0x30, 0xe9, 0x69, 0x91, 0x11, 0xce, 0x4e,
 
 113         0xad, 0x2d, 0xe5, 0x65, 0x8d, 0x0d, 0xcb, 0x4b,
 
 114         0xbc, 0x3c, 0xfa, 0x7a, 0x9d, 0x1d, 0xd9, 0x59,
 
 115         0xa5, 0x25, 0xde, 0x5e, 0x85, 0x05, 0xc3, 0x43,
 
 116         0xb4, 0x34, 0xed, 0x6d, 0x95, 0x15, 0xd1, 0x51,
 
 117         0xac, 0x2c, 0xe4, 0x64, 0x8c, 0x0c, 0xca, 0x4a,
 
 118         0xbb, 0x3b, 0xf8, 0x78, 0x9c, 0x1c, 0xd8, 0x58,
 
 119         0xa4, 0x24, 0xde, 0x5e, 0x84, 0x04, 0xc2, 0x42,
 
 120         0xb3, 0x33, 0xec, 0x6c, 0x94, 0x14, 0xd0, 0x50,
 
 121         0xb0, 0x30, 0xe8, 0x68, 0x90, 0x10, 0xce, 0x4e,
 
 122         0xbf, 0x3f, 0xfe, 0x7e, 0xa0, 0x20, 0xdc, 0x5c,
 
 123         0xa8, 0x28, 0xe0, 0x60, 0x88, 0x08, 0xc6, 0x46,
 
 124         0xb7, 0x37, 0xf0, 0x70, 0x98, 0x18, 0xd4, 0x54,
 
 125         0xaa, 0x2a, 0xe2, 0x62, 0x8a, 0x0a, 0xc8, 0x48,
 
 126         0xb9, 0x39, 0xf4, 0x74, 0x9a, 0x1a, 0xd6, 0x56,
 
 127         0xa2, 0x22, 0xdd, 0x5d, 0x82, 0x02, 0xc0, 0x40,
 
 128         0xb1, 0x31, 0xea, 0x6a, 0x92, 0x12, 0xcf, 0x4f,
 
 129         0xae, 0x2e, 0xe6, 0x66, 0x8e, 0x0e, 0xcc, 0x4c,
 
 130         0xbd, 0x3d, 0xfc, 0x7c, 0x9e, 0x1e, 0xda, 0x5a,
 
 131         0xa6, 0x26, 0xdf, 0x5f, 0x86, 0x06, 0xc4, 0x44,
 
 132         0xb5, 0x35, 0xee, 0x6e, 0x96, 0x16, 0xd2, 0x52
 
 136 static char isdn_audio_ulaw_to_alaw[] =
 
 138         0xab, 0x55, 0xd5, 0x15, 0x95, 0x75, 0xf5, 0x35,
 
 139         0xb5, 0x45, 0xc5, 0x05, 0x85, 0x65, 0xe5, 0x25,
 
 140         0xa5, 0x5d, 0xdd, 0x1d, 0x9d, 0x7d, 0xfd, 0x3d,
 
 141         0xbd, 0x4d, 0xcd, 0x0d, 0x8d, 0x6d, 0xed, 0x2d,
 
 142         0xad, 0x51, 0xd1, 0x11, 0x91, 0x71, 0xf1, 0x31,
 
 143         0xb1, 0x41, 0xc1, 0x01, 0x81, 0x61, 0xe1, 0x21,
 
 144         0x59, 0xd9, 0x19, 0x99, 0x79, 0xf9, 0x39, 0xb9,
 
 145         0x49, 0xc9, 0x09, 0x89, 0x69, 0xe9, 0x29, 0xa9,
 
 146         0xd7, 0x17, 0x97, 0x77, 0xf7, 0x37, 0xb7, 0x47,
 
 147         0xc7, 0x07, 0x87, 0x67, 0xe7, 0x27, 0xa7, 0xdf,
 
 148         0x9f, 0x7f, 0xff, 0x3f, 0xbf, 0x4f, 0xcf, 0x0f,
 
 149         0x8f, 0x6f, 0xef, 0x2f, 0x53, 0x13, 0x73, 0x33,
 
 150         0xb3, 0x43, 0xc3, 0x03, 0x83, 0x63, 0xe3, 0x23,
 
 151         0xa3, 0x5b, 0xdb, 0x1b, 0x9b, 0x7b, 0xfb, 0x3b,
 
 152         0xbb, 0xbb, 0x4b, 0x4b, 0xcb, 0xcb, 0x0b, 0x0b,
 
 153         0x8b, 0x8b, 0x6b, 0x6b, 0xeb, 0xeb, 0x2b, 0x2b,
 
 154         0xab, 0x54, 0xd4, 0x14, 0x94, 0x74, 0xf4, 0x34,
 
 155         0xb4, 0x44, 0xc4, 0x04, 0x84, 0x64, 0xe4, 0x24,
 
 156         0xa4, 0x5c, 0xdc, 0x1c, 0x9c, 0x7c, 0xfc, 0x3c,
 
 157         0xbc, 0x4c, 0xcc, 0x0c, 0x8c, 0x6c, 0xec, 0x2c,
 
 158         0xac, 0x50, 0xd0, 0x10, 0x90, 0x70, 0xf0, 0x30,
 
 159         0xb0, 0x40, 0xc0, 0x00, 0x80, 0x60, 0xe0, 0x20,
 
 160         0x58, 0xd8, 0x18, 0x98, 0x78, 0xf8, 0x38, 0xb8,
 
 161         0x48, 0xc8, 0x08, 0x88, 0x68, 0xe8, 0x28, 0xa8,
 
 162         0xd6, 0x16, 0x96, 0x76, 0xf6, 0x36, 0xb6, 0x46,
 
 163         0xc6, 0x06, 0x86, 0x66, 0xe6, 0x26, 0xa6, 0xde,
 
 164         0x9e, 0x7e, 0xfe, 0x3e, 0xbe, 0x4e, 0xce, 0x0e,
 
 165         0x8e, 0x6e, 0xee, 0x2e, 0x52, 0x12, 0x72, 0x32,
 
 166         0xb2, 0x42, 0xc2, 0x02, 0x82, 0x62, 0xe2, 0x22,
 
 167         0xa2, 0x5a, 0xda, 0x1a, 0x9a, 0x7a, 0xfa, 0x3a,
 
 168         0xba, 0xba, 0x4a, 0x4a, 0xca, 0xca, 0x0a, 0x0a,
 
 169         0x8a, 0x8a, 0x6a, 0x6a, 0xea, 0xea, 0x2a, 0x2a
 
 172 #define NCOEFF            8     /* number of frequencies to be analyzed       */
 
 173 #define DTMF_TRESH     4000     /* above this is dtmf                         */
 
 174 #define SILENCE_TRESH   200     /* below this is silence                      */
 
 175 #define AMP_BITS          9     /* bits per sample, reduced to avoid overflow */
 
 179 /* For DTMF recognition:
 
 180  * 2 * cos(2 * PI * k / N) precalculated for all k
 
 182 static int cos2pik[NCOEFF] =
 
 184         55813, 53604, 51193, 48591, 38114, 33057, 25889, 18332
 
 187 static char dtmf_matrix[4][4] =
 
 189         {'1', '2', '3', 'A'},
 
 190         {'4', '5', '6', 'B'},
 
 191         {'7', '8', '9', 'C'},
 
 196 isdn_audio_tlookup(const u_char *table, u_char *buff, unsigned long n)
 
 199         unsigned long d0, d1, d2, d3;
 
 200         __asm__ __volatile__(
 
 206         :       "=&b"(d0), "=&c"(d1), "=&D"(d2), "=&S"(d3)
 
 207         :       "0"((long) table), "1"(n), "2"((long) buff), "3"((long) buff)
 
 211                 *buff = table[*(unsigned char *)buff], buff++;
 
 216 isdn_audio_ulaw2alaw(unsigned char *buff, unsigned long len)
 
 218         isdn_audio_tlookup(isdn_audio_ulaw_to_alaw, buff, len);
 
 222 isdn_audio_alaw2ulaw(unsigned char *buff, unsigned long len)
 
 224         isdn_audio_tlookup(isdn_audio_alaw_to_ulaw, buff, len);
 
 228  * linear <-> adpcm conversion stuff
 
 229  * Most parts from the mgetty-package.
 
 230  * (C) by Gert Doering and Klaus Weidner
 
 231  * Used by permission of Gert Doering
 
 235 #define ZEROTRAP                /* turn on the trap as per the MIL-STD */
 
 237 #define BIAS 0x84               /* define the add-in bias for 16 bit samples */
 
 241 isdn_audio_linear2ulaw(int sample)
 
 243         static int exp_lut[256] =
 
 245                 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
 
 246                 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
 
 247                 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
 
 248                 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
 
 249                 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
 
 250                 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
 
 251                 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
 
 252                 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
 
 253                 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 
 254                 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 
 255                 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 
 256                 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 
 257                 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 
 258                 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 
 259                 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
 
 260                 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
 
 265         unsigned char ulawbyte;
 
 267         /* Get the sample into sign-magnitude. */
 
 268         sign = (sample >> 8) & 0x80;    /* set aside the sign  */
 
 270                 sample = -sample;       /* get magnitude       */
 
 272                 sample = CLIP;  /* clip the magnitude  */
 
 274         /* Convert from 16 bit linear to ulaw. */
 
 275         sample = sample + BIAS;
 
 276         exponent = exp_lut[(sample >> 7) & 0xFF];
 
 277         mantissa = (sample >> (exponent + 3)) & 0x0F;
 
 278         ulawbyte = ~(sign | (exponent << 4) | mantissa);
 
 280         /* optional CCITT trap */
 
 288 static int Mx[3][8] =
 
 290         {0x3800, 0x5600, 0, 0, 0, 0, 0, 0},
 
 291         {0x399a, 0x3a9f, 0x4d14, 0x6607, 0, 0, 0, 0},
 
 292         {0x3556, 0x3556, 0x399A, 0x3A9F, 0x4200, 0x4D14, 0x6607, 0x6607},
 
 295 static int bitmask[9] =
 
 297         0, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff
 
 301 isdn_audio_get_bits(adpcm_state * s, unsigned char **in, int *len)
 
 303         while (s->nleft < s->nbits) {
 
 306                 s->word = (s->word << 8) | d;
 
 309         s->nleft -= s->nbits;
 
 310         return (s->word >> s->nleft) & bitmask[s->nbits];
 
 314 isdn_audio_put_bits(int data, int nbits, adpcm_state * s,
 
 315                     unsigned char **out, int *len)
 
 317         s->word = (s->word << nbits) | (data & bitmask[nbits]);
 
 319         while (s->nleft >= 8) {
 
 320                 int d = (s->word >> (s->nleft - 8));
 
 321                 *(out[0]++) = d & 255;
 
 328 isdn_audio_adpcm_init(adpcm_state * s, int nbits)
 
 331                 s = (adpcm_state *) kmalloc(sizeof(adpcm_state), GFP_ATOMIC);
 
 343 isdn_audio_dtmf_init(dtmf_state * s)
 
 346                 s = (dtmf_state *) kmalloc(sizeof(dtmf_state), GFP_ATOMIC);
 
 355  * Decompression of adpcm data to a/u-law
 
 360 isdn_audio_adpcm2xlaw(adpcm_state * s, int fmt, unsigned char *in,
 
 361                       unsigned char *out, int len)
 
 365         int nbits = s->nbits;
 
 369                 int e = isdn_audio_get_bits(s, &in, &len);
 
 372                 if (nbits == 4 && e == 0)
 
 374                 sign = (e >> (nbits - 1)) ? -1 : 1;
 
 375                 e &= bitmask[nbits - 1];
 
 376                 a += sign * ((e << 1) + 1) * d >> 1;
 
 380                         *out++ = isdn_audio_ulaw_to_alaw[
 
 381                                          isdn_audio_linear2ulaw(a << 2)];
 
 383                         *out++ = isdn_audio_linear2ulaw(a << 2);
 
 385                 d = (d * Mx[nbits - 2][e] + 0x2000) >> 14;
 
 395 isdn_audio_xlaw2adpcm(adpcm_state * s, int fmt, unsigned char *in,
 
 396                       unsigned char *out, int len)
 
 400         int nbits = s->nbits;
 
 405                  nmax = 1 << (nbits - 1);
 
 410                         delta = (isdn_audio_alaw_to_s16[*in++] >> 2) - a;
 
 412                         delta = (isdn_audio_ulaw_to_s16[*in++] >> 2) - a;
 
 417                 while (--nmax && delta > d) {
 
 421                 if (nbits == 4 && ((e & 0x0f) == 0))
 
 423                 isdn_audio_put_bits(e, nbits, s, &out, &olen);
 
 424                 sign = (e >> (nbits - 1)) ? -1 : 1;
 
 425                 e &= bitmask[nbits - 1];
 
 427                 a += sign * ((e << 1) + 1) * d >> 1;
 
 430                 d = (d * Mx[nbits - 2][e] + 0x2000) >> 14;
 
 440  * Goertzel algorithm.
 
 441  * See http://ptolemy.eecs.berkeley.edu/~pino/Ptolemy/papers/96/dtmf_ict/
 
 443  * Result is stored into an sk_buff and queued up for later
 
 447 isdn_audio_goertzel(int *sample, modem_info * info)
 
 457         skb = dev_alloc_skb(sizeof(int) * NCOEFF);
 
 460                   "isdn_audio: Could not alloc DTMF result for ttyI%d\n",
 
 464         result = (int *) skb_put(skb, sizeof(int) * NCOEFF);
 
 465         for (k = 0; k < NCOEFF; k++) {
 
 467                 for (n = 0; n < DTMF_NPOINTS; n++) {
 
 468                         sk = sample[n] + ((cos2pik[k] * sk1) >> 15) - sk2;
 
 472                 /* Avoid overflows */
 
 475                 /* compute |X(k)|**2 */
 
 476                 /* report overflows. This should not happen. */
 
 477                 /* Comment this out if desired */
 
 478                 if (sk < -32768 || sk > 32767)
 
 480                                "isdn_audio: dtmf goertzel overflow, sk=%d\n", sk);
 
 481                 if (sk2 < -32768 || sk2 > 32767)
 
 483                                "isdn_audio: dtmf goertzel overflow, sk2=%d\n", sk2);
 
 485                     ((sk * sk) >> AMP_BITS) -
 
 486                     ((((cos2pik[k] * sk) >> 15) * sk2) >> AMP_BITS) +
 
 487                     ((sk2 * sk2) >> AMP_BITS);
 
 489         skb_queue_tail(&info->dtmf_queue, skb);
 
 490         isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1);
 
 494 isdn_audio_eval_dtmf(modem_info * info)
 
 508         while ((skb = skb_dequeue(&info->dtmf_queue))) {
 
 509                 result = (int *) skb->data;
 
 510                 s = info->dtmf_state;
 
 511                 grp[LOGRP] = grp[HIGRP] = -1;
 
 514                 for (i = 0; i < NCOEFF; i++) {
 
 515                         if (result[i] > DTMF_TRESH) {
 
 516                                 if (result[i] > thresh)
 
 519                         else if (result[i] < SILENCE_TRESH)
 
 522                 if (silence == NCOEFF)
 
 526                                 thresh = thresh >> 4;  /* touchtones must match within 12 dB */
 
 527                                 for (i = 0; i < NCOEFF; i++) {
 
 528                                         if (result[i] < thresh)
 
 529                                                 continue;  /* ignore */
 
 530                                         /* good level found. This is allowed only one time per group */
 
 531                                         if (i < NCOEFF / 2) {
 
 533                                                 if (grp[LOGRP] >= 0) {
 
 534                                                         // Bad. Another tone found. */
 
 542                                                 if (grp[HIGRP] >= 0) { // Bad. Another tone found. */
 
 547                                                         grp[HIGRP] = i - NCOEFF/2;
 
 550                                 if ((grp[LOGRP] >= 0) && (grp[HIGRP] >= 0)) {
 
 551                                         what = dtmf_matrix[grp[LOGRP]][grp[HIGRP]];
 
 552                                         if (s->last != ' ' && s->last != '.')
 
 553                                                 s->last = what; /* min. 1 non-DTMF between DTMF */
 
 560                 if ((what != s->last) && (what != ' ') && (what != '.')) {
 
 561                         printk(KERN_DEBUG "dtmf: tt='%c'\n", what);
 
 566                         ISDN_AUDIO_SKB_DLECOUNT(skb) = 0;
 
 567                         ISDN_AUDIO_SKB_LOCK(skb) = 0;
 
 568                         di = info->isdn_driver;
 
 569                         ch = info->isdn_channel;
 
 570                         __skb_queue_tail(&dev->drv[di]->rpqueue[ch], skb);
 
 571                         dev->drv[di]->rcvcount[ch] += 2;
 
 572                         /* Schedule dequeuing */
 
 573                         if ((dev->modempoll) && (info->rcvsched))
 
 574                                 isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1);
 
 575                         wake_up_interruptible(&dev->drv[di]->rcv_waitq[ch]);
 
 583  * Decode DTMF tones, queue result in separate sk_buf for
 
 586  *   s    = pointer to state-struct.
 
 587  *   buf  = input audio data
 
 588  *   len  = size of audio data.
 
 589  *   fmt  = audio data format (0 = ulaw, 1 = alaw)
 
 592 isdn_audio_calc_dtmf(modem_info * info, unsigned char *buf, int len, int fmt)
 
 594         dtmf_state *s = info->dtmf_state;
 
 599                 c = DTMF_NPOINTS - s->idx;
 
 604                 for (i = 0; i < c; i++) {
 
 607                                     isdn_audio_alaw_to_s16[*buf++] >> (15 - AMP_BITS);
 
 610                                     isdn_audio_ulaw_to_s16[*buf++] >> (15 - AMP_BITS);
 
 612                 if (s->idx == DTMF_NPOINTS) {
 
 613                         isdn_audio_goertzel(s->buf, info);
 
 621 isdn_audio_silence_init(silence_state * s)
 
 624                 s = (silence_state *) kmalloc(sizeof(silence_state), GFP_ATOMIC);
 
 633 isdn_audio_calc_silence(modem_info * info, unsigned char *buf, int len, int fmt)
 
 635         silence_state *s = info->silence_state;
 
 639         if (!info->emu.vpar[1]) return;
 
 641         for (i = 0; i < len; i++) {
 
 643                     c = isdn_audio_alaw_to_ulaw[*buf++];
 
 650                 if (c > (info->emu.vpar[1] * 4)) { 
 
 654                         if (s->idx < 210000) s->idx++; 
 
 660 isdn_audio_put_dle_code(modem_info * info, u_char code)
 
 667         skb = dev_alloc_skb(2);
 
 670                   "isdn_audio: Could not alloc skb for ttyI%d\n",
 
 674         p = (char *) skb_put(skb, 2);
 
 677         ISDN_AUDIO_SKB_DLECOUNT(skb) = 0;
 
 678         ISDN_AUDIO_SKB_LOCK(skb) = 0;
 
 679         di = info->isdn_driver;
 
 680         ch = info->isdn_channel;
 
 681         __skb_queue_tail(&dev->drv[di]->rpqueue[ch], skb);
 
 682         dev->drv[di]->rcvcount[ch] += 2;
 
 683         /* Schedule dequeuing */
 
 684         if ((dev->modempoll) && (info->rcvsched))
 
 685                 isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1);
 
 686         wake_up_interruptible(&dev->drv[di]->rcv_waitq[ch]);
 
 690 isdn_audio_eval_silence(modem_info * info)
 
 692         silence_state *s = info->silence_state;
 
 697         if (s->idx > (info->emu.vpar[2] * 800)) { 
 
 699                 if (!s->state) {        /* silence from beginning of rec */ 
 
 705                 if ((what == 's') || (what == 'q')) {
 
 706                         printk(KERN_DEBUG "ttyI%d: %s\n", info->line,
 
 707                                 (what=='s') ? "silence":"quiet");
 
 708                         isdn_audio_put_dle_code(info, what);