Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
isdn_audio.c
Go to the documentation of this file.
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 ([email protected])
6  * DTMF code (c) 1996 by Christian Mock ([email protected])
7  * Silence detection (c) 1998 by Armin Schindler ([email protected])
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 *
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 *
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/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) {
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)
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);
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);
492 }
493 
494 void
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))
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 
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
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) {
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))
687  wake_up_interruptible(&dev->drv[di]->rcv_waitq[ch]);
688 }
689 
690 void
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 }