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