fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / isdn / i4l / isdn_audio.c
1 /* $Id: isdn_audio.c,v 1.1.2.2 2004/01/12 22:37:18 keil 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.2.2 $";
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 = 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 = 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_xlaw2adpcm(adpcm_state * s, int fmt, unsigned char *in,
396                       unsigned char *out, int len)
397 {
398         int a = s->a;
399         int d = s->d;
400         int nbits = s->nbits;
401         int olen = 0;
402
403         while (len--) {
404                 int e = 0,
405                  nmax = 1 << (nbits - 1);
406                 int sign,
407                  delta;
408
409                 if (fmt)
410                         delta = (isdn_audio_alaw_to_s16[*in++] >> 2) - a;
411                 else
412                         delta = (isdn_audio_ulaw_to_s16[*in++] >> 2) - a;
413                 if (delta < 0) {
414                         e = nmax;
415                         delta = -delta;
416                 }
417                 while (--nmax && delta > d) {
418                         delta -= d;
419                         e++;
420                 }
421                 if (nbits == 4 && ((e & 0x0f) == 0))
422                         e = 8;
423                 isdn_audio_put_bits(e, nbits, s, &out, &olen);
424                 sign = (e >> (nbits - 1)) ? -1 : 1;
425                 e &= bitmask[nbits - 1];
426
427                 a += sign * ((e << 1) + 1) * d >> 1;
428                 if (d & 1)
429                         a++;
430                 d = (d * Mx[nbits - 2][e] + 0x2000) >> 14;
431                 if (d < 5)
432                         d = 5;
433         }
434         s->a = a;
435         s->d = d;
436         return olen;
437 }
438
439 /*
440  * Goertzel algorithm.
441  * See http://ptolemy.eecs.berkeley.edu/~pino/Ptolemy/papers/96/dtmf_ict/
442  * for more info.
443  * Result is stored into an sk_buff and queued up for later
444  * evaluation.
445  */
446 static void
447 isdn_audio_goertzel(int *sample, modem_info * info)
448 {
449         int sk,
450          sk1,
451          sk2;
452         int k,
453          n;
454         struct sk_buff *skb;
455         int *result;
456
457         skb = dev_alloc_skb(sizeof(int) * NCOEFF);
458         if (!skb) {
459                 printk(KERN_WARNING
460                   "isdn_audio: Could not alloc DTMF result for ttyI%d\n",
461                        info->line);
462                 return;
463         }
464         result = (int *) skb_put(skb, sizeof(int) * NCOEFF);
465         for (k = 0; k < NCOEFF; k++) {
466                 sk = sk1 = sk2 = 0;
467                 for (n = 0; n < DTMF_NPOINTS; n++) {
468                         sk = sample[n] + ((cos2pik[k] * sk1) >> 15) - sk2;
469                         sk2 = sk1;
470                         sk1 = sk;
471                 }
472                 /* Avoid overflows */
473                 sk >>= 1;
474                 sk2 >>= 1;
475                 /* compute |X(k)|**2 */
476                 /* report overflows. This should not happen. */
477                 /* Comment this out if desired */
478                 if (sk < -32768 || sk > 32767)
479                         printk(KERN_DEBUG
480                                "isdn_audio: dtmf goertzel overflow, sk=%d\n", sk);
481                 if (sk2 < -32768 || sk2 > 32767)
482                         printk(KERN_DEBUG
483                                "isdn_audio: dtmf goertzel overflow, sk2=%d\n", sk2);
484                 result[k] =
485                     ((sk * sk) >> AMP_BITS) -
486                     ((((cos2pik[k] * sk) >> 15) * sk2) >> AMP_BITS) +
487                     ((sk2 * sk2) >> AMP_BITS);
488         }
489         skb_queue_tail(&info->dtmf_queue, skb);
490         isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1);
491 }
492
493 void
494 isdn_audio_eval_dtmf(modem_info * info)
495 {
496         struct sk_buff *skb;
497         int *result;
498         dtmf_state *s;
499         int silence;
500         int i;
501         int di;
502         int ch;
503         int grp[2];
504         char what;
505         char *p;
506         int thresh;
507
508         while ((skb = skb_dequeue(&info->dtmf_queue))) {
509                 result = (int *) skb->data;
510                 s = info->dtmf_state;
511                 grp[LOGRP] = grp[HIGRP] = -1;
512                 silence = 0;
513                 thresh = 0;
514                 for (i = 0; i < NCOEFF; i++) {
515                         if (result[i] > DTMF_TRESH) {
516                                 if (result[i] > thresh)
517                                         thresh = result[i];
518                         }
519                         else if (result[i] < SILENCE_TRESH)
520                                 silence++;
521                 }
522                 if (silence == NCOEFF)
523                         what = ' ';
524                 else {
525                         if (thresh > 0) {
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) {
532                                                 /* lowgroup*/
533                                                 if (grp[LOGRP] >= 0) {
534                                                         // Bad. Another tone found. */
535                                                         grp[LOGRP] = -1;
536                                                         break;
537                                                 }
538                                                 else
539                                                         grp[LOGRP] = i;
540                                         }
541                                         else { /* higroup */
542                                                 if (grp[HIGRP] >= 0) { // Bad. Another tone found. */
543                                                         grp[HIGRP] = -1;
544                                                         break;
545                                                 }
546                                                 else
547                                                         grp[HIGRP] = i - NCOEFF/2;
548                                         }
549                                 }
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 */
554                                 } else
555                                         what = '.';
556                         }
557                         else
558                                 what = '.';
559                 }
560                 if ((what != s->last) && (what != ' ') && (what != '.')) {
561                         printk(KERN_DEBUG "dtmf: tt='%c'\n", what);
562                         p = skb->data;
563                         *p++ = 0x10;
564                         *p = what;
565                         skb_trim(skb, 2);
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]);
576                 } else
577                         kfree_skb(skb);
578                 s->last = what;
579         }
580 }
581
582 /*
583  * Decode DTMF tones, queue result in separate sk_buf for
584  * later examination.
585  * Parameters:
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)
590  */
591 void
592 isdn_audio_calc_dtmf(modem_info * info, unsigned char *buf, int len, int fmt)
593 {
594         dtmf_state *s = info->dtmf_state;
595         int i;
596         int c;
597
598         while (len) {
599                 c = DTMF_NPOINTS - s->idx;
600                 if (c > len)
601                         c = len;
602                 if (c <= 0)
603                         break;
604                 for (i = 0; i < c; i++) {
605                         if (fmt)
606                                 s->buf[s->idx++] =
607                                     isdn_audio_alaw_to_s16[*buf++] >> (15 - AMP_BITS);
608                         else
609                                 s->buf[s->idx++] =
610                                     isdn_audio_ulaw_to_s16[*buf++] >> (15 - AMP_BITS);
611                 }
612                 if (s->idx == DTMF_NPOINTS) {
613                         isdn_audio_goertzel(s->buf, info);
614                         s->idx = 0;
615                 }
616                 len -= c;
617         }
618 }
619
620 silence_state *
621 isdn_audio_silence_init(silence_state * s)
622 {
623         if (!s)
624                 s = kmalloc(sizeof(silence_state), GFP_ATOMIC);
625         if (s) {
626                 s->idx = 0;
627                 s->state = 0;
628         }
629         return s;
630 }
631
632 void
633 isdn_audio_calc_silence(modem_info * info, unsigned char *buf, int len, int fmt)
634 {
635         silence_state *s = info->silence_state;
636         int i;
637         signed char c;
638
639         if (!info->emu.vpar[1]) return;
640
641         for (i = 0; i < len; i++) {
642                 if (fmt)
643                     c = isdn_audio_alaw_to_ulaw[*buf++];
644                         else
645                     c = *buf++;
646
647                 if (c > 0) c -= 128;
648                 c = abs(c);
649
650                 if (c > (info->emu.vpar[1] * 4)) { 
651                         s->idx = 0;
652                         s->state = 1; 
653                 } else {
654                         if (s->idx < 210000) s->idx++; 
655                 }
656         }
657 }
658
659 void
660 isdn_audio_put_dle_code(modem_info * info, u_char code)
661 {
662         struct sk_buff *skb;
663         int di;
664         int ch;
665         char *p;
666
667         skb = dev_alloc_skb(2);
668         if (!skb) {
669                 printk(KERN_WARNING
670                   "isdn_audio: Could not alloc skb for ttyI%d\n",
671                        info->line);
672                 return;
673         }
674         p = (char *) skb_put(skb, 2);
675         p[0] = 0x10;
676         p[1] = code;
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]);
687 }
688
689 void
690 isdn_audio_eval_silence(modem_info * info)
691 {
692         silence_state *s = info->silence_state;
693         char what;
694
695         what = ' ';
696
697         if (s->idx > (info->emu.vpar[2] * 800)) { 
698                 s->idx = 0;
699                 if (!s->state) {        /* silence from beginning of rec */ 
700                         what = 's';
701                 } else {
702                         what = 'q';
703                 }
704         }
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);
709                 } 
710 }