This source file includes following definitions.
- dsp_audio_generate_ulaw_samples
- dsp_tone_copy
- dsp_tone_hw_message
- dsp_tone_timeout
- dsp_tone
1
2
3
4
5
6
7
8
9
10
11 #include <linux/gfp.h>
12 #include <linux/mISDNif.h>
13 #include <linux/mISDNdsp.h>
14 #include "core.h"
15 #include "dsp.h"
16
17
18 #define DATA_S sample_silence
19 #define SIZE_S (&sizeof_silence)
20 #define DATA_GA sample_german_all
21 #define SIZE_GA (&sizeof_german_all)
22 #define DATA_GO sample_german_old
23 #define SIZE_GO (&sizeof_german_old)
24 #define DATA_DT sample_american_dialtone
25 #define SIZE_DT (&sizeof_american_dialtone)
26 #define DATA_RI sample_american_ringing
27 #define SIZE_RI (&sizeof_american_ringing)
28 #define DATA_BU sample_american_busy
29 #define SIZE_BU (&sizeof_american_busy)
30 #define DATA_S1 sample_special1
31 #define SIZE_S1 (&sizeof_special1)
32 #define DATA_S2 sample_special2
33 #define SIZE_S2 (&sizeof_special2)
34 #define DATA_S3 sample_special3
35 #define SIZE_S3 (&sizeof_special3)
36
37
38
39
40
41
42
43
44 static u8 sample_german_all[] = {
45 0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
46 0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
47 0xdc, 0xfc, 0x6c,
48 0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
49 0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
50 0xdc, 0xfc, 0x6c,
51 0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
52 0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
53 0xdc, 0xfc, 0x6c,
54 0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
55 0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
56 0xdc, 0xfc, 0x6c,
57 };
58 static u32 sizeof_german_all = sizeof(sample_german_all);
59
60 static u8 sample_german_old[] = {
61 0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
62 0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
63 0x8c,
64 0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
65 0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
66 0x8c,
67 0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
68 0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
69 0x8c,
70 0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
71 0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
72 0x8c,
73 };
74 static u32 sizeof_german_old = sizeof(sample_german_old);
75
76 static u8 sample_american_dialtone[] = {
77 0x2a, 0x18, 0x90, 0x6c, 0x4c, 0xbc, 0x4c, 0x6c,
78 0x10, 0x58, 0x32, 0xb9, 0x31, 0x2d, 0x8d, 0x0d,
79 0x8d, 0x2d, 0x31, 0x99, 0x0f, 0x28, 0x60, 0xf0,
80 0xd0, 0x50, 0xd0, 0x30, 0x60, 0x08, 0x8e, 0x67,
81 0x09, 0x19, 0x21, 0xe1, 0xd9, 0xb9, 0x29, 0x67,
82 0x83, 0x02, 0xce, 0xbe, 0xee, 0x1a, 0x1b, 0xef,
83 0xbf, 0xcf, 0x03, 0x82, 0x66, 0x28, 0xb8, 0xd8,
84 0xe0, 0x20, 0x18, 0x08, 0x66, 0x8f, 0x09, 0x61,
85 0x31, 0xd1, 0x51, 0xd1, 0xf1, 0x61, 0x29, 0x0e,
86 0x98, 0x30, 0x2c, 0x8c, 0x0c, 0x8c, 0x2c, 0x30,
87 0xb8, 0x33, 0x59, 0x11, 0x6d, 0x4d, 0xbd, 0x4d,
88 0x6d, 0x91, 0x19,
89 };
90 static u32 sizeof_american_dialtone = sizeof(sample_american_dialtone);
91
92 static u8 sample_american_ringing[] = {
93 0x2a, 0xe0, 0xac, 0x0c, 0xbc, 0x4c, 0x8c, 0x90,
94 0x48, 0xc7, 0xc1, 0xed, 0xcd, 0x4d, 0xcd, 0xed,
95 0xc1, 0xb7, 0x08, 0x30, 0xec, 0xcc, 0xcc, 0x8c,
96 0x10, 0x58, 0x1a, 0x99, 0x71, 0xed, 0x8d, 0x8d,
97 0x2d, 0x41, 0x89, 0x9e, 0x20, 0x70, 0x2c, 0xec,
98 0x2c, 0x70, 0x20, 0x86, 0x77, 0xe1, 0x31, 0x11,
99 0xd1, 0xf1, 0x81, 0x09, 0xa3, 0x56, 0x58, 0x00,
100 0x40, 0xc0, 0x60, 0x38, 0x46, 0x43, 0x57, 0x39,
101 0xd9, 0x59, 0x99, 0xc9, 0x77, 0x2f, 0x2e, 0xc6,
102 0xd6, 0x28, 0xd6, 0x36, 0x26, 0x2e, 0x8a, 0xa3,
103 0x43, 0x63, 0x4b, 0x4a, 0x62, 0x42, 0xa2, 0x8b,
104 0x2f, 0x27, 0x37, 0xd7, 0x29, 0xd7, 0xc7, 0x2f,
105 0x2e, 0x76, 0xc8, 0x98, 0x58, 0xd8, 0x38, 0x56,
106 0x42, 0x47, 0x39, 0x61, 0xc1, 0x41, 0x01, 0x59,
107 0x57, 0xa2, 0x08, 0x80, 0xf0, 0xd0, 0x10, 0x30,
108 0xe0, 0x76, 0x87, 0x21, 0x71, 0x2d, 0xed, 0x2d,
109 0x71, 0x21, 0x9f, 0x88, 0x40, 0x2c, 0x8c, 0x8c,
110 0xec, 0x70, 0x98, 0x1b, 0x59, 0x11, 0x8d, 0xcd,
111 0xcd, 0xed, 0x31, 0x09, 0xb6, 0xc0, 0xec, 0xcc,
112 0x4c, 0xcc, 0xec, 0xc0, 0xc6, 0x49, 0x91, 0x8d,
113 0x4d, 0xbd, 0x0d, 0xad, 0xe1,
114 };
115 static u32 sizeof_american_ringing = sizeof(sample_american_ringing);
116
117 static u8 sample_american_busy[] = {
118 0x2a, 0x00, 0x6c, 0x4c, 0x4c, 0x6c, 0xb0, 0x66,
119 0x99, 0x11, 0x6d, 0x8d, 0x2d, 0x41, 0xd7, 0x96,
120 0x60, 0xf0, 0x70, 0x40, 0x58, 0xf6, 0x53, 0x57,
121 0x09, 0x89, 0xd7, 0x5f, 0xe3, 0x2a, 0xe3, 0x5f,
122 0xd7, 0x89, 0x09, 0x57, 0x53, 0xf6, 0x58, 0x40,
123 0x70, 0xf0, 0x60, 0x96, 0xd7, 0x41, 0x2d, 0x8d,
124 0x6d, 0x11, 0x99, 0x66, 0xb0, 0x6c, 0x4c, 0x4c,
125 0x6c, 0x00, 0x2a, 0x01, 0x6d, 0x4d, 0x4d, 0x6d,
126 0xb1, 0x67, 0x98, 0x10, 0x6c, 0x8c, 0x2c, 0x40,
127 0xd6, 0x97, 0x61, 0xf1, 0x71, 0x41, 0x59, 0xf7,
128 0x52, 0x56, 0x08, 0x88, 0xd6, 0x5e, 0xe2, 0x2a,
129 0xe2, 0x5e, 0xd6, 0x88, 0x08, 0x56, 0x52, 0xf7,
130 0x59, 0x41, 0x71, 0xf1, 0x61, 0x97, 0xd6, 0x40,
131 0x2c, 0x8c, 0x6c, 0x10, 0x98, 0x67, 0xb1, 0x6d,
132 0x4d, 0x4d, 0x6d, 0x01,
133 };
134 static u32 sizeof_american_busy = sizeof(sample_american_busy);
135
136 static u8 sample_special1[] = {
137 0x2a, 0x2c, 0xbc, 0x6c, 0xd6, 0x71, 0xbd, 0x0d,
138 0xd9, 0x80, 0xcc, 0x4c, 0x40, 0x39, 0x0d, 0xbd,
139 0x11, 0x86, 0xec, 0xbc, 0xec, 0x0e, 0x51, 0xbd,
140 0x8d, 0x89, 0x30, 0x4c, 0xcc, 0xe0, 0xe1, 0xcd,
141 0x4d, 0x31, 0x88, 0x8c, 0xbc, 0x50, 0x0f, 0xed,
142 0xbd, 0xed, 0x87, 0x10, 0xbc, 0x0c, 0x38, 0x41,
143 0x4d, 0xcd, 0x81, 0xd8, 0x0c, 0xbc, 0x70, 0xd7,
144 0x6d, 0xbd, 0x2d,
145 };
146 static u32 sizeof_special1 = sizeof(sample_special1);
147
148 static u8 sample_special2[] = {
149 0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc,
150 0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d,
151 0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6,
152 0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0,
153 0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd,
154 0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc,
155 0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d,
156 0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6,
157 0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0,
158 0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd,
159 };
160 static u32 sizeof_special2 = sizeof(sample_special2);
161
162 static u8 sample_special3[] = {
163 0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1,
164 0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c,
165 0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc,
166 0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7,
167 0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd,
168 0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1,
169 0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c,
170 0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc,
171 0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7,
172 0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd,
173 };
174 static u32 sizeof_special3 = sizeof(sample_special3);
175
176 static u8 sample_silence[] = {
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 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
189 };
190 static u32 sizeof_silence = sizeof(sample_silence);
191
192 struct tones_samples {
193 u32 *len;
194 u8 *data;
195 };
196 static struct
197 tones_samples samples[] = {
198 {&sizeof_german_all, sample_german_all},
199 {&sizeof_german_old, sample_german_old},
200 {&sizeof_american_dialtone, sample_american_dialtone},
201 {&sizeof_american_ringing, sample_american_ringing},
202 {&sizeof_american_busy, sample_american_busy},
203 {&sizeof_special1, sample_special1},
204 {&sizeof_special2, sample_special2},
205 {&sizeof_special3, sample_special3},
206 {NULL, NULL},
207 };
208
209
210
211
212
213 void
214 dsp_audio_generate_ulaw_samples(void)
215 {
216 int i, j;
217
218 i = 0;
219 while (samples[i].len) {
220 j = 0;
221 while (j < (*samples[i].len)) {
222 samples[i].data[j] =
223 dsp_audio_alaw_to_ulaw[samples[i].data[j]];
224 j++;
225 }
226 i++;
227 }
228 }
229
230
231
232
233
234
235 static struct pattern {
236 int tone;
237 u8 *data[10];
238 u32 *siz[10];
239 u32 seq[10];
240 } pattern[] = {
241 {TONE_GERMAN_DIALTONE,
242 {DATA_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
243 {SIZE_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
244 {1900, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
245
246 {TONE_GERMAN_OLDDIALTONE,
247 {DATA_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
248 {SIZE_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
249 {1998, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
250
251 {TONE_AMERICAN_DIALTONE,
252 {DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
253 {SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
254 {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
255
256 {TONE_GERMAN_DIALPBX,
257 {DATA_GA, DATA_S, DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL,
258 NULL},
259 {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL,
260 NULL},
261 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
262
263 {TONE_GERMAN_OLDDIALPBX,
264 {DATA_GO, DATA_S, DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL,
265 NULL},
266 {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL,
267 NULL},
268 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
269
270 {TONE_AMERICAN_DIALPBX,
271 {DATA_DT, DATA_S, DATA_DT, DATA_S, DATA_DT, DATA_S, NULL, NULL, NULL,
272 NULL},
273 {SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, NULL, NULL, NULL,
274 NULL},
275 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
276
277 {TONE_GERMAN_RINGING,
278 {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
279 {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
280 {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
281
282 {TONE_GERMAN_OLDRINGING,
283 {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
284 {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
285 {8000, 40000, 0, 0, 0, 0, 0, 0, 0, 0} },
286
287 {TONE_AMERICAN_RINGING,
288 {DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
289 {SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
290 {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
291
292 {TONE_GERMAN_RINGPBX,
293 {DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
294 {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
295 {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
296
297 {TONE_GERMAN_OLDRINGPBX,
298 {DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
299 {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
300 {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
301
302 {TONE_AMERICAN_RINGPBX,
303 {DATA_RI, DATA_S, DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
304 {SIZE_RI, SIZE_S, SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
305 {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
306
307 {TONE_GERMAN_BUSY,
308 {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
309 {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
310 {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
311
312 {TONE_GERMAN_OLDBUSY,
313 {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
314 {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
315 {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
316
317 {TONE_AMERICAN_BUSY,
318 {DATA_BU, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
319 {SIZE_BU, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
320 {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
321
322 {TONE_GERMAN_HANGUP,
323 {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
324 {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
325 {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
326
327 {TONE_GERMAN_OLDHANGUP,
328 {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
329 {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
330 {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
331
332 {TONE_AMERICAN_HANGUP,
333 {DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
334 {SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
335 {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
336
337 {TONE_SPECIAL_INFO,
338 {DATA_S1, DATA_S2, DATA_S3, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
339 {SIZE_S1, SIZE_S2, SIZE_S3, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
340 {2666, 2666, 2666, 8002, 0, 0, 0, 0, 0, 0} },
341
342 {TONE_GERMAN_GASSENBESETZT,
343 {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
344 {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
345 {2000, 2000, 0, 0, 0, 0, 0, 0, 0, 0} },
346
347 {TONE_GERMAN_AUFSCHALTTON,
348 {DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
349 {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
350 {1000, 5000, 1000, 17000, 0, 0, 0, 0, 0, 0} },
351
352 {0,
353 {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
354 {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
355 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
356 };
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375 void dsp_tone_copy(struct dsp *dsp, u8 *data, int len)
376 {
377 int index, count, start, num;
378 struct pattern *pat;
379 struct dsp_tone *tone = &dsp->tone;
380
381
382 if (!tone->tone) {
383 memset(data, dsp_silence, len);
384 return;
385 }
386
387
388 pat = (struct pattern *)tone->pattern;
389
390 index = tone->index;
391 count = tone->count;
392
393
394 while (len) {
395
396 while (42) {
397
398 if (!pat->seq[index]) {
399 count = 0;
400 index = 0;
401 }
402
403 if (count < pat->seq[index])
404 break;
405 if (dsp_debug & DEBUG_DSP_TONE)
406 printk(KERN_DEBUG "%s: reaching next sequence "
407 "(index=%d)\n", __func__, index);
408 count -= pat->seq[index];
409 index++;
410 }
411
412 start = count % (*(pat->siz[index]));
413 num = len;
414 if (num + count > pat->seq[index])
415 num = pat->seq[index] - count;
416 if (num + start > (*(pat->siz[index])))
417 num = (*(pat->siz[index])) - start;
418
419 memcpy(data, pat->data[index] + start, num);
420
421 data += num;
422 count += num;
423 len -= num;
424 }
425 tone->index = index;
426 tone->count = count;
427
428
429 return;
430 }
431
432
433
434
435
436
437 static void
438 dsp_tone_hw_message(struct dsp *dsp, u8 *sample, int len)
439 {
440 struct sk_buff *nskb;
441
442
443 nskb = _alloc_mISDN_skb(PH_CONTROL_REQ,
444 (len) ? HFC_SPL_LOOP_ON : HFC_SPL_LOOP_OFF, len, sample,
445 GFP_ATOMIC);
446 if (nskb) {
447 if (dsp->ch.peer) {
448 if (dsp->ch.recv(dsp->ch.peer, nskb))
449 dev_kfree_skb(nskb);
450 } else
451 dev_kfree_skb(nskb);
452 }
453 }
454
455
456
457
458
459 void
460 dsp_tone_timeout(struct timer_list *t)
461 {
462 struct dsp *dsp = from_timer(dsp, t, tone.tl);
463 struct dsp_tone *tone = &dsp->tone;
464 struct pattern *pat = (struct pattern *)tone->pattern;
465 int index = tone->index;
466
467 if (!tone->tone)
468 return;
469
470 index++;
471 if (!pat->seq[index])
472 index = 0;
473 tone->index = index;
474
475
476 if (pat->data[index] == DATA_S)
477 dsp_tone_hw_message(dsp, NULL, 0);
478 else
479 dsp_tone_hw_message(dsp, pat->data[index], *(pat->siz[index]));
480
481 tone->tl.expires = jiffies + (pat->seq[index] * HZ) / 8000;
482 add_timer(&tone->tl);
483 }
484
485
486
487
488
489
490
491
492
493
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
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
539 dsp_tone_hw_message(dsp, pat->data[0], *(pat->siz[0]));
540
541 if (timer_pending(&tonet->tl))
542 del_timer(&tonet->tl);
543 tonet->tl.expires = jiffies + (pat->seq[0] * HZ) / 8000;
544 add_timer(&tonet->tl);
545 } else {
546 tonet->software = 1;
547 }
548
549 return 0;
550 }