Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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 
  This page was automatically generated by the LXR engine.