2 * Audio support data for ISDN4Linux.
4 * Copyright Andreas Eversberg (jolly@eversberg.eu)
6 * This software may be used and distributed according to the terms
7 * of the GNU General Public License, incorporated herein by reference.
11 #include <linux/mISDNif.h>
12 #include <linux/mISDNdsp.h>
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)
40 /* all tones are alaw encoded */
41 /* the last sample+1 is in phase with the first sample. the error is low */
43 static u8 sample_german_all
[] = {
44 0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
45 0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
47 0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
48 0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
50 0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
51 0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
53 0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
54 0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
57 static u32 sizeof_german_all
= sizeof(sample_german_all
);
59 static u8 sample_german_old
[] = {
60 0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
61 0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
63 0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
64 0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
66 0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
67 0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
69 0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
70 0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
73 static u32 sizeof_german_old
= sizeof(sample_german_old
);
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,
89 static u32 sizeof_american_dialtone
= sizeof(sample_american_dialtone
);
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,
114 static u32 sizeof_american_ringing
= sizeof(sample_american_ringing
);
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,
133 static u32 sizeof_american_busy
= sizeof(sample_american_busy
);
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,
145 static u32 sizeof_special1
= sizeof(sample_special1
);
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,
159 static u32 sizeof_special2
= sizeof(sample_special2
);
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,
173 static u32 sizeof_special3
= sizeof(sample_special3
);
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,
189 static u32 sizeof_silence
= sizeof(sample_silence
);
191 struct tones_samples
{
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
},
208 /***********************************
209 * generate ulaw from alaw samples *
210 ***********************************/
213 dsp_audio_generate_ulaw_samples(void)
218 while (samples
[i
].len
) {
220 while (j
< (*samples
[i
].len
)) {
222 dsp_audio_alaw_to_ulaw
[samples
[i
].data
[j
]];
230 /****************************
231 * tone sequence definition *
232 ****************************/
234 static struct 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} },
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} },
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} },
255 {TONE_GERMAN_DIALPBX
,
256 {DATA_GA
, DATA_S
, DATA_GA
, DATA_S
, DATA_GA
, DATA_S
, NULL
, NULL
, NULL
,
258 {SIZE_GA
, SIZE_S
, SIZE_GA
, SIZE_S
, SIZE_GA
, SIZE_S
, NULL
, NULL
, NULL
,
260 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
262 {TONE_GERMAN_OLDDIALPBX
,
263 {DATA_GO
, DATA_S
, DATA_GO
, DATA_S
, DATA_GO
, DATA_S
, NULL
, NULL
, NULL
,
265 {SIZE_GO
, SIZE_S
, SIZE_GO
, SIZE_S
, SIZE_GO
, SIZE_S
, NULL
, NULL
, NULL
,
267 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
269 {TONE_AMERICAN_DIALPBX
,
270 {DATA_DT
, DATA_S
, DATA_DT
, DATA_S
, DATA_DT
, DATA_S
, NULL
, NULL
, NULL
,
272 {SIZE_DT
, SIZE_S
, SIZE_DT
, SIZE_S
, SIZE_DT
, SIZE_S
, NULL
, NULL
, NULL
,
274 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
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} },
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} },
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} },
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} },
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} },
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} },
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} },
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} },
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} },
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} },
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} },
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} },
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} },
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} },
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} },
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} },
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.
366 * pattern - the type of the pattern
367 * count - the sample from the beginning of the pattern (phase)
368 * len - the number of bytes
370 * return - the sk_buff with the sample
372 * if tones has finished (e.g. knocking tone), dsp->tones is turned off
374 void dsp_tone_copy(struct dsp
*dsp
, u8
*data
, int len
)
376 int index
, count
, start
, num
;
378 struct dsp_tone
*tone
= &dsp
->tone
;
380 /* if we have no tone, we copy silence */
382 memset(data
, dsp_silence
, len
);
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 */
394 /* find sample to start with */
397 if (!pat
->seq
[index
]) {
401 /* check if we are currently playing this tone */
402 if (count
< pat
->seq
[index
])
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
];
410 /* calculate start and number of samples */
411 start
= count
% (*(pat
->siz
[index
]));
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
;
418 memcpy(data
, pat
->data
[index
]+start
, num
);
432 /*******************************
433 * send HW message to hfc card *
434 *******************************/
437 dsp_tone_hw_message(struct dsp
*dsp
, u8
*sample
, int len
)
439 struct sk_buff
*nskb
;
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
,
447 if (dsp
->ch
.recv(dsp
->ch
.peer
, nskb
))
459 dsp_tone_timeout(void *arg
)
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
;
470 if (!pat
->seq
[index
])
475 if (pat
->data
[index
] == DATA_S
)
476 dsp_tone_hw_message(dsp
, NULL
, 0);
478 dsp_tone_hw_message(dsp
, pat
->data
[index
], *(pat
->siz
[index
]));
480 init_timer(&tone
->tl
);
481 tone
->tl
.expires
= jiffies
+ (pat
->seq
[index
] * HZ
) / 8000;
482 add_timer(&tone
->tl
);
486 /********************
488 ********************/
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
496 dsp_tone(struct dsp
*dsp
, int tone
)
500 struct dsp_tone
*tonet
= &dsp
->tone
;
505 /* we turn off the 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);
517 while (pattern
[i
].tone
) {
518 if (pattern
[i
].tone
== tone
) {
525 printk(KERN_WARNING
"dsp: given tone 0x%x is invalid\n", tone
);
528 if (dsp_debug
& DEBUG_DSP_TONE
)
529 printk(KERN_DEBUG
"%s: now starting tone %d (index=%d)\n",
532 tonet
->pattern
= pat
;
536 if (dsp
->features
.hfc_loops
) {
539 dsp_tone_hw_message(dsp
, pat
->data
[0], *(pat
->siz
[0]));
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
);