added mtd driver
[linux-2.4.git] / drivers / isdn / isdn_audio.c
1 /* $Id: isdn_audio.c,v 1.1.4.1 2001/11/20 14:19:33 kai Exp $
2  *
3  * Linux ISDN subsystem, audio conversion and compression (linklevel).
4  *
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)
8  *
9  * This software may be used and distributed according to the terms
10  * of the GNU General Public License, incorporated herein by reference.
11  *
12  */
13
14 #include <linux/isdn.h>
15 #include "isdn_audio.h"
16 #include "isdn_common.h"
17
18 char *isdn_audio_revision = "$Revision: 1.1.4.1 $";
19
20 /*
21  * Misc. lookup-tables.
22  */
23
24 /* ulaw -> signed 16-bit */
25 static short isdn_audio_ulaw_to_s16[] =
26 {
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
59 };
60
61 /* alaw -> signed 16-bit */
62 static short isdn_audio_alaw_to_s16[] =
63 {
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
96 };
97
98 /* alaw -> ulaw */
99 static char isdn_audio_alaw_to_ulaw[] =
100 {
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
133 };
134
135 /* ulaw -> alaw */
136 static char isdn_audio_ulaw_to_alaw[] =
137 {
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
170 };
171
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 */
176 #define LOGRP             0
177 #define HIGRP             1
178
179 /* For DTMF recognition:
180  * 2 * cos(2 * PI * k / N) precalculated for all k
181  */
182 static int cos2pik[NCOEFF] =
183 {
184         55813, 53604, 51193, 48591, 38114, 33057, 25889, 18332
185 };
186
187 static char dtmf_matrix[4][4] =
188 {
189         {'1', '2', '3', 'A'},
190         {'4', '5', '6', 'B'},
191         {'7', '8', '9', 'C'},
192         {'*', '0', '#', 'D'}
193 };
194
195 static inline void
196 isdn_audio_tlookup(const u_char *table, u_char *buff, unsigned long n)
197 {
198 #ifdef __i386__
199         unsigned long d0, d1, d2, d3;
200         __asm__ __volatile__(
201                 "cld\n"
202                 "1:\tlodsb\n\t"
203                 "xlatb\n\t"
204                 "stosb\n\t"
205                 "loop 1b\n\t"
206         :       "=&b"(d0), "=&c"(d1), "=&D"(d2), "=&S"(d3)
207         :       "0"((long) table), "1"(n), "2"((long) buff), "3"((long) buff)
208         :       "memory", "ax");
209 #else
210         while (n--)
211                 *buff = table[*(unsigned char *)buff], buff++;
212 #endif
213 }
214
215 void
216 isdn_audio_ulaw2alaw(unsigned char *buff, unsigned long len)
217 {
218         isdn_audio_tlookup(isdn_audio_ulaw_to_alaw, buff, len);
219 }
220
221 void
222 isdn_audio_alaw2ulaw(unsigned char *buff, unsigned long len)
223 {
224         isdn_audio_tlookup(isdn_audio_alaw_to_ulaw, buff, len);
225 }
226
227 /*
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
232  */
233
234
235 #define ZEROTRAP                /* turn on the trap as per the MIL-STD */
236 #undef ZEROTRAP
237 #define BIAS 0x84               /* define the add-in bias for 16 bit samples */
238 #define CLIP 32635
239
240 static unsigned char
241 isdn_audio_linear2ulaw(int sample)
242 {
243         static int exp_lut[256] =
244         {
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
261         };
262         int sign,
263          exponent,
264          mantissa;
265         unsigned char ulawbyte;
266
267         /* Get the sample into sign-magnitude. */
268         sign = (sample >> 8) & 0x80;    /* set aside the sign  */
269         if (sign != 0)
270                 sample = -sample;       /* get magnitude       */
271         if (sample > CLIP)
272                 sample = CLIP;  /* clip the magnitude  */
273
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);
279 #ifdef ZEROTRAP
280         /* optional CCITT trap */
281         if (ulawbyte == 0)
282                 ulawbyte = 0x02;
283 #endif
284         return (ulawbyte);
285 }
286
287
288 static int Mx[3][8] =
289 {
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},
293 };
294
295 static int bitmask[9] =
296 {
297         0, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff
298 };
299
300 static int
301 isdn_audio_get_bits(adpcm_state * s, unsigned char **in, int *len)
302 {
303         while (s->nleft < s->nbits) {
304                 int d = *((*in)++);
305                 (*len)--;
306                 s->word = (s->word << 8) | d;
307                 s->nleft += 8;
308         }
309         s->nleft -= s->nbits;
310         return (s->word >> s->nleft) & bitmask[s->nbits];
311 }
312
313 static void
314 isdn_audio_put_bits(int data, int nbits, adpcm_state * s,
315                     unsigned char **out, int *len)
316 {
317         s->word = (s->word << nbits) | (data & bitmask[nbits]);
318         s->nleft += nbits;
319         while (s->nleft >= 8) {
320                 int d = (s->word >> (s->nleft - 8));
321                 *(out[0]++) = d & 255;
322                 (*len)++;
323                 s->nleft -= 8;
324         }
325 }
326
327 adpcm_state *
328 isdn_audio_adpcm_init(adpcm_state * s, int nbits)
329 {
330         if (!s)
331                 s = (adpcm_state *) kmalloc(sizeof(adpcm_state), GFP_ATOMIC);
332         if (s) {
333                 s->a = 0;
334                 s->d = 5;
335                 s->word = 0;
336                 s->nleft = 0;
337                 s->nbits = nbits;
338         }
339         return s;
340 }
341
342 dtmf_state *
343 isdn_audio_dtmf_init(dtmf_state * s)
344 {
345         if (!s)
346                 s = (dtmf_state *) kmalloc(sizeof(dtmf_state), GFP_ATOMIC);
347         if (s) {
348                 s->idx = 0;
349                 s->last = ' ';
350         }
351         return s;
352 }
353
354 /*
355  * Decompression of adpcm data to a/u-law
356  *
357  */
358
359 int
360 isdn_audio_adpcm2xlaw(adpcm_state * s, int fmt, unsigned char *in,
361                       unsigned char *out, int len)
362 {
363         int a = s->a;
364         int d = s->d;
365         int nbits = s->nbits;
366         int olen = 0;
367
368         while (len) {
369                 int e = isdn_audio_get_bits(s, &in, &len);
370                 int sign;
371
372                 if (nbits == 4 && e == 0)
373                         d = 4;
374                 sign = (e >> (nbits - 1)) ? -1 : 1;
375                 e &= bitmask[nbits - 1];
376                 a += sign * ((e << 1) + 1) * d >> 1;
377                 if (d & 1)
378                         a++;
379                 if (fmt)
380                         *out++ = isdn_audio_ulaw_to_alaw[
381                                          isdn_audio_linear2ulaw(a << 2)];
382                 else
383                         *out++ = isdn_audio_linear2ulaw(a << 2);
384                 olen++;
385                 d = (d * Mx[nbits - 2][e] + 0x2000) >> 14;
386                 if (d < 5)
387                         d = 5;
388         }
389         s->a = a;
390         s->d = d;
391         return olen;
392 }
393
394 int
395 isdn_audio_2adpcm_flush(adpcm_state * s, unsigned char *out)
396 {
397         int olen = 0;
398
399         if (s->nleft)
400                 isdn_audio_put_bits(0, 8 - s->nleft, s, &out, &olen);
401         return olen;
402 }
403
404 int
405 isdn_audio_xlaw2adpcm(adpcm_state * s, int fmt, unsigned char *in,
406                       unsigned char *out, int len)
407 {
408         int a = s->a;
409         int d = s->d;
410         int nbits = s->nbits;
411         int olen = 0;
412
413         while (len--) {
414                 int e = 0,
415                  nmax = 1 << (nbits - 1);
416                 int sign,
417                  delta;
418
419                 if (fmt)
420                         delta = (isdn_audio_alaw_to_s16[*in++] >> 2) - a;
421                 else
422                         delta = (isdn_audio_ulaw_to_s16[*in++] >> 2) - a;
423                 if (delta < 0) {
424                         e = nmax;
425                         delta = -delta;
426                 }
427                 while (--nmax && delta > d) {
428                         delta -= d;
429                         e++;
430                 }
431                 if (nbits == 4 && ((e & 0x0f) == 0))
432                         e = 8;
433                 isdn_audio_put_bits(e, nbits, s, &out, &olen);
434                 sign = (e >> (nbits - 1)) ? -1 : 1;
435                 e &= bitmask[nbits - 1];
436
437                 a += sign * ((e << 1) + 1) * d >> 1;
438                 if (d & 1)
439                         a++;
440                 d = (d * Mx[nbits - 2][e] + 0x2000) >> 14;
441                 if (d < 5)
442                         d = 5;
443         }
444         s->a = a;
445         s->d = d;
446         return olen;
447 }
448
449 /*
450  * Goertzel algorithm.
451  * See http://ptolemy.eecs.berkeley.edu/~pino/Ptolemy/papers/96/dtmf_ict/
452  * for more info.
453  * Result is stored into an sk_buff and queued up for later
454  * evaluation.
455  */
456 static void
457 isdn_audio_goertzel(int *sample, modem_info * info)
458 {
459         int sk,
460          sk1,
461          sk2;
462         int k,
463          n;
464         struct sk_buff *skb;
465         int *result;
466
467         skb = dev_alloc_skb(sizeof(int) * NCOEFF);
468         if (!skb) {
469                 printk(KERN_WARNING
470                   "isdn_audio: Could not alloc DTMF result for ttyI%d\n",
471                        info->line);
472                 return;
473         }
474         result = (int *) skb_put(skb, sizeof(int) * NCOEFF);
475         for (k = 0; k < NCOEFF; k++) {
476                 sk = sk1 = sk2 = 0;
477                 for (n = 0; n < DTMF_NPOINTS; n++) {
478                         sk = sample[n] + ((cos2pik[k] * sk1) >> 15) - sk2;
479                         sk2 = sk1;
480                         sk1 = sk;
481                 }
482                 /* Avoid overflows */
483                 sk >>= 1;
484                 sk2 >>= 1;
485                 /* compute |X(k)|**2 */
486                 /* report overflows. This should not happen. */
487                 /* Comment this out if desired */
488                 if (sk < -32768 || sk > 32767)
489                         printk(KERN_DEBUG
490                                "isdn_audio: dtmf goertzel overflow, sk=%d\n", sk);
491                 if (sk2 < -32768 || sk2 > 32767)
492                         printk(KERN_DEBUG
493                                "isdn_audio: dtmf goertzel overflow, sk2=%d\n", sk2);
494                 result[k] =
495                     ((sk * sk) >> AMP_BITS) -
496                     ((((cos2pik[k] * sk) >> 15) * sk2) >> AMP_BITS) +
497                     ((sk2 * sk2) >> AMP_BITS);
498         }
499         skb_queue_tail(&info->dtmf_queue, skb);
500         isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1);
501 }
502
503 void
504 isdn_audio_eval_dtmf(modem_info * info)
505 {
506         struct sk_buff *skb;
507         int *result;
508         dtmf_state *s;
509         int silence;
510         int i;
511         int di;
512         int ch;
513         unsigned long flags;
514         int grp[2];
515         char what;
516         char *p;
517         int thresh;
518
519         while ((skb = skb_dequeue(&info->dtmf_queue))) {
520                 result = (int *) skb->data;
521                 s = info->dtmf_state;
522                 grp[LOGRP] = grp[HIGRP] = -1;
523                 silence = 0;
524                 thresh = 0;
525                 for (i = 0; i < NCOEFF; i++) {
526                         if (result[i] > DTMF_TRESH) {
527                                 if (result[i] > thresh)
528                                         thresh = result[i];
529                         }
530                         else if (result[i] < SILENCE_TRESH)
531                                 silence++;
532                 }
533                 if (silence == NCOEFF)
534                         what = ' ';
535                 else {
536                         if (thresh > 0) {
537                                 thresh = thresh >> 4;  /* touchtones must match within 12 dB */
538                                 for (i = 0; i < NCOEFF; i++) {
539                                         if (result[i] < thresh)
540                                                 continue;  /* ignore */
541                                         /* good level found. This is allowed only one time per group */
542                                         if (i < NCOEFF / 2) {
543                                                 /* lowgroup*/
544                                                 if (grp[LOGRP] >= 0) {
545                                                         // Bad. Another tone found. */
546                                                         grp[LOGRP] = -1;
547                                                         break;
548                                                 }
549                                                 else
550                                                         grp[LOGRP] = i;
551                                         }
552                                         else { /* higroup */
553                                                 if (grp[HIGRP] >= 0) { // Bad. Another tone found. */
554                                                         grp[HIGRP] = -1;
555                                                         break;
556                                                 }
557                                                 else
558                                                         grp[HIGRP] = i - NCOEFF/2;
559                                         }
560                                 }
561                                 if ((grp[LOGRP] >= 0) && (grp[HIGRP] >= 0)) {
562                                         what = dtmf_matrix[grp[LOGRP]][grp[HIGRP]];
563                                         if (s->last != ' ' && s->last != '.')
564                                                 s->last = what; /* min. 1 non-DTMF between DTMF */
565                                 } else
566                                         what = '.';
567                         }
568                         else
569                                 what = '.';
570                 }
571                 if ((what != s->last) && (what != ' ') && (what != '.')) {
572                         printk(KERN_DEBUG "dtmf: tt='%c'\n", what);
573                         p = skb->data;
574                         *p++ = 0x10;
575                         *p = what;
576                         skb_trim(skb, 2);
577                         if (skb_headroom(skb) < sizeof(isdn_audio_skb)) {
578                                 printk(KERN_WARNING
579                                        "isdn_audio: insufficient skb_headroom, dropping\n");
580                                 kfree_skb(skb);
581                                 return;
582                         }
583                         ISDN_AUDIO_SKB_DLECOUNT(skb) = 0;
584                         ISDN_AUDIO_SKB_LOCK(skb) = 0;
585                         save_flags(flags);
586                         cli();
587                         di = info->isdn_driver;
588                         ch = info->isdn_channel;
589                         __skb_queue_tail(&dev->drv[di]->rpqueue[ch], skb);
590                         dev->drv[di]->rcvcount[ch] += 2;
591                         restore_flags(flags);
592                         /* Schedule dequeuing */
593                         if ((dev->modempoll) && (info->rcvsched))
594                                 isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1);
595                         wake_up_interruptible(&dev->drv[di]->rcv_waitq[ch]);
596                 } else
597                         kfree_skb(skb);
598                 s->last = what;
599         }
600 }
601
602 /*
603  * Decode DTMF tones, queue result in separate sk_buf for
604  * later examination.
605  * Parameters:
606  *   s    = pointer to state-struct.
607  *   buf  = input audio data
608  *   len  = size of audio data.
609  *   fmt  = audio data format (0 = ulaw, 1 = alaw)
610  */
611 void
612 isdn_audio_calc_dtmf(modem_info * info, unsigned char *buf, int len, int fmt)
613 {
614         dtmf_state *s = info->dtmf_state;
615         int i;
616         int c;
617
618         while (len) {
619                 c = DTMF_NPOINTS - s->idx;
620                 if (c > len)
621                         c = len;
622                 if (c <= 0)
623                         break;
624                 for (i = 0; i < c; i++) {
625                         if (fmt)
626                                 s->buf[s->idx++] =
627                                     isdn_audio_alaw_to_s16[*buf++] >> (15 - AMP_BITS);
628                         else
629                                 s->buf[s->idx++] =
630                                     isdn_audio_ulaw_to_s16[*buf++] >> (15 - AMP_BITS);
631                 }
632                 if (s->idx == DTMF_NPOINTS) {
633                         isdn_audio_goertzel(s->buf, info);
634                         s->idx = 0;
635                 }
636                 len -= c;
637         }
638 }
639
640 silence_state *
641 isdn_audio_silence_init(silence_state * s)
642 {
643         if (!s)
644                 s = (silence_state *) kmalloc(sizeof(silence_state), GFP_ATOMIC);
645         if (s) {
646                 s->idx = 0;
647                 s->state = 0;
648         }
649         return s;
650 }
651
652 void
653 isdn_audio_calc_silence(modem_info * info, unsigned char *buf, int len, int fmt)
654 {
655         silence_state *s = info->silence_state;
656         int i;
657         signed char c;
658
659         if (!info->emu.vpar[1]) return;
660
661         for (i = 0; i < len; i++) {
662                 if (fmt)
663                     c = isdn_audio_alaw_to_ulaw[*buf++];
664                         else
665                     c = *buf++;
666
667                 if (c > 0) c -= 128;
668                 c = abs(c);
669
670                 if (c > (info->emu.vpar[1] * 4)) { 
671                         s->idx = 0;
672                         s->state = 1; 
673                 } else {
674                         if (s->idx < 210000) s->idx++; 
675                 }
676         }
677 }
678
679 void
680 isdn_audio_put_dle_code(modem_info * info, u_char code)
681 {
682         struct sk_buff *skb;
683         unsigned long flags;
684         int di;
685         int ch;
686         char *p;
687
688         skb = dev_alloc_skb(2);
689         if (!skb) {
690                 printk(KERN_WARNING
691                   "isdn_audio: Could not alloc skb for ttyI%d\n",
692                        info->line);
693                 return;
694         }
695         p = (char *) skb_put(skb, 2);
696         p[0] = 0x10;
697         p[1] = code;
698         if (skb_headroom(skb) < sizeof(isdn_audio_skb)) {
699                 printk(KERN_WARNING
700                        "isdn_audio: insufficient skb_headroom, dropping\n");
701                 kfree_skb(skb);
702                 return;
703         }
704         ISDN_AUDIO_SKB_DLECOUNT(skb) = 0;
705         ISDN_AUDIO_SKB_LOCK(skb) = 0;
706         save_flags(flags);
707         cli();
708         di = info->isdn_driver;
709         ch = info->isdn_channel;
710         __skb_queue_tail(&dev->drv[di]->rpqueue[ch], skb);
711         dev->drv[di]->rcvcount[ch] += 2;
712         restore_flags(flags);
713         /* Schedule dequeuing */
714         if ((dev->modempoll) && (info->rcvsched))
715                 isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1);
716         wake_up_interruptible(&dev->drv[di]->rcv_waitq[ch]);
717 }
718
719 void
720 isdn_audio_eval_silence(modem_info * info)
721 {
722         silence_state *s = info->silence_state;
723         char what;
724
725         what = ' ';
726
727         if (s->idx > (info->emu.vpar[2] * 800)) { 
728                 s->idx = 0;
729                 if (!s->state) {        /* silence from beginning of rec */ 
730                         what = 's';
731                 } else {
732                         what = 'q';
733                 }
734         }
735                 if ((what == 's') || (what == 'q')) {
736                         printk(KERN_DEBUG "ttyI%d: %s\n", info->line,
737                                 (what=='s') ? "silence":"quiet");
738                         isdn_audio_put_dle_code(info, what);
739                 } 
740 }