14 #include <linux/isdn.h>
15 #include <linux/slab.h>
26 static short isdn_audio_ulaw_to_s16[] =
28 0x8284, 0x8684, 0x8a84, 0x8e84, 0x9284, 0x9684, 0x9a84, 0x9e84,
29 0xa284, 0xa684, 0xaa84, 0xae84, 0xb284, 0xb684, 0xba84, 0xbe84,
30 0xc184, 0xc384, 0xc584, 0xc784, 0xc984, 0xcb84, 0xcd84, 0xcf84,
31 0xd184, 0xd384, 0xd584, 0xd784, 0xd984, 0xdb84, 0xdd84, 0xdf84,
32 0xe104, 0xe204, 0xe304, 0xe404, 0xe504, 0xe604, 0xe704, 0xe804,
33 0xe904, 0xea04, 0xeb04, 0xec04, 0xed04, 0xee04, 0xef04, 0xf004,
34 0xf0c4, 0xf144, 0xf1c4, 0xf244, 0xf2c4, 0xf344, 0xf3c4, 0xf444,
35 0xf4c4, 0xf544, 0xf5c4, 0xf644, 0xf6c4, 0xf744, 0xf7c4, 0xf844,
36 0xf8a4, 0xf8e4, 0xf924, 0xf964, 0xf9a4, 0xf9e4, 0xfa24, 0xfa64,
37 0xfaa4, 0xfae4, 0xfb24, 0xfb64, 0xfba4, 0xfbe4, 0xfc24, 0xfc64,
38 0xfc94, 0xfcb4, 0xfcd4, 0xfcf4, 0xfd14, 0xfd34, 0xfd54, 0xfd74,
39 0xfd94, 0xfdb4, 0xfdd4, 0xfdf4, 0xfe14, 0xfe34, 0xfe54, 0xfe74,
40 0xfe8c, 0xfe9c, 0xfeac, 0xfebc, 0xfecc, 0xfedc, 0xfeec, 0xfefc,
41 0xff0c, 0xff1c, 0xff2c, 0xff3c, 0xff4c, 0xff5c, 0xff6c, 0xff7c,
42 0xff88, 0xff90, 0xff98, 0xffa0, 0xffa8, 0xffb0, 0xffb8, 0xffc0,
43 0xffc8, 0xffd0, 0xffd8, 0xffe0, 0xffe8, 0xfff0, 0xfff8, 0x0000,
44 0x7d7c, 0x797c, 0x757c, 0x717c, 0x6d7c, 0x697c, 0x657c, 0x617c,
45 0x5d7c, 0x597c, 0x557c, 0x517c, 0x4d7c, 0x497c, 0x457c, 0x417c,
46 0x3e7c, 0x3c7c, 0x3a7c, 0x387c, 0x367c, 0x347c, 0x327c, 0x307c,
47 0x2e7c, 0x2c7c, 0x2a7c, 0x287c, 0x267c, 0x247c, 0x227c, 0x207c,
48 0x1efc, 0x1dfc, 0x1cfc, 0x1bfc, 0x1afc, 0x19fc, 0x18fc, 0x17fc,
49 0x16fc, 0x15fc, 0x14fc, 0x13fc, 0x12fc, 0x11fc, 0x10fc, 0x0ffc,
50 0x0f3c, 0x0ebc, 0x0e3c, 0x0dbc, 0x0d3c, 0x0cbc, 0x0c3c, 0x0bbc,
51 0x0b3c, 0x0abc, 0x0a3c, 0x09bc, 0x093c, 0x08bc, 0x083c, 0x07bc,
52 0x075c, 0x071c, 0x06dc, 0x069c, 0x065c, 0x061c, 0x05dc, 0x059c,
53 0x055c, 0x051c, 0x04dc, 0x049c, 0x045c, 0x041c, 0x03dc, 0x039c,
54 0x036c, 0x034c, 0x032c, 0x030c, 0x02ec, 0x02cc, 0x02ac, 0x028c,
55 0x026c, 0x024c, 0x022c, 0x020c, 0x01ec, 0x01cc, 0x01ac, 0x018c,
56 0x0174, 0x0164, 0x0154, 0x0144, 0x0134, 0x0124, 0x0114, 0x0104,
57 0x00f4, 0x00e4, 0x00d4, 0x00c4, 0x00b4, 0x00a4, 0x0094, 0x0084,
58 0x0078, 0x0070, 0x0068, 0x0060, 0x0058, 0x0050, 0x0048, 0x0040,
59 0x0038, 0x0030, 0x0028, 0x0020, 0x0018, 0x0010, 0x0008, 0x0000
63 static short isdn_audio_alaw_to_s16[] =
65 0x13fc, 0xec04, 0x0144, 0xfebc, 0x517c, 0xae84, 0x051c, 0xfae4,
66 0x0a3c, 0xf5c4, 0x0048, 0xffb8, 0x287c, 0xd784, 0x028c, 0xfd74,
67 0x1bfc, 0xe404, 0x01cc, 0xfe34, 0x717c, 0x8e84, 0x071c, 0xf8e4,
68 0x0e3c, 0xf1c4, 0x00c4, 0xff3c, 0x387c, 0xc784, 0x039c, 0xfc64,
69 0x0ffc, 0xf004, 0x0104, 0xfefc, 0x417c, 0xbe84, 0x041c, 0xfbe4,
70 0x083c, 0xf7c4, 0x0008, 0xfff8, 0x207c, 0xdf84, 0x020c, 0xfdf4,
71 0x17fc, 0xe804, 0x018c, 0xfe74, 0x617c, 0x9e84, 0x061c, 0xf9e4,
72 0x0c3c, 0xf3c4, 0x0084, 0xff7c, 0x307c, 0xcf84, 0x030c, 0xfcf4,
73 0x15fc, 0xea04, 0x0164, 0xfe9c, 0x597c, 0xa684, 0x059c, 0xfa64,
74 0x0b3c, 0xf4c4, 0x0068, 0xff98, 0x2c7c, 0xd384, 0x02cc, 0xfd34,
75 0x1dfc, 0xe204, 0x01ec, 0xfe14, 0x797c, 0x8684, 0x07bc, 0xf844,
76 0x0f3c, 0xf0c4, 0x00e4, 0xff1c, 0x3c7c, 0xc384, 0x03dc, 0xfc24,
77 0x11fc, 0xee04, 0x0124, 0xfedc, 0x497c, 0xb684, 0x049c, 0xfb64,
78 0x093c, 0xf6c4, 0x0028, 0xffd8, 0x247c, 0xdb84, 0x024c, 0xfdb4,
79 0x19fc, 0xe604, 0x01ac, 0xfe54, 0x697c, 0x9684, 0x069c, 0xf964,
80 0x0d3c, 0xf2c4, 0x00a4, 0xff5c, 0x347c, 0xcb84, 0x034c, 0xfcb4,
81 0x12fc, 0xed04, 0x0134, 0xfecc, 0x4d7c, 0xb284, 0x04dc, 0xfb24,
82 0x09bc, 0xf644, 0x0038, 0xffc8, 0x267c, 0xd984, 0x026c, 0xfd94,
83 0x1afc, 0xe504, 0x01ac, 0xfe54, 0x6d7c, 0x9284, 0x06dc, 0xf924,
84 0x0dbc, 0xf244, 0x00b4, 0xff4c, 0x367c, 0xc984, 0x036c, 0xfc94,
85 0x0f3c, 0xf0c4, 0x00f4, 0xff0c, 0x3e7c, 0xc184, 0x03dc, 0xfc24,
86 0x07bc, 0xf844, 0x0008, 0xfff8, 0x1efc, 0xe104, 0x01ec, 0xfe14,
87 0x16fc, 0xe904, 0x0174, 0xfe8c, 0x5d7c, 0xa284, 0x05dc, 0xfa24,
88 0x0bbc, 0xf444, 0x0078, 0xff88, 0x2e7c, 0xd184, 0x02ec, 0xfd14,
89 0x14fc, 0xeb04, 0x0154, 0xfeac, 0x557c, 0xaa84, 0x055c, 0xfaa4,
90 0x0abc, 0xf544, 0x0058, 0xffa8, 0x2a7c, 0xd584, 0x02ac, 0xfd54,
91 0x1cfc, 0xe304, 0x01cc, 0xfe34, 0x757c, 0x8a84, 0x075c, 0xf8a4,
92 0x0ebc, 0xf144, 0x00d4, 0xff2c, 0x3a7c, 0xc584, 0x039c, 0xfc64,
93 0x10fc, 0xef04, 0x0114, 0xfeec, 0x457c, 0xba84, 0x045c, 0xfba4,
94 0x08bc, 0xf744, 0x0018, 0xffe8, 0x227c, 0xdd84, 0x022c, 0xfdd4,
95 0x18fc, 0xe704, 0x018c, 0xfe74, 0x657c, 0x9a84, 0x065c, 0xf9a4,
96 0x0cbc, 0xf344, 0x0094, 0xff6c, 0x327c, 0xcd84, 0x032c, 0xfcd4
100 static char isdn_audio_alaw_to_ulaw[] =
102 0xab, 0x2b, 0xe3, 0x63, 0x8b, 0x0b, 0xc9, 0x49,
103 0xba, 0x3a, 0xf6, 0x76, 0x9b, 0x1b, 0xd7, 0x57,
104 0xa3, 0x23, 0xdd, 0x5d, 0x83, 0x03, 0xc1, 0x41,
105 0xb2, 0x32, 0xeb, 0x6b, 0x93, 0x13, 0xcf, 0x4f,
106 0xaf, 0x2f, 0xe7, 0x67, 0x8f, 0x0f, 0xcd, 0x4d,
107 0xbe, 0x3e, 0xfe, 0x7e, 0x9f, 0x1f, 0xdb, 0x5b,
108 0xa7, 0x27, 0xdf, 0x5f, 0x87, 0x07, 0xc5, 0x45,
109 0xb6, 0x36, 0xef, 0x6f, 0x97, 0x17, 0xd3, 0x53,
110 0xa9, 0x29, 0xe1, 0x61, 0x89, 0x09, 0xc7, 0x47,
111 0xb8, 0x38, 0xf2, 0x72, 0x99, 0x19, 0xd5, 0x55,
112 0xa1, 0x21, 0xdc, 0x5c, 0x81, 0x01, 0xbf, 0x3f,
113 0xb0, 0x30, 0xe9, 0x69, 0x91, 0x11, 0xce, 0x4e,
114 0xad, 0x2d, 0xe5, 0x65, 0x8d, 0x0d, 0xcb, 0x4b,
115 0xbc, 0x3c, 0xfa, 0x7a, 0x9d, 0x1d, 0xd9, 0x59,
116 0xa5, 0x25, 0xde, 0x5e, 0x85, 0x05, 0xc3, 0x43,
117 0xb4, 0x34, 0xed, 0x6d, 0x95, 0x15, 0xd1, 0x51,
118 0xac, 0x2c, 0xe4, 0x64, 0x8c, 0x0c, 0xca, 0x4a,
119 0xbb, 0x3b, 0xf8, 0x78, 0x9c, 0x1c, 0xd8, 0x58,
120 0xa4, 0x24, 0xde, 0x5e, 0x84, 0x04, 0xc2, 0x42,
121 0xb3, 0x33, 0xec, 0x6c, 0x94, 0x14, 0xd0, 0x50,
122 0xb0, 0x30, 0xe8, 0x68, 0x90, 0x10, 0xce, 0x4e,
123 0xbf, 0x3f, 0xfe, 0x7e, 0xa0, 0x20, 0xdc, 0x5c,
124 0xa8, 0x28, 0xe0, 0x60, 0x88, 0x08, 0xc6, 0x46,
125 0xb7, 0x37, 0xf0, 0x70, 0x98, 0x18, 0xd4, 0x54,
126 0xaa, 0x2a, 0xe2, 0x62, 0x8a, 0x0a, 0xc8, 0x48,
127 0xb9, 0x39, 0xf4, 0x74, 0x9a, 0x1a, 0xd6, 0x56,
128 0xa2, 0x22, 0xdd, 0x5d, 0x82, 0x02, 0xc0, 0x40,
129 0xb1, 0x31, 0xea, 0x6a, 0x92, 0x12, 0xcf, 0x4f,
130 0xae, 0x2e, 0xe6, 0x66, 0x8e, 0x0e, 0xcc, 0x4c,
131 0xbd, 0x3d, 0xfc, 0x7c, 0x9e, 0x1e, 0xda, 0x5a,
132 0xa6, 0x26, 0xdf, 0x5f, 0x86, 0x06, 0xc4, 0x44,
133 0xb5, 0x35, 0xee, 0x6e, 0x96, 0x16, 0xd2, 0x52
137 static char isdn_audio_ulaw_to_alaw[] =
139 0xab, 0x55, 0xd5, 0x15, 0x95, 0x75, 0xf5, 0x35,
140 0xb5, 0x45, 0xc5, 0x05, 0x85, 0x65, 0xe5, 0x25,
141 0xa5, 0x5d, 0xdd, 0x1d, 0x9d, 0x7d, 0xfd, 0x3d,
142 0xbd, 0x4d, 0xcd, 0x0d, 0x8d, 0x6d, 0xed, 0x2d,
143 0xad, 0x51, 0xd1, 0x11, 0x91, 0x71, 0xf1, 0x31,
144 0xb1, 0x41, 0xc1, 0x01, 0x81, 0x61, 0xe1, 0x21,
145 0x59, 0xd9, 0x19, 0x99, 0x79, 0xf9, 0x39, 0xb9,
146 0x49, 0xc9, 0x09, 0x89, 0x69, 0xe9, 0x29, 0xa9,
147 0xd7, 0x17, 0x97, 0x77, 0xf7, 0x37, 0xb7, 0x47,
148 0xc7, 0x07, 0x87, 0x67, 0xe7, 0x27, 0xa7, 0xdf,
149 0x9f, 0x7f, 0xff, 0x3f, 0xbf, 0x4f, 0xcf, 0x0f,
150 0x8f, 0x6f, 0xef, 0x2f, 0x53, 0x13, 0x73, 0x33,
151 0xb3, 0x43, 0xc3, 0x03, 0x83, 0x63, 0xe3, 0x23,
152 0xa3, 0x5b, 0xdb, 0x1b, 0x9b, 0x7b, 0xfb, 0x3b,
153 0xbb, 0xbb, 0x4b, 0x4b, 0xcb, 0xcb, 0x0b, 0x0b,
154 0x8b, 0x8b, 0x6b, 0x6b, 0xeb, 0xeb, 0x2b, 0x2b,
155 0xab, 0x54, 0xd4, 0x14, 0x94, 0x74, 0xf4, 0x34,
156 0xb4, 0x44, 0xc4, 0x04, 0x84, 0x64, 0xe4, 0x24,
157 0xa4, 0x5c, 0xdc, 0x1c, 0x9c, 0x7c, 0xfc, 0x3c,
158 0xbc, 0x4c, 0xcc, 0x0c, 0x8c, 0x6c, 0xec, 0x2c,
159 0xac, 0x50, 0xd0, 0x10, 0x90, 0x70, 0xf0, 0x30,
160 0xb0, 0x40, 0xc0, 0x00, 0x80, 0x60, 0xe0, 0x20,
161 0x58, 0xd8, 0x18, 0x98, 0x78, 0xf8, 0x38, 0xb8,
162 0x48, 0xc8, 0x08, 0x88, 0x68, 0xe8, 0x28, 0xa8,
163 0xd6, 0x16, 0x96, 0x76, 0xf6, 0x36, 0xb6, 0x46,
164 0xc6, 0x06, 0x86, 0x66, 0xe6, 0x26, 0xa6, 0xde,
165 0x9e, 0x7e, 0xfe, 0x3e, 0xbe, 0x4e, 0xce, 0x0e,
166 0x8e, 0x6e, 0xee, 0x2e, 0x52, 0x12, 0x72, 0x32,
167 0xb2, 0x42, 0xc2, 0x02, 0x82, 0x62, 0xe2, 0x22,
168 0xa2, 0x5a, 0xda, 0x1a, 0x9a, 0x7a, 0xfa, 0x3a,
169 0xba, 0xba, 0x4a, 0x4a, 0xca, 0xca, 0x0a, 0x0a,
170 0x8a, 0x8a, 0x6a, 0x6a, 0xea, 0xea, 0x2a, 0x2a
174 #define DTMF_TRESH 4000
175 #define SILENCE_TRESH 200
183 static int cos2pik[
NCOEFF] =
185 55813, 53604, 51193, 48591, 38114, 33057, 25889, 18332
188 static char dtmf_matrix[4][4] =
190 {
'1',
'2',
'3',
'A'},
191 {
'4',
'5',
'6',
'B'},
192 {
'7',
'8',
'9',
'C'},
200 unsigned long d0,
d1,
d2, d3;
207 :
"=&b"(d0),
"=&c"(d1),
"=&D"(d2),
"=&S"(d3)
208 :
"0"((
long) table),
"1"(n),
"2"((
long) buff),
"3"((
long) buff)
212 *buff = table[*(
unsigned char *)buff], buff++;
219 isdn_audio_tlookup(isdn_audio_ulaw_to_alaw, buff, len);
225 isdn_audio_tlookup(isdn_audio_alaw_to_ulaw, buff, len);
242 isdn_audio_linear2ulaw(
int sample)
244 static int exp_lut[256] =
246 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
247 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
248 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
249 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
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 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
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,
261 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
266 unsigned char ulawbyte;
269 sign = (sample >> 8) & 0x80;
276 sample = sample +
BIAS;
277 exponent = exp_lut[(sample >> 7) & 0xFF];
278 mantissa = (sample >> (exponent + 3)) & 0x0F;
279 ulawbyte = ~(sign | (exponent << 4) | mantissa);
289 static int Mx[3][8] =
291 {0x3800, 0x5600, 0, 0, 0, 0, 0, 0},
292 {0x399a, 0x3a9f, 0x4d14, 0x6607, 0, 0, 0, 0},
293 {0x3556, 0x3556, 0x399A, 0x3A9F, 0x4200, 0x4D14, 0x6607, 0x6607},
298 0, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff
316 unsigned char **
out,
int *len)
318 s->
word = (s->
word << nbits) | (data & bitmask[nbits]);
320 while (s->
nleft >= 8) {
322 *(out[0]++) = d & 255;
362 unsigned char *out,
int len)
366 int nbits = s->
nbits;
370 int e = isdn_audio_get_bits(s, &in, &len);
373 if (nbits == 4 && e == 0)
375 sign = (e >> (nbits - 1)) ? -1 : 1;
376 e &= bitmask[nbits - 1];
377 a += sign * ((e << 1) + 1) * d >> 1;
381 *out++ = isdn_audio_ulaw_to_alaw[
382 isdn_audio_linear2ulaw(a << 2)];
384 *out++ = isdn_audio_linear2ulaw(a << 2);
386 d = (d * Mx[nbits - 2][
e] + 0x2000) >> 14;
397 unsigned char *out,
int len)
401 int nbits = s->
nbits;
406 nmax = 1 << (nbits - 1);
411 delta = (isdn_audio_alaw_to_s16[*in++] >> 2) - a;
413 delta = (isdn_audio_ulaw_to_s16[*in++] >> 2) - a;
418 while (--nmax && delta > d) {
422 if (nbits == 4 && ((e & 0x0f) == 0))
424 isdn_audio_put_bits(e, nbits, s, &out, &olen);
425 sign = (e >> (nbits - 1)) ? -1 : 1;
426 e &= bitmask[nbits - 1];
428 a += sign * ((e << 1) + 1) * d >> 1;
431 d = (d * Mx[nbits - 2][
e] + 0x2000) >> 14;
458 skb = dev_alloc_skb(
sizeof(
int) *
NCOEFF);
461 "isdn_audio: Could not alloc DTMF result for ttyI%d\n",
466 for (k = 0; k <
NCOEFF; k++) {
469 sk = sample[
n] + ((cos2pik[
k] * sk1) >> 15) - sk2;
479 if (sk < -32768 || sk > 32767)
481 "isdn_audio: dtmf goertzel overflow, sk=%d\n", sk);
482 if (sk2 < -32768 || sk2 > 32767)
484 "isdn_audio: dtmf goertzel overflow, sk2=%d\n", sk2);
510 result = (
int *) skb->
data;
511 s = info->dtmf_state;
517 if (result[i] > thresh)
523 if (silence == NCOEFF)
527 thresh = thresh >> 4;
528 for (i = 0; i <
NCOEFF; i++) {
529 if (result[i] < thresh)
532 if (i < NCOEFF / 2) {
534 if (grp[
LOGRP] >= 0) {
543 if (grp[
HIGRP] >= 0) {
548 grp[
HIGRP] = i - NCOEFF/2;
553 if (s->
last !=
' ' && s->
last !=
'.')
561 if ((what != s->
last) && (what !=
' ') && (what !=
'.')) {
567 ISDN_AUDIO_SKB_DLECOUNT(skb) = 0;
568 ISDN_AUDIO_SKB_LOCK(skb) = 0;
571 __skb_queue_tail(&
dev->drv[di]->rpqueue[ch], skb);
572 dev->drv[di]->rcvcount[ch] += 2;
605 for (i = 0; i <
c; i++) {
608 isdn_audio_alaw_to_s16[*buf++] >> (15 -
AMP_BITS);
611 isdn_audio_ulaw_to_s16[*buf++] >> (15 -
AMP_BITS);
614 isdn_audio_goertzel(s->
buf, info);
640 if (!info->
emu.vpar[1])
return;
642 for (i = 0; i <
len; i++) {
644 c = isdn_audio_alaw_to_ulaw[*buf++];
651 if (c > (info->
emu.vpar[1] * 4)) {
655 if (s->
idx < 210000) s->
idx++;
668 skb = dev_alloc_skb(2);
671 "isdn_audio: Could not alloc skb for ttyI%d\n",
678 ISDN_AUDIO_SKB_DLECOUNT(skb) = 0;
679 ISDN_AUDIO_SKB_LOCK(skb) = 0;
682 __skb_queue_tail(&
dev->drv[di]->rpqueue[ch], skb);
683 dev->drv[di]->rcvcount[ch] += 2;
698 if (s->
idx > (info->
emu.vpar[2] * 800)) {
706 if ((what ==
's') || (what ==
'q')) {
708 (what ==
's') ?
"silence" :
"quiet");