1 /* $Id: isdn_audio.c,v 1.21 2000/06/20 18:01:55 keil Exp $
3 * Linux ISDN subsystem, audio conversion and compression (linklevel).
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)
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2, or (at your option)
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #define __NO_VERSION__
26 #include <linux/module.h>
27 #include <linux/isdn.h>
28 #include "isdn_audio.h"
29 #include "isdn_common.h"
31 char *isdn_audio_revision
= "$Revision: 1.21 $";
34 * Misc. lookup-tables.
37 /* ulaw -> signed 16-bit */
38 static short isdn_audio_ulaw_to_s16
[] =
40 0x8284, 0x8684, 0x8a84, 0x8e84, 0x9284, 0x9684, 0x9a84, 0x9e84,
41 0xa284, 0xa684, 0xaa84, 0xae84, 0xb284, 0xb684, 0xba84, 0xbe84,
42 0xc184, 0xc384, 0xc584, 0xc784, 0xc984, 0xcb84, 0xcd84, 0xcf84,
43 0xd184, 0xd384, 0xd584, 0xd784, 0xd984, 0xdb84, 0xdd84, 0xdf84,
44 0xe104, 0xe204, 0xe304, 0xe404, 0xe504, 0xe604, 0xe704, 0xe804,
45 0xe904, 0xea04, 0xeb04, 0xec04, 0xed04, 0xee04, 0xef04, 0xf004,
46 0xf0c4, 0xf144, 0xf1c4, 0xf244, 0xf2c4, 0xf344, 0xf3c4, 0xf444,
47 0xf4c4, 0xf544, 0xf5c4, 0xf644, 0xf6c4, 0xf744, 0xf7c4, 0xf844,
48 0xf8a4, 0xf8e4, 0xf924, 0xf964, 0xf9a4, 0xf9e4, 0xfa24, 0xfa64,
49 0xfaa4, 0xfae4, 0xfb24, 0xfb64, 0xfba4, 0xfbe4, 0xfc24, 0xfc64,
50 0xfc94, 0xfcb4, 0xfcd4, 0xfcf4, 0xfd14, 0xfd34, 0xfd54, 0xfd74,
51 0xfd94, 0xfdb4, 0xfdd4, 0xfdf4, 0xfe14, 0xfe34, 0xfe54, 0xfe74,
52 0xfe8c, 0xfe9c, 0xfeac, 0xfebc, 0xfecc, 0xfedc, 0xfeec, 0xfefc,
53 0xff0c, 0xff1c, 0xff2c, 0xff3c, 0xff4c, 0xff5c, 0xff6c, 0xff7c,
54 0xff88, 0xff90, 0xff98, 0xffa0, 0xffa8, 0xffb0, 0xffb8, 0xffc0,
55 0xffc8, 0xffd0, 0xffd8, 0xffe0, 0xffe8, 0xfff0, 0xfff8, 0x0000,
56 0x7d7c, 0x797c, 0x757c, 0x717c, 0x6d7c, 0x697c, 0x657c, 0x617c,
57 0x5d7c, 0x597c, 0x557c, 0x517c, 0x4d7c, 0x497c, 0x457c, 0x417c,
58 0x3e7c, 0x3c7c, 0x3a7c, 0x387c, 0x367c, 0x347c, 0x327c, 0x307c,
59 0x2e7c, 0x2c7c, 0x2a7c, 0x287c, 0x267c, 0x247c, 0x227c, 0x207c,
60 0x1efc, 0x1dfc, 0x1cfc, 0x1bfc, 0x1afc, 0x19fc, 0x18fc, 0x17fc,
61 0x16fc, 0x15fc, 0x14fc, 0x13fc, 0x12fc, 0x11fc, 0x10fc, 0x0ffc,
62 0x0f3c, 0x0ebc, 0x0e3c, 0x0dbc, 0x0d3c, 0x0cbc, 0x0c3c, 0x0bbc,
63 0x0b3c, 0x0abc, 0x0a3c, 0x09bc, 0x093c, 0x08bc, 0x083c, 0x07bc,
64 0x075c, 0x071c, 0x06dc, 0x069c, 0x065c, 0x061c, 0x05dc, 0x059c,
65 0x055c, 0x051c, 0x04dc, 0x049c, 0x045c, 0x041c, 0x03dc, 0x039c,
66 0x036c, 0x034c, 0x032c, 0x030c, 0x02ec, 0x02cc, 0x02ac, 0x028c,
67 0x026c, 0x024c, 0x022c, 0x020c, 0x01ec, 0x01cc, 0x01ac, 0x018c,
68 0x0174, 0x0164, 0x0154, 0x0144, 0x0134, 0x0124, 0x0114, 0x0104,
69 0x00f4, 0x00e4, 0x00d4, 0x00c4, 0x00b4, 0x00a4, 0x0094, 0x0084,
70 0x0078, 0x0070, 0x0068, 0x0060, 0x0058, 0x0050, 0x0048, 0x0040,
71 0x0038, 0x0030, 0x0028, 0x0020, 0x0018, 0x0010, 0x0008, 0x0000
74 /* alaw -> signed 16-bit */
75 static short isdn_audio_alaw_to_s16
[] =
77 0x13fc, 0xec04, 0x0144, 0xfebc, 0x517c, 0xae84, 0x051c, 0xfae4,
78 0x0a3c, 0xf5c4, 0x0048, 0xffb8, 0x287c, 0xd784, 0x028c, 0xfd74,
79 0x1bfc, 0xe404, 0x01cc, 0xfe34, 0x717c, 0x8e84, 0x071c, 0xf8e4,
80 0x0e3c, 0xf1c4, 0x00c4, 0xff3c, 0x387c, 0xc784, 0x039c, 0xfc64,
81 0x0ffc, 0xf004, 0x0104, 0xfefc, 0x417c, 0xbe84, 0x041c, 0xfbe4,
82 0x083c, 0xf7c4, 0x0008, 0xfff8, 0x207c, 0xdf84, 0x020c, 0xfdf4,
83 0x17fc, 0xe804, 0x018c, 0xfe74, 0x617c, 0x9e84, 0x061c, 0xf9e4,
84 0x0c3c, 0xf3c4, 0x0084, 0xff7c, 0x307c, 0xcf84, 0x030c, 0xfcf4,
85 0x15fc, 0xea04, 0x0164, 0xfe9c, 0x597c, 0xa684, 0x059c, 0xfa64,
86 0x0b3c, 0xf4c4, 0x0068, 0xff98, 0x2c7c, 0xd384, 0x02cc, 0xfd34,
87 0x1dfc, 0xe204, 0x01ec, 0xfe14, 0x797c, 0x8684, 0x07bc, 0xf844,
88 0x0f3c, 0xf0c4, 0x00e4, 0xff1c, 0x3c7c, 0xc384, 0x03dc, 0xfc24,
89 0x11fc, 0xee04, 0x0124, 0xfedc, 0x497c, 0xb684, 0x049c, 0xfb64,
90 0x093c, 0xf6c4, 0x0028, 0xffd8, 0x247c, 0xdb84, 0x024c, 0xfdb4,
91 0x19fc, 0xe604, 0x01ac, 0xfe54, 0x697c, 0x9684, 0x069c, 0xf964,
92 0x0d3c, 0xf2c4, 0x00a4, 0xff5c, 0x347c, 0xcb84, 0x034c, 0xfcb4,
93 0x12fc, 0xed04, 0x0134, 0xfecc, 0x4d7c, 0xb284, 0x04dc, 0xfb24,
94 0x09bc, 0xf644, 0x0038, 0xffc8, 0x267c, 0xd984, 0x026c, 0xfd94,
95 0x1afc, 0xe504, 0x01ac, 0xfe54, 0x6d7c, 0x9284, 0x06dc, 0xf924,
96 0x0dbc, 0xf244, 0x00b4, 0xff4c, 0x367c, 0xc984, 0x036c, 0xfc94,
97 0x0f3c, 0xf0c4, 0x00f4, 0xff0c, 0x3e7c, 0xc184, 0x03dc, 0xfc24,
98 0x07bc, 0xf844, 0x0008, 0xfff8, 0x1efc, 0xe104, 0x01ec, 0xfe14,
99 0x16fc, 0xe904, 0x0174, 0xfe8c, 0x5d7c, 0xa284, 0x05dc, 0xfa24,
100 0x0bbc, 0xf444, 0x0078, 0xff88, 0x2e7c, 0xd184, 0x02ec, 0xfd14,
101 0x14fc, 0xeb04, 0x0154, 0xfeac, 0x557c, 0xaa84, 0x055c, 0xfaa4,
102 0x0abc, 0xf544, 0x0058, 0xffa8, 0x2a7c, 0xd584, 0x02ac, 0xfd54,
103 0x1cfc, 0xe304, 0x01cc, 0xfe34, 0x757c, 0x8a84, 0x075c, 0xf8a4,
104 0x0ebc, 0xf144, 0x00d4, 0xff2c, 0x3a7c, 0xc584, 0x039c, 0xfc64,
105 0x10fc, 0xef04, 0x0114, 0xfeec, 0x457c, 0xba84, 0x045c, 0xfba4,
106 0x08bc, 0xf744, 0x0018, 0xffe8, 0x227c, 0xdd84, 0x022c, 0xfdd4,
107 0x18fc, 0xe704, 0x018c, 0xfe74, 0x657c, 0x9a84, 0x065c, 0xf9a4,
108 0x0cbc, 0xf344, 0x0094, 0xff6c, 0x327c, 0xcd84, 0x032c, 0xfcd4
112 static char isdn_audio_alaw_to_ulaw
[] =
114 0xab, 0x2b, 0xe3, 0x63, 0x8b, 0x0b, 0xc9, 0x49,
115 0xba, 0x3a, 0xf6, 0x76, 0x9b, 0x1b, 0xd7, 0x57,
116 0xa3, 0x23, 0xdd, 0x5d, 0x83, 0x03, 0xc1, 0x41,
117 0xb2, 0x32, 0xeb, 0x6b, 0x93, 0x13, 0xcf, 0x4f,
118 0xaf, 0x2f, 0xe7, 0x67, 0x8f, 0x0f, 0xcd, 0x4d,
119 0xbe, 0x3e, 0xfe, 0x7e, 0x9f, 0x1f, 0xdb, 0x5b,
120 0xa7, 0x27, 0xdf, 0x5f, 0x87, 0x07, 0xc5, 0x45,
121 0xb6, 0x36, 0xef, 0x6f, 0x97, 0x17, 0xd3, 0x53,
122 0xa9, 0x29, 0xe1, 0x61, 0x89, 0x09, 0xc7, 0x47,
123 0xb8, 0x38, 0xf2, 0x72, 0x99, 0x19, 0xd5, 0x55,
124 0xa1, 0x21, 0xdc, 0x5c, 0x81, 0x01, 0xbf, 0x3f,
125 0xb0, 0x30, 0xe9, 0x69, 0x91, 0x11, 0xce, 0x4e,
126 0xad, 0x2d, 0xe5, 0x65, 0x8d, 0x0d, 0xcb, 0x4b,
127 0xbc, 0x3c, 0xfa, 0x7a, 0x9d, 0x1d, 0xd9, 0x59,
128 0xa5, 0x25, 0xde, 0x5e, 0x85, 0x05, 0xc3, 0x43,
129 0xb4, 0x34, 0xed, 0x6d, 0x95, 0x15, 0xd1, 0x51,
130 0xac, 0x2c, 0xe4, 0x64, 0x8c, 0x0c, 0xca, 0x4a,
131 0xbb, 0x3b, 0xf8, 0x78, 0x9c, 0x1c, 0xd8, 0x58,
132 0xa4, 0x24, 0xde, 0x5e, 0x84, 0x04, 0xc2, 0x42,
133 0xb3, 0x33, 0xec, 0x6c, 0x94, 0x14, 0xd0, 0x50,
134 0xb0, 0x30, 0xe8, 0x68, 0x90, 0x10, 0xce, 0x4e,
135 0xbf, 0x3f, 0xfe, 0x7e, 0xa0, 0x20, 0xdc, 0x5c,
136 0xa8, 0x28, 0xe0, 0x60, 0x88, 0x08, 0xc6, 0x46,
137 0xb7, 0x37, 0xf0, 0x70, 0x98, 0x18, 0xd4, 0x54,
138 0xaa, 0x2a, 0xe2, 0x62, 0x8a, 0x0a, 0xc8, 0x48,
139 0xb9, 0x39, 0xf4, 0x74, 0x9a, 0x1a, 0xd6, 0x56,
140 0xa2, 0x22, 0xdd, 0x5d, 0x82, 0x02, 0xc0, 0x40,
141 0xb1, 0x31, 0xea, 0x6a, 0x92, 0x12, 0xcf, 0x4f,
142 0xae, 0x2e, 0xe6, 0x66, 0x8e, 0x0e, 0xcc, 0x4c,
143 0xbd, 0x3d, 0xfc, 0x7c, 0x9e, 0x1e, 0xda, 0x5a,
144 0xa6, 0x26, 0xdf, 0x5f, 0x86, 0x06, 0xc4, 0x44,
145 0xb5, 0x35, 0xee, 0x6e, 0x96, 0x16, 0xd2, 0x52
149 static char isdn_audio_ulaw_to_alaw
[] =
151 0xab, 0x55, 0xd5, 0x15, 0x95, 0x75, 0xf5, 0x35,
152 0xb5, 0x45, 0xc5, 0x05, 0x85, 0x65, 0xe5, 0x25,
153 0xa5, 0x5d, 0xdd, 0x1d, 0x9d, 0x7d, 0xfd, 0x3d,
154 0xbd, 0x4d, 0xcd, 0x0d, 0x8d, 0x6d, 0xed, 0x2d,
155 0xad, 0x51, 0xd1, 0x11, 0x91, 0x71, 0xf1, 0x31,
156 0xb1, 0x41, 0xc1, 0x01, 0x81, 0x61, 0xe1, 0x21,
157 0x59, 0xd9, 0x19, 0x99, 0x79, 0xf9, 0x39, 0xb9,
158 0x49, 0xc9, 0x09, 0x89, 0x69, 0xe9, 0x29, 0xa9,
159 0xd7, 0x17, 0x97, 0x77, 0xf7, 0x37, 0xb7, 0x47,
160 0xc7, 0x07, 0x87, 0x67, 0xe7, 0x27, 0xa7, 0xdf,
161 0x9f, 0x7f, 0xff, 0x3f, 0xbf, 0x4f, 0xcf, 0x0f,
162 0x8f, 0x6f, 0xef, 0x2f, 0x53, 0x13, 0x73, 0x33,
163 0xb3, 0x43, 0xc3, 0x03, 0x83, 0x63, 0xe3, 0x23,
164 0xa3, 0x5b, 0xdb, 0x1b, 0x9b, 0x7b, 0xfb, 0x3b,
165 0xbb, 0xbb, 0x4b, 0x4b, 0xcb, 0xcb, 0x0b, 0x0b,
166 0x8b, 0x8b, 0x6b, 0x6b, 0xeb, 0xeb, 0x2b, 0x2b,
167 0xab, 0x54, 0xd4, 0x14, 0x94, 0x74, 0xf4, 0x34,
168 0xb4, 0x44, 0xc4, 0x04, 0x84, 0x64, 0xe4, 0x24,
169 0xa4, 0x5c, 0xdc, 0x1c, 0x9c, 0x7c, 0xfc, 0x3c,
170 0xbc, 0x4c, 0xcc, 0x0c, 0x8c, 0x6c, 0xec, 0x2c,
171 0xac, 0x50, 0xd0, 0x10, 0x90, 0x70, 0xf0, 0x30,
172 0xb0, 0x40, 0xc0, 0x00, 0x80, 0x60, 0xe0, 0x20,
173 0x58, 0xd8, 0x18, 0x98, 0x78, 0xf8, 0x38, 0xb8,
174 0x48, 0xc8, 0x08, 0x88, 0x68, 0xe8, 0x28, 0xa8,
175 0xd6, 0x16, 0x96, 0x76, 0xf6, 0x36, 0xb6, 0x46,
176 0xc6, 0x06, 0x86, 0x66, 0xe6, 0x26, 0xa6, 0xde,
177 0x9e, 0x7e, 0xfe, 0x3e, 0xbe, 0x4e, 0xce, 0x0e,
178 0x8e, 0x6e, 0xee, 0x2e, 0x52, 0x12, 0x72, 0x32,
179 0xb2, 0x42, 0xc2, 0x02, 0x82, 0x62, 0xe2, 0x22,
180 0xa2, 0x5a, 0xda, 0x1a, 0x9a, 0x7a, 0xfa, 0x3a,
181 0xba, 0xba, 0x4a, 0x4a, 0xca, 0xca, 0x0a, 0x0a,
182 0x8a, 0x8a, 0x6a, 0x6a, 0xea, 0xea, 0x2a, 0x2a
185 #define NCOEFF 16 /* number of frequencies to be analyzed */
186 #define DTMF_TRESH 25000 /* above this is dtmf */
187 #define SILENCE_TRESH 200 /* below this is silence */
188 #define H2_TRESH 20000 /* 2nd harmonic */
189 #define AMP_BITS 9 /* bits per sample, reduced to avoid overflow */
194 int grp
; /* low/high group */
196 int k2
; /* k fuer 2. harmonic */
199 /* For DTMF recognition:
200 * 2 * cos(2 * PI * k / N) precalculated for all k
202 static int cos2pik
[NCOEFF
] =
204 55812, 29528, 53603, 24032, 51193, 14443, 48590, 6517,
205 38113, -21204, 33057, -32186, 25889, -45081, 18332, -55279
208 static dtmf_t dtmf_tones
[8] =
210 {LOGRP
, 0, 1}, /* 697 Hz */
211 {LOGRP
, 2, 3}, /* 770 Hz */
212 {LOGRP
, 4, 5}, /* 852 Hz */
213 {LOGRP
, 6, 7}, /* 941 Hz */
214 {HIGRP
, 8, 9}, /* 1209 Hz */
215 {HIGRP
, 10, 11}, /* 1336 Hz */
216 {HIGRP
, 12, 13}, /* 1477 Hz */
217 {HIGRP
, 14, 15} /* 1633 Hz */
220 static char dtmf_matrix
[4][4] =
222 {'1', '2', '3', 'A'},
223 {'4', '5', '6', 'B'},
224 {'7', '8', '9', 'C'},
229 isdn_audio_tlookup(const u_char
*table
, u_char
*buff
, unsigned long n
)
232 unsigned long d0
, d1
, d2
, d3
;
233 __asm__
__volatile__(
239 : "=&b"(d0
), "=&c"(d1
), "=&D"(d2
), "=&S"(d3
)
240 : "0"((long) table
), "1"(n
), "2"((long) buff
), "3"((long) buff
)
244 *buff
++ = table
[*(unsigned char *)buff
];
249 isdn_audio_ulaw2alaw(unsigned char *buff
, unsigned long len
)
251 isdn_audio_tlookup(isdn_audio_ulaw_to_alaw
, buff
, len
);
255 isdn_audio_alaw2ulaw(unsigned char *buff
, unsigned long len
)
257 isdn_audio_tlookup(isdn_audio_alaw_to_ulaw
, buff
, len
);
261 * linear <-> adpcm conversion stuff
262 * Most parts from the mgetty-package.
263 * (C) by Gert Doering and Klaus Weidner
264 * Used by permission of Gert Doering
268 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
270 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
274 isdn_audio_linear2ulaw(int sample
)
276 static int exp_lut
[256] =
278 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
279 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
280 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
281 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
282 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
283 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
284 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
285 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
286 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
287 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
288 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
289 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
290 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
291 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
292 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
293 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
298 unsigned char ulawbyte
;
300 /* Get the sample into sign-magnitude. */
301 sign
= (sample
>> 8) & 0x80; /* set aside the sign */
303 sample
= -sample
; /* get magnitude */
305 sample
= CLIP
; /* clip the magnitude */
307 /* Convert from 16 bit linear to ulaw. */
308 sample
= sample
+ BIAS
;
309 exponent
= exp_lut
[(sample
>> 7) & 0xFF];
310 mantissa
= (sample
>> (exponent
+ 3)) & 0x0F;
311 ulawbyte
= ~(sign
| (exponent
<< 4) | mantissa
);
313 /* optional CCITT trap */
321 static int Mx
[3][8] =
323 {0x3800, 0x5600, 0, 0, 0, 0, 0, 0},
324 {0x399a, 0x3a9f, 0x4d14, 0x6607, 0, 0, 0, 0},
325 {0x3556, 0x3556, 0x399A, 0x3A9F, 0x4200, 0x4D14, 0x6607, 0x6607},
328 static int bitmask
[9] =
330 0, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff
334 isdn_audio_get_bits(adpcm_state
* s
, unsigned char **in
, int *len
)
336 while (s
->nleft
< s
->nbits
) {
339 s
->word
= (s
->word
<< 8) | d
;
342 s
->nleft
-= s
->nbits
;
343 return (s
->word
>> s
->nleft
) & bitmask
[s
->nbits
];
347 isdn_audio_put_bits(int data
, int nbits
, adpcm_state
* s
,
348 unsigned char **out
, int *len
)
350 s
->word
= (s
->word
<< nbits
) | (data
& bitmask
[nbits
]);
352 while (s
->nleft
>= 8) {
353 int d
= (s
->word
>> (s
->nleft
- 8));
354 *(out
[0]++) = d
& 255;
361 isdn_audio_adpcm_init(adpcm_state
* s
, int nbits
)
364 s
= (adpcm_state
*) kmalloc(sizeof(adpcm_state
), GFP_ATOMIC
);
376 isdn_audio_dtmf_init(dtmf_state
* s
)
379 s
= (dtmf_state
*) kmalloc(sizeof(dtmf_state
), GFP_ATOMIC
);
388 * Decompression of adpcm data to a/u-law
393 isdn_audio_adpcm2xlaw(adpcm_state
* s
, int fmt
, unsigned char *in
,
394 unsigned char *out
, int len
)
398 int nbits
= s
->nbits
;
402 int e
= isdn_audio_get_bits(s
, &in
, &len
);
405 if (nbits
== 4 && e
== 0)
407 sign
= (e
>> (nbits
- 1)) ? -1 : 1;
408 e
&= bitmask
[nbits
- 1];
409 a
+= sign
* ((e
<< 1) + 1) * d
>> 1;
413 *out
++ = isdn_audio_ulaw_to_alaw
[
414 isdn_audio_linear2ulaw(a
<< 2)];
416 *out
++ = isdn_audio_linear2ulaw(a
<< 2);
418 d
= (d
* Mx
[nbits
- 2][e
] + 0x2000) >> 14;
428 isdn_audio_2adpcm_flush(adpcm_state
* s
, unsigned char *out
)
433 isdn_audio_put_bits(0, 8 - s
->nleft
, s
, &out
, &olen
);
438 isdn_audio_xlaw2adpcm(adpcm_state
* s
, int fmt
, unsigned char *in
,
439 unsigned char *out
, int len
)
443 int nbits
= s
->nbits
;
448 nmax
= 1 << (nbits
- 1);
453 delta
= (isdn_audio_alaw_to_s16
[*in
++] >> 2) - a
;
455 delta
= (isdn_audio_ulaw_to_s16
[*in
++] >> 2) - a
;
460 while (--nmax
&& delta
> d
) {
464 if (nbits
== 4 && ((e
& 0x0f) == 0))
466 isdn_audio_put_bits(e
, nbits
, s
, &out
, &olen
);
467 sign
= (e
>> (nbits
- 1)) ? -1 : 1;
468 e
&= bitmask
[nbits
- 1];
470 a
+= sign
* ((e
<< 1) + 1) * d
>> 1;
473 d
= (d
* Mx
[nbits
- 2][e
] + 0x2000) >> 14;
483 * Goertzel algorithm.
484 * See http://ptolemy.eecs.berkeley.edu/~pino/Ptolemy/papers/96/dtmf_ict/
486 * Result is stored into an sk_buff and queued up for later
490 isdn_audio_goertzel(int *sample
, modem_info
* info
)
500 skb
= dev_alloc_skb(sizeof(int) * NCOEFF
);
503 "isdn_audio: Could not alloc DTMF result for ttyI%d\n",
507 result
= (int *) skb_put(skb
, sizeof(int) * NCOEFF
);
508 for (k
= 0; k
< NCOEFF
; k
++) {
510 for (n
= 0; n
< DTMF_NPOINTS
; n
++) {
511 sk
= sample
[n
] + ((cos2pik
[k
] * sk1
) >> 15) - sk2
;
516 ((sk
* sk
) >> AMP_BITS
) -
517 ((((cos2pik
[k
] * sk
) >> 15) * sk2
) >> AMP_BITS
) +
518 ((sk2
* sk2
) >> AMP_BITS
);
520 skb_queue_tail(&info
->dtmf_queue
, skb
);
521 isdn_timer_ctrl(ISDN_TIMER_MODEMREAD
, 1);
525 isdn_audio_eval_dtmf(modem_info
* info
)
539 while ((skb
= skb_dequeue(&info
->dtmf_queue
))) {
540 result
= (int *) skb
->data
;
541 s
= info
->dtmf_state
;
542 grp
[LOGRP
] = grp
[HIGRP
] = -2;
544 for (i
= 0; i
< 8; i
++) {
545 if ((result
[dtmf_tones
[i
].k
] > DTMF_TRESH
) &&
546 (result
[dtmf_tones
[i
].k2
] < H2_TRESH
))
547 grp
[dtmf_tones
[i
].grp
] = (grp
[dtmf_tones
[i
].grp
] == -2) ? i
: -1;
548 else if ((result
[dtmf_tones
[i
].k
] < SILENCE_TRESH
) &&
549 (result
[dtmf_tones
[i
].k2
] < SILENCE_TRESH
))
555 if ((grp
[LOGRP
] >= 0) && (grp
[HIGRP
] >= 0)) {
556 what
= dtmf_matrix
[grp
[LOGRP
]][grp
[HIGRP
] - 4];
557 if (s
->last
!= ' ' && s
->last
!= '.')
558 s
->last
= what
; /* min. 1 non-DTMF between DTMF */
562 if ((what
!= s
->last
) && (what
!= ' ') && (what
!= '.')) {
563 printk(KERN_DEBUG
"dtmf: tt='%c'\n", what
);
568 if (skb_headroom(skb
) < sizeof(isdn_audio_skb
)) {
570 "isdn_audio: insufficient skb_headroom, dropping\n");
574 ISDN_AUDIO_SKB_DLECOUNT(skb
) = 0;
575 ISDN_AUDIO_SKB_LOCK(skb
) = 0;
578 di
= info
->isdn_driver
;
579 ch
= info
->isdn_channel
;
580 __skb_queue_tail(&dev
->drv
[di
]->rpqueue
[ch
], skb
);
581 dev
->drv
[di
]->rcvcount
[ch
] += 2;
582 restore_flags(flags
);
583 /* Schedule dequeuing */
584 if ((dev
->modempoll
) && (info
->rcvsched
))
585 isdn_timer_ctrl(ISDN_TIMER_MODEMREAD
, 1);
586 wake_up_interruptible(&dev
->drv
[di
]->rcv_waitq
[ch
]);
594 * Decode DTMF tones, queue result in separate sk_buf for
597 * s = pointer to state-struct.
598 * buf = input audio data
599 * len = size of audio data.
600 * fmt = audio data format (0 = ulaw, 1 = alaw)
603 isdn_audio_calc_dtmf(modem_info
* info
, unsigned char *buf
, int len
, int fmt
)
605 dtmf_state
*s
= info
->dtmf_state
;
610 c
= MIN(len
, (DTMF_NPOINTS
- s
->idx
));
613 for (i
= 0; i
< c
; i
++) {
616 isdn_audio_alaw_to_s16
[*buf
++] >> (15 - AMP_BITS
);
619 isdn_audio_ulaw_to_s16
[*buf
++] >> (15 - AMP_BITS
);
621 if (s
->idx
== DTMF_NPOINTS
) {
622 isdn_audio_goertzel(s
->buf
, info
);
630 isdn_audio_silence_init(silence_state
* s
)
633 s
= (silence_state
*) kmalloc(sizeof(silence_state
), GFP_ATOMIC
);
642 isdn_audio_calc_silence(modem_info
* info
, unsigned char *buf
, int len
, int fmt
)
644 silence_state
*s
= info
->silence_state
;
648 if (!info
->emu
.vpar
[1]) return;
650 for (i
= 0; i
< len
; i
++) {
652 c
= isdn_audio_alaw_to_ulaw
[*buf
++];
659 if (c
> (info
->emu
.vpar
[1] * 4)) {
663 if (s
->idx
< 210000) s
->idx
++;
669 isdn_audio_put_dle_code(modem_info
* info
, u_char code
)
677 skb
= dev_alloc_skb(2);
680 "isdn_audio: Could not alloc skb for ttyI%d\n",
684 p
= (char *) skb_put(skb
, 2);
687 if (skb_headroom(skb
) < sizeof(isdn_audio_skb
)) {
689 "isdn_audio: insufficient skb_headroom, dropping\n");
693 ISDN_AUDIO_SKB_DLECOUNT(skb
) = 0;
694 ISDN_AUDIO_SKB_LOCK(skb
) = 0;
697 di
= info
->isdn_driver
;
698 ch
= info
->isdn_channel
;
699 __skb_queue_tail(&dev
->drv
[di
]->rpqueue
[ch
], skb
);
700 dev
->drv
[di
]->rcvcount
[ch
] += 2;
701 restore_flags(flags
);
702 /* Schedule dequeuing */
703 if ((dev
->modempoll
) && (info
->rcvsched
))
704 isdn_timer_ctrl(ISDN_TIMER_MODEMREAD
, 1);
705 wake_up_interruptible(&dev
->drv
[di
]->rcv_waitq
[ch
]);
709 isdn_audio_eval_silence(modem_info
* info
)
711 silence_state
*s
= info
->silence_state
;
716 if (s
->idx
> (info
->emu
.vpar
[2] * 800)) {
718 if (!s
->state
) { /* silence from beginning of rec */
724 if ((what
== 's') || (what
== 'q')) {
725 printk(KERN_DEBUG
"ttyI%d: %s\n", info
->line
,
726 (what
=='s') ? "silence":"quiet");
727 isdn_audio_put_dle_code(info
, what
);