1
2
3
4
5
6
7
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
38
39
40
41
42
43static 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};
57static u32 sizeof_german_all = sizeof(sample_german_all);
58
59static 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};
73static u32 sizeof_german_old = sizeof(sample_german_old);
74
75static 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};
89static u32 sizeof_american_dialtone = sizeof(sample_american_dialtone);
90
91static 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};
114static u32 sizeof_american_ringing = sizeof(sample_american_ringing);
115
116static 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};
133static u32 sizeof_american_busy = sizeof(sample_american_busy);
134
135static 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};
145static u32 sizeof_special1 = sizeof(sample_special1);
146
147static 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};
159static u32 sizeof_special2 = sizeof(sample_special2);
160
161static 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};
173static u32 sizeof_special3 = sizeof(sample_special3);
174
175static 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};
189static u32 sizeof_silence = sizeof(sample_silence);
190
191struct tones_samples {
192 u32 *len;
193 u8 *data;
194};
195static struct
196tones_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
210
211
212void
213dsp_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
232
233
234static 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
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374void 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
381 if (!tone->tone) {
382 memset(data, dsp_silence, len);
383 return;
384 }
385
386
387 pat = (struct pattern *)tone->pattern;
388
389 index = tone->index;
390 count = tone->count;
391
392
393 while (len) {
394
395 while (42) {
396
397 if (!pat->seq[index]) {
398 count = 0;
399 index = 0;
400 }
401
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
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
418 memcpy(data, pat->data[index]+start, num);
419
420 data += num;
421 count += num;
422 len -= num;
423 }
424 tone->index = index;
425 tone->count = count;
426
427
428 return;
429}
430
431
432
433
434
435
436static void
437dsp_tone_hw_message(struct dsp *dsp, u8 *sample, int len)
438{
439 struct sk_buff *nskb;
440
441
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
457
458void
459dsp_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
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
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
488
489
490
491
492
493
494
495int
496dsp_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 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