Merge branch 'for-np' of git://git.wormnet.eu/alex/ts78xx into orion/master
[linux-2.6] / drivers / isdn / mISDN / dsp_tones.c
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, NULL},
257         {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL},
258         {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
259
260         {TONE_GERMAN_OLDDIALPBX,
261         {DATA_GO, DATA_S, DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL},
262         {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL},
263         {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
264
265         {TONE_AMERICAN_DIALPBX,
266         {DATA_DT, DATA_S, DATA_DT, DATA_S, DATA_DT, DATA_S, NULL, NULL, NULL, NULL},
267         {SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, NULL, NULL, NULL, NULL},
268         {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
269
270         {TONE_GERMAN_RINGING,
271         {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
272         {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
273         {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
274
275         {TONE_GERMAN_OLDRINGING,
276         {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
277         {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
278         {8000, 40000, 0, 0, 0, 0, 0, 0, 0, 0} },
279
280         {TONE_AMERICAN_RINGING,
281         {DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
282         {SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
283         {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
284
285         {TONE_GERMAN_RINGPBX,
286         {DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
287         {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
288         {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
289
290         {TONE_GERMAN_OLDRINGPBX,
291         {DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
292         {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
293         {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
294
295         {TONE_AMERICAN_RINGPBX,
296         {DATA_RI, DATA_S, DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
297         {SIZE_RI, SIZE_S, SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
298         {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
299
300         {TONE_GERMAN_BUSY,
301         {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
302         {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
303         {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
304
305         {TONE_GERMAN_OLDBUSY,
306         {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
307         {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
308         {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
309
310         {TONE_AMERICAN_BUSY,
311         {DATA_BU, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
312         {SIZE_BU, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
313         {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
314
315         {TONE_GERMAN_HANGUP,
316         {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
317         {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
318         {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
319
320         {TONE_GERMAN_OLDHANGUP,
321         {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
322         {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
323         {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
324
325         {TONE_AMERICAN_HANGUP,
326         {DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
327         {SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
328         {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
329
330         {TONE_SPECIAL_INFO,
331         {DATA_S1, DATA_S2, DATA_S3, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
332         {SIZE_S1, SIZE_S2, SIZE_S3, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
333         {2666, 2666, 2666, 8002, 0, 0, 0, 0, 0, 0} },
334
335         {TONE_GERMAN_GASSENBESETZT,
336         {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
337         {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
338         {2000, 2000, 0, 0, 0, 0, 0, 0, 0, 0} },
339
340         {TONE_GERMAN_AUFSCHALTTON,
341         {DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
342         {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
343         {1000, 5000, 1000, 17000, 0, 0, 0, 0, 0, 0} },
344
345         {0,
346         {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
347         {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
348         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
349 };
350
351 /******************
352  * copy tone data *
353  ******************/
354
355 /* an sk_buff is generated from the number of samples needed.
356  * the count will be changed and may begin from 0 each pattern period.
357  * the clue is to precalculate the pointers and legths to use only one
358  * memcpy per function call, or two memcpy if the tone sequence changes.
359  *
360  * pattern - the type of the pattern
361  * count - the sample from the beginning of the pattern (phase)
362  * len - the number of bytes
363  *
364  * return - the sk_buff with the sample
365  *
366  * if tones has finished (e.g. knocking tone), dsp->tones is turned off
367  */
368 void dsp_tone_copy(struct dsp *dsp, u8 *data, int len)
369 {
370         int index, count, start, num;
371         struct pattern *pat;
372         struct dsp_tone *tone = &dsp->tone;
373
374         /* if we have no tone, we copy silence */
375         if (!tone->tone) {
376                 memset(data, dsp_silence, len);
377                 return;
378         }
379
380         /* process pattern */
381         pat = (struct pattern *)tone->pattern;
382                 /* points to the current pattern */
383         index = tone->index; /* gives current sequence index */
384         count = tone->count; /* gives current sample */
385
386         /* copy sample */
387         while (len) {
388                 /* find sample to start with */
389                 while (42) {
390                         /* warp arround */
391                         if (!pat->seq[index]) {
392                                 count = 0;
393                                 index = 0;
394                         }
395                         /* check if we are currently playing this tone */
396                         if (count < pat->seq[index])
397                                 break;
398                         if (dsp_debug & DEBUG_DSP_TONE)
399                                 printk(KERN_DEBUG "%s: reaching next sequence "
400                                         "(index=%d)\n", __func__, index);
401                         count -= pat->seq[index];
402                         index++;
403                 }
404                 /* calculate start and number of samples */
405                 start = count % (*(pat->siz[index]));
406                 num = len;
407                 if (num+count > pat->seq[index])
408                         num = pat->seq[index] - count;
409                 if (num+start > (*(pat->siz[index])))
410                         num = (*(pat->siz[index])) - start;
411                 /* copy memory */
412                 memcpy(data, pat->data[index]+start, num);
413                 /* reduce length */
414                 data += num;
415                 count += num;
416                 len -= num;
417         }
418         tone->index = index;
419         tone->count = count;
420
421         /* return sk_buff */
422         return;
423 }
424
425
426 /*******************************
427  * send HW message to hfc card *
428  *******************************/
429
430 static void
431 dsp_tone_hw_message(struct dsp *dsp, u8 *sample, int len)
432 {
433         struct sk_buff *nskb;
434
435         /* unlocking is not required, because we don't expect a response */
436         nskb = _alloc_mISDN_skb(PH_CONTROL_REQ,
437                 (len)?HFC_SPL_LOOP_ON:HFC_SPL_LOOP_OFF, len, sample,
438                 GFP_ATOMIC);
439         if (nskb) {
440                 if (dsp->ch.peer) {
441                         if (dsp->ch.recv(dsp->ch.peer, nskb))
442                                 dev_kfree_skb(nskb);
443                 } else
444                         dev_kfree_skb(nskb);
445         }
446 }
447
448
449 /*****************
450  * timer expires *
451  *****************/
452 void
453 dsp_tone_timeout(void *arg)
454 {
455         struct dsp *dsp = arg;
456         struct dsp_tone *tone = &dsp->tone;
457         struct pattern *pat = (struct pattern *)tone->pattern;
458         int index = tone->index;
459
460         if (!tone->tone)
461                 return;
462
463         index++;
464         if (!pat->seq[index])
465                 index = 0;
466         tone->index = index;
467
468         /* set next tone */
469         if (pat->data[index] == DATA_S)
470                 dsp_tone_hw_message(dsp, NULL, 0);
471         else
472                 dsp_tone_hw_message(dsp, pat->data[index], *(pat->siz[index]));
473         /* set timer */
474         init_timer(&tone->tl);
475         tone->tl.expires = jiffies + (pat->seq[index] * HZ) / 8000;
476         add_timer(&tone->tl);
477 }
478
479
480 /********************
481  * set/release tone *
482  ********************/
483
484 /*
485  * tones are relaized by streaming or by special loop commands if supported
486  * by hardware. when hardware is used, the patterns will be controlled by
487  * timers.
488  */
489 int
490 dsp_tone(struct dsp *dsp, int tone)
491 {
492         struct pattern *pat;
493         int i;
494         struct dsp_tone *tonet = &dsp->tone;
495
496         tonet->software = 0;
497         tonet->hardware = 0;
498
499         /* we turn off the tone */
500         if (!tone) {
501                 if (dsp->features.hfc_loops)
502                 if (timer_pending(&tonet->tl))
503                         del_timer(&tonet->tl);
504                 if (dsp->features.hfc_loops)
505                         dsp_tone_hw_message(dsp, NULL, 0);
506                 tonet->tone = 0;
507                 return 0;
508         }
509
510         pat = NULL;
511         i = 0;
512         while (pattern[i].tone) {
513                 if (pattern[i].tone == tone) {
514                         pat = &pattern[i];
515                         break;
516                 }
517                 i++;
518         }
519         if (!pat) {
520                 printk(KERN_WARNING "dsp: given tone 0x%x is invalid\n", tone);
521                 return -EINVAL;
522         }
523         if (dsp_debug & DEBUG_DSP_TONE)
524                 printk(KERN_DEBUG "%s: now starting tone %d (index=%d)\n",
525                         __func__, tone, 0);
526         tonet->tone = tone;
527         tonet->pattern = pat;
528         tonet->index = 0;
529         tonet->count = 0;
530
531         if (dsp->features.hfc_loops) {
532                 tonet->hardware = 1;
533                 /* set first tone */
534                 dsp_tone_hw_message(dsp, pat->data[0], *(pat->siz[0]));
535                 /* set timer */
536                 if (timer_pending(&tonet->tl))
537                         del_timer(&tonet->tl);
538                 init_timer(&tonet->tl);
539                 tonet->tl.expires = jiffies + (pat->seq[0] * HZ) / 8000;
540                 add_timer(&tonet->tl);
541         } else {
542                 tonet->software = 1;
543         }
544
545         return 0;
546 }
547
548
549
550
551