xref: /openbmc/linux/drivers/isdn/mISDN/dsp_tones.c (revision a09d2831)
1 /*
2  * Audio support data for ISDN4Linux.
3  *
4  * Copyright Andreas Eversberg (jolly@eversberg.eu)
5  *
6  * This software may be used and distributed according to the terms
7  * of the GNU General Public License, incorporated herein by reference.
8  *
9  */
10 
11 #include <linux/mISDNif.h>
12 #include <linux/mISDNdsp.h>
13 #include "core.h"
14 #include "dsp.h"
15 
16 
17 #define DATA_S sample_silence
18 #define SIZE_S (&sizeof_silence)
19 #define DATA_GA sample_german_all
20 #define SIZE_GA (&sizeof_german_all)
21 #define DATA_GO sample_german_old
22 #define SIZE_GO (&sizeof_german_old)
23 #define DATA_DT sample_american_dialtone
24 #define SIZE_DT (&sizeof_american_dialtone)
25 #define DATA_RI sample_american_ringing
26 #define SIZE_RI (&sizeof_american_ringing)
27 #define DATA_BU sample_american_busy
28 #define SIZE_BU (&sizeof_american_busy)
29 #define DATA_S1 sample_special1
30 #define SIZE_S1 (&sizeof_special1)
31 #define DATA_S2 sample_special2
32 #define SIZE_S2 (&sizeof_special2)
33 #define DATA_S3 sample_special3
34 #define SIZE_S3 (&sizeof_special3)
35 
36 /***************/
37 /* tones loops */
38 /***************/
39 
40 /* all tones are alaw encoded */
41 /* the last sample+1 is in phase with the first sample. the error is low */
42 
43 static u8 sample_german_all[] = {
44 	0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
45 	0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
46 	0xdc, 0xfc, 0x6c,
47 	0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
48 	0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
49 	0xdc, 0xfc, 0x6c,
50 	0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
51 	0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
52 	0xdc, 0xfc, 0x6c,
53 	0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
54 	0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
55 	0xdc, 0xfc, 0x6c,
56 };
57 static u32 sizeof_german_all = sizeof(sample_german_all);
58 
59 static u8 sample_german_old[] = {
60 	0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
61 	0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
62 	0x8c,
63 	0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
64 	0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
65 	0x8c,
66 	0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
67 	0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
68 	0x8c,
69 	0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
70 	0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
71 	0x8c,
72 };
73 static u32 sizeof_german_old = sizeof(sample_german_old);
74 
75 static u8 sample_american_dialtone[] = {
76 	0x2a, 0x18, 0x90, 0x6c, 0x4c, 0xbc, 0x4c, 0x6c,
77 	0x10, 0x58, 0x32, 0xb9, 0x31, 0x2d, 0x8d, 0x0d,
78 	0x8d, 0x2d, 0x31, 0x99, 0x0f, 0x28, 0x60, 0xf0,
79 	0xd0, 0x50, 0xd0, 0x30, 0x60, 0x08, 0x8e, 0x67,
80 	0x09, 0x19, 0x21, 0xe1, 0xd9, 0xb9, 0x29, 0x67,
81 	0x83, 0x02, 0xce, 0xbe, 0xee, 0x1a, 0x1b, 0xef,
82 	0xbf, 0xcf, 0x03, 0x82, 0x66, 0x28, 0xb8, 0xd8,
83 	0xe0, 0x20, 0x18, 0x08, 0x66, 0x8f, 0x09, 0x61,
84 	0x31, 0xd1, 0x51, 0xd1, 0xf1, 0x61, 0x29, 0x0e,
85 	0x98, 0x30, 0x2c, 0x8c, 0x0c, 0x8c, 0x2c, 0x30,
86 	0xb8, 0x33, 0x59, 0x11, 0x6d, 0x4d, 0xbd, 0x4d,
87 	0x6d, 0x91, 0x19,
88 };
89 static u32 sizeof_american_dialtone = sizeof(sample_american_dialtone);
90 
91 static u8 sample_american_ringing[] = {
92 	0x2a, 0xe0, 0xac, 0x0c, 0xbc, 0x4c, 0x8c, 0x90,
93 	0x48, 0xc7, 0xc1, 0xed, 0xcd, 0x4d, 0xcd, 0xed,
94 	0xc1, 0xb7, 0x08, 0x30, 0xec, 0xcc, 0xcc, 0x8c,
95 	0x10, 0x58, 0x1a, 0x99, 0x71, 0xed, 0x8d, 0x8d,
96 	0x2d, 0x41, 0x89, 0x9e, 0x20, 0x70, 0x2c, 0xec,
97 	0x2c, 0x70, 0x20, 0x86, 0x77, 0xe1, 0x31, 0x11,
98 	0xd1, 0xf1, 0x81, 0x09, 0xa3, 0x56, 0x58, 0x00,
99 	0x40, 0xc0, 0x60, 0x38, 0x46, 0x43, 0x57, 0x39,
100 	0xd9, 0x59, 0x99, 0xc9, 0x77, 0x2f, 0x2e, 0xc6,
101 	0xd6, 0x28, 0xd6, 0x36, 0x26, 0x2e, 0x8a, 0xa3,
102 	0x43, 0x63, 0x4b, 0x4a, 0x62, 0x42, 0xa2, 0x8b,
103 	0x2f, 0x27, 0x37, 0xd7, 0x29, 0xd7, 0xc7, 0x2f,
104 	0x2e, 0x76, 0xc8, 0x98, 0x58, 0xd8, 0x38, 0x56,
105 	0x42, 0x47, 0x39, 0x61, 0xc1, 0x41, 0x01, 0x59,
106 	0x57, 0xa2, 0x08, 0x80, 0xf0, 0xd0, 0x10, 0x30,
107 	0xe0, 0x76, 0x87, 0x21, 0x71, 0x2d, 0xed, 0x2d,
108 	0x71, 0x21, 0x9f, 0x88, 0x40, 0x2c, 0x8c, 0x8c,
109 	0xec, 0x70, 0x98, 0x1b, 0x59, 0x11, 0x8d, 0xcd,
110 	0xcd, 0xed, 0x31, 0x09, 0xb6, 0xc0, 0xec, 0xcc,
111 	0x4c, 0xcc, 0xec, 0xc0, 0xc6, 0x49, 0x91, 0x8d,
112 	0x4d, 0xbd, 0x0d, 0xad, 0xe1,
113 };
114 static u32 sizeof_american_ringing = sizeof(sample_american_ringing);
115 
116 static u8 sample_american_busy[] = {
117 	0x2a, 0x00, 0x6c, 0x4c, 0x4c, 0x6c, 0xb0, 0x66,
118 	0x99, 0x11, 0x6d, 0x8d, 0x2d, 0x41, 0xd7, 0x96,
119 	0x60, 0xf0, 0x70, 0x40, 0x58, 0xf6, 0x53, 0x57,
120 	0x09, 0x89, 0xd7, 0x5f, 0xe3, 0x2a, 0xe3, 0x5f,
121 	0xd7, 0x89, 0x09, 0x57, 0x53, 0xf6, 0x58, 0x40,
122 	0x70, 0xf0, 0x60, 0x96, 0xd7, 0x41, 0x2d, 0x8d,
123 	0x6d, 0x11, 0x99, 0x66, 0xb0, 0x6c, 0x4c, 0x4c,
124 	0x6c, 0x00, 0x2a, 0x01, 0x6d, 0x4d, 0x4d, 0x6d,
125 	0xb1, 0x67, 0x98, 0x10, 0x6c, 0x8c, 0x2c, 0x40,
126 	0xd6, 0x97, 0x61, 0xf1, 0x71, 0x41, 0x59, 0xf7,
127 	0x52, 0x56, 0x08, 0x88, 0xd6, 0x5e, 0xe2, 0x2a,
128 	0xe2, 0x5e, 0xd6, 0x88, 0x08, 0x56, 0x52, 0xf7,
129 	0x59, 0x41, 0x71, 0xf1, 0x61, 0x97, 0xd6, 0x40,
130 	0x2c, 0x8c, 0x6c, 0x10, 0x98, 0x67, 0xb1, 0x6d,
131 	0x4d, 0x4d, 0x6d, 0x01,
132 };
133 static u32 sizeof_american_busy = sizeof(sample_american_busy);
134 
135 static u8 sample_special1[] = {
136 	0x2a, 0x2c, 0xbc, 0x6c, 0xd6, 0x71, 0xbd, 0x0d,
137 	0xd9, 0x80, 0xcc, 0x4c, 0x40, 0x39, 0x0d, 0xbd,
138 	0x11, 0x86, 0xec, 0xbc, 0xec, 0x0e, 0x51, 0xbd,
139 	0x8d, 0x89, 0x30, 0x4c, 0xcc, 0xe0, 0xe1, 0xcd,
140 	0x4d, 0x31, 0x88, 0x8c, 0xbc, 0x50, 0x0f, 0xed,
141 	0xbd, 0xed, 0x87, 0x10, 0xbc, 0x0c, 0x38, 0x41,
142 	0x4d, 0xcd, 0x81, 0xd8, 0x0c, 0xbc, 0x70, 0xd7,
143 	0x6d, 0xbd, 0x2d,
144 };
145 static u32 sizeof_special1 = sizeof(sample_special1);
146 
147 static u8 sample_special2[] = {
148 	0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc,
149 	0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d,
150 	0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6,
151 	0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0,
152 	0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd,
153 	0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc,
154 	0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d,
155 	0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6,
156 	0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0,
157 	0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd,
158 };
159 static u32 sizeof_special2 = sizeof(sample_special2);
160 
161 static u8 sample_special3[] = {
162 	0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1,
163 	0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c,
164 	0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc,
165 	0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7,
166 	0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd,
167 	0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1,
168 	0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c,
169 	0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc,
170 	0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7,
171 	0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd,
172 };
173 static u32 sizeof_special3 = sizeof(sample_special3);
174 
175 static u8 sample_silence[] = {
176 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
177 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
178 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
179 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
180 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
181 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
182 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
183 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
184 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
185 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
186 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
187 	0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
188 };
189 static u32 sizeof_silence = sizeof(sample_silence);
190 
191 struct tones_samples {
192 	u32 *len;
193 	u8 *data;
194 };
195 static struct
196 tones_samples samples[] = {
197 	{&sizeof_german_all, sample_german_all},
198 	{&sizeof_german_old, sample_german_old},
199 	{&sizeof_american_dialtone, sample_american_dialtone},
200 	{&sizeof_american_ringing, sample_american_ringing},
201 	{&sizeof_american_busy, sample_american_busy},
202 	{&sizeof_special1, sample_special1},
203 	{&sizeof_special2, sample_special2},
204 	{&sizeof_special3, sample_special3},
205 	{NULL, NULL},
206 };
207 
208 /***********************************
209  * generate ulaw from alaw samples *
210  ***********************************/
211 
212 void
213 dsp_audio_generate_ulaw_samples(void)
214 {
215 	int i, j;
216 
217 	i = 0;
218 	while (samples[i].len) {
219 		j = 0;
220 		while (j < (*samples[i].len)) {
221 			samples[i].data[j] =
222 				dsp_audio_alaw_to_ulaw[samples[i].data[j]];
223 			j++;
224 		}
225 		i++;
226 	}
227 }
228 
229 
230 /****************************
231  * tone sequence definition *
232  ****************************/
233 
234 static struct pattern {
235 	int tone;
236 	u8 *data[10];
237 	u32 *siz[10];
238 	u32 seq[10];
239 } pattern[] = {
240 	{TONE_GERMAN_DIALTONE,
241 	{DATA_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
242 	{SIZE_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
243 	{1900, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
244 
245 	{TONE_GERMAN_OLDDIALTONE,
246 	{DATA_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
247 	{SIZE_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
248 	{1998, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
249 
250 	{TONE_AMERICAN_DIALTONE,
251 	{DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
252 	{SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
253 	{8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
254 
255 	{TONE_GERMAN_DIALPBX,
256 	{DATA_GA, DATA_S, DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL,
257 		NULL},
258 	{SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL,
259 		NULL},
260 	{2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
261 
262 	{TONE_GERMAN_OLDDIALPBX,
263 	{DATA_GO, DATA_S, DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL,
264 		NULL},
265 	{SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL,
266 		NULL},
267 	{2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
268 
269 	{TONE_AMERICAN_DIALPBX,
270 	{DATA_DT, DATA_S, DATA_DT, DATA_S, DATA_DT, DATA_S, NULL, NULL, NULL,
271 		NULL},
272 	{SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, NULL, NULL, NULL,
273 		NULL},
274 	{2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
275 
276 	{TONE_GERMAN_RINGING,
277 	{DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
278 	{SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
279 	{8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
280 
281 	{TONE_GERMAN_OLDRINGING,
282 	{DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
283 	{SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
284 	{8000, 40000, 0, 0, 0, 0, 0, 0, 0, 0} },
285 
286 	{TONE_AMERICAN_RINGING,
287 	{DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
288 	{SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
289 	{8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
290 
291 	{TONE_GERMAN_RINGPBX,
292 	{DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
293 	{SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
294 	{4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
295 
296 	{TONE_GERMAN_OLDRINGPBX,
297 	{DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
298 	{SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
299 	{4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
300 
301 	{TONE_AMERICAN_RINGPBX,
302 	{DATA_RI, DATA_S, DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
303 	{SIZE_RI, SIZE_S, SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
304 	{4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
305 
306 	{TONE_GERMAN_BUSY,
307 	{DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
308 	{SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
309 	{4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
310 
311 	{TONE_GERMAN_OLDBUSY,
312 	{DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
313 	{SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
314 	{1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
315 
316 	{TONE_AMERICAN_BUSY,
317 	{DATA_BU, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
318 	{SIZE_BU, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
319 	{4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
320 
321 	{TONE_GERMAN_HANGUP,
322 	{DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
323 	{SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
324 	{4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
325 
326 	{TONE_GERMAN_OLDHANGUP,
327 	{DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
328 	{SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
329 	{1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
330 
331 	{TONE_AMERICAN_HANGUP,
332 	{DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
333 	{SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
334 	{8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
335 
336 	{TONE_SPECIAL_INFO,
337 	{DATA_S1, DATA_S2, DATA_S3, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
338 	{SIZE_S1, SIZE_S2, SIZE_S3, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
339 	{2666, 2666, 2666, 8002, 0, 0, 0, 0, 0, 0} },
340 
341 	{TONE_GERMAN_GASSENBESETZT,
342 	{DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
343 	{SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
344 	{2000, 2000, 0, 0, 0, 0, 0, 0, 0, 0} },
345 
346 	{TONE_GERMAN_AUFSCHALTTON,
347 	{DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
348 	{SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
349 	{1000, 5000, 1000, 17000, 0, 0, 0, 0, 0, 0} },
350 
351 	{0,
352 	{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
353 	{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
354 	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
355 };
356 
357 /******************
358  * copy tone data *
359  ******************/
360 
361 /* an sk_buff is generated from the number of samples needed.
362  * the count will be changed and may begin from 0 each pattern period.
363  * the clue is to precalculate the pointers and legths to use only one
364  * memcpy per function call, or two memcpy if the tone sequence changes.
365  *
366  * pattern - the type of the pattern
367  * count - the sample from the beginning of the pattern (phase)
368  * len - the number of bytes
369  *
370  * return - the sk_buff with the sample
371  *
372  * if tones has finished (e.g. knocking tone), dsp->tones is turned off
373  */
374 void dsp_tone_copy(struct dsp *dsp, u8 *data, int len)
375 {
376 	int index, count, start, num;
377 	struct pattern *pat;
378 	struct dsp_tone *tone = &dsp->tone;
379 
380 	/* if we have no tone, we copy silence */
381 	if (!tone->tone) {
382 		memset(data, dsp_silence, len);
383 		return;
384 	}
385 
386 	/* process pattern */
387 	pat = (struct pattern *)tone->pattern;
388 		/* points to the current pattern */
389 	index = tone->index; /* gives current sequence index */
390 	count = tone->count; /* gives current sample */
391 
392 	/* copy sample */
393 	while (len) {
394 		/* find sample to start with */
395 		while (42) {
396 			/* warp arround */
397 			if (!pat->seq[index]) {
398 				count = 0;
399 				index = 0;
400 			}
401 			/* check if we are currently playing this tone */
402 			if (count < pat->seq[index])
403 				break;
404 			if (dsp_debug & DEBUG_DSP_TONE)
405 				printk(KERN_DEBUG "%s: reaching next sequence "
406 					"(index=%d)\n", __func__, index);
407 			count -= pat->seq[index];
408 			index++;
409 		}
410 		/* calculate start and number of samples */
411 		start = count % (*(pat->siz[index]));
412 		num = len;
413 		if (num+count > pat->seq[index])
414 			num = pat->seq[index] - count;
415 		if (num+start > (*(pat->siz[index])))
416 			num = (*(pat->siz[index])) - start;
417 		/* copy memory */
418 		memcpy(data, pat->data[index]+start, num);
419 		/* reduce length */
420 		data += num;
421 		count += num;
422 		len -= num;
423 	}
424 	tone->index = index;
425 	tone->count = count;
426 
427 	/* return sk_buff */
428 	return;
429 }
430 
431 
432 /*******************************
433  * send HW message to hfc card *
434  *******************************/
435 
436 static void
437 dsp_tone_hw_message(struct dsp *dsp, u8 *sample, int len)
438 {
439 	struct sk_buff *nskb;
440 
441 	/* unlocking is not required, because we don't expect a response */
442 	nskb = _alloc_mISDN_skb(PH_CONTROL_REQ,
443 		(len) ? HFC_SPL_LOOP_ON : HFC_SPL_LOOP_OFF, len, sample,
444 		GFP_ATOMIC);
445 	if (nskb) {
446 		if (dsp->ch.peer) {
447 			if (dsp->ch.recv(dsp->ch.peer, nskb))
448 				dev_kfree_skb(nskb);
449 		} else
450 			dev_kfree_skb(nskb);
451 	}
452 }
453 
454 
455 /*****************
456  * timer expires *
457  *****************/
458 void
459 dsp_tone_timeout(void *arg)
460 {
461 	struct dsp *dsp = arg;
462 	struct dsp_tone *tone = &dsp->tone;
463 	struct pattern *pat = (struct pattern *)tone->pattern;
464 	int index = tone->index;
465 
466 	if (!tone->tone)
467 		return;
468 
469 	index++;
470 	if (!pat->seq[index])
471 		index = 0;
472 	tone->index = index;
473 
474 	/* set next tone */
475 	if (pat->data[index] == DATA_S)
476 		dsp_tone_hw_message(dsp, NULL, 0);
477 	else
478 		dsp_tone_hw_message(dsp, pat->data[index], *(pat->siz[index]));
479 	/* set timer */
480 	init_timer(&tone->tl);
481 	tone->tl.expires = jiffies + (pat->seq[index] * HZ) / 8000;
482 	add_timer(&tone->tl);
483 }
484 
485 
486 /********************
487  * set/release tone *
488  ********************/
489 
490 /*
491  * tones are relaized by streaming or by special loop commands if supported
492  * by hardware. when hardware is used, the patterns will be controlled by
493  * timers.
494  */
495 int
496 dsp_tone(struct dsp *dsp, int tone)
497 {
498 	struct pattern *pat;
499 	int i;
500 	struct dsp_tone *tonet = &dsp->tone;
501 
502 	tonet->software = 0;
503 	tonet->hardware = 0;
504 
505 	/* we turn off the tone */
506 	if (!tone) {
507 		if (dsp->features.hfc_loops && timer_pending(&tonet->tl))
508 			del_timer(&tonet->tl);
509 		if (dsp->features.hfc_loops)
510 			dsp_tone_hw_message(dsp, NULL, 0);
511 		tonet->tone = 0;
512 		return 0;
513 	}
514 
515 	pat = NULL;
516 	i = 0;
517 	while (pattern[i].tone) {
518 		if (pattern[i].tone == tone) {
519 			pat = &pattern[i];
520 			break;
521 		}
522 		i++;
523 	}
524 	if (!pat) {
525 		printk(KERN_WARNING "dsp: given tone 0x%x is invalid\n", tone);
526 		return -EINVAL;
527 	}
528 	if (dsp_debug & DEBUG_DSP_TONE)
529 		printk(KERN_DEBUG "%s: now starting tone %d (index=%d)\n",
530 			__func__, tone, 0);
531 	tonet->tone = tone;
532 	tonet->pattern = pat;
533 	tonet->index = 0;
534 	tonet->count = 0;
535 
536 	if (dsp->features.hfc_loops) {
537 		tonet->hardware = 1;
538 		/* set first tone */
539 		dsp_tone_hw_message(dsp, pat->data[0], *(pat->siz[0]));
540 		/* set timer */
541 		if (timer_pending(&tonet->tl))
542 			del_timer(&tonet->tl);
543 		init_timer(&tonet->tl);
544 		tonet->tl.expires = jiffies + (pat->seq[0] * HZ) / 8000;
545 		add_timer(&tonet->tl);
546 	} else {
547 		tonet->software = 1;
548 	}
549 
550 	return 0;
551 }
552 
553 
554 
555 
556 
557