blob: 7dbe54ed1debf77231cd7c6e6f91841e2367904d [file] [log] [blame]
Karsten Keil960366c2008-07-27 01:56:38 +02001/*
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
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090011#include <linux/gfp.h>
Karsten Keil960366c2008-07-27 01:56:38 +020012#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/* tones loops */
39/***************/
40
41/* all tones are alaw encoded */
42/* the last sample+1 is in phase with the first sample. the error is low */
43
44static 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};
58static u32 sizeof_german_all = sizeof(sample_german_all);
59
60static 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};
74static u32 sizeof_german_old = sizeof(sample_german_old);
75
76static 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};
90static u32 sizeof_american_dialtone = sizeof(sample_american_dialtone);
91
92static 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};
115static u32 sizeof_american_ringing = sizeof(sample_american_ringing);
116
117static 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};
134static u32 sizeof_american_busy = sizeof(sample_american_busy);
135
136static 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};
146static u32 sizeof_special1 = sizeof(sample_special1);
147
148static 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};
160static u32 sizeof_special2 = sizeof(sample_special2);
161
162static 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};
174static u32 sizeof_special3 = sizeof(sample_special3);
175
176static 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};
190static u32 sizeof_silence = sizeof(sample_silence);
191
192struct tones_samples {
193 u32 *len;
194 u8 *data;
195};
196static struct
197tones_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 * generate ulaw from alaw samples *
211 ***********************************/
212
213void
214dsp_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 * tone sequence definition *
233 ****************************/
234
Hannes Eder5b834352008-12-12 21:15:17 -0800235static struct pattern {
Karsten Keil960366c2008-07-27 01:56:38 +0200236 int tone;
237 u8 *data[10];
238 u32 *siz[10];
239 u32 seq[10];
240} pattern[] = {
241 {TONE_GERMAN_DIALTONE,
Hannes Ederbcf91742008-12-12 21:11:28 -0800242 {DATA_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
243 {SIZE_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
Karsten Keil960366c2008-07-27 01:56:38 +0200244 {1900, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
245
246 {TONE_GERMAN_OLDDIALTONE,
Hannes Ederbcf91742008-12-12 21:11:28 -0800247 {DATA_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
248 {SIZE_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
Karsten Keil960366c2008-07-27 01:56:38 +0200249 {1998, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
250
251 {TONE_AMERICAN_DIALTONE,
Hannes Ederbcf91742008-12-12 21:11:28 -0800252 {DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
253 {SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
Karsten Keil960366c2008-07-27 01:56:38 +0200254 {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
255
256 {TONE_GERMAN_DIALPBX,
Karsten Keileac74af2009-05-22 11:04:56 +0000257 {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},
Karsten Keil960366c2008-07-27 01:56:38 +0200261 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
262
263 {TONE_GERMAN_OLDDIALPBX,
Karsten Keileac74af2009-05-22 11:04:56 +0000264 {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},
Karsten Keil960366c2008-07-27 01:56:38 +0200268 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
269
270 {TONE_AMERICAN_DIALPBX,
Karsten Keileac74af2009-05-22 11:04:56 +0000271 {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},
Karsten Keil960366c2008-07-27 01:56:38 +0200275 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
276
277 {TONE_GERMAN_RINGING,
Hannes Ederbcf91742008-12-12 21:11:28 -0800278 {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},
Karsten Keil960366c2008-07-27 01:56:38 +0200280 {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
281
282 {TONE_GERMAN_OLDRINGING,
Hannes Ederbcf91742008-12-12 21:11:28 -0800283 {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},
Karsten Keil960366c2008-07-27 01:56:38 +0200285 {8000, 40000, 0, 0, 0, 0, 0, 0, 0, 0} },
286
287 {TONE_AMERICAN_RINGING,
Hannes Ederbcf91742008-12-12 21:11:28 -0800288 {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},
Karsten Keil960366c2008-07-27 01:56:38 +0200290 {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
291
292 {TONE_GERMAN_RINGPBX,
Hannes Ederbcf91742008-12-12 21:11:28 -0800293 {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},
Karsten Keil960366c2008-07-27 01:56:38 +0200295 {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
296
297 {TONE_GERMAN_OLDRINGPBX,
Hannes Ederbcf91742008-12-12 21:11:28 -0800298 {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},
Karsten Keil960366c2008-07-27 01:56:38 +0200300 {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
301
302 {TONE_AMERICAN_RINGPBX,
Hannes Ederbcf91742008-12-12 21:11:28 -0800303 {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},
Karsten Keil960366c2008-07-27 01:56:38 +0200305 {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
306
307 {TONE_GERMAN_BUSY,
Hannes Ederbcf91742008-12-12 21:11:28 -0800308 {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},
Karsten Keil960366c2008-07-27 01:56:38 +0200310 {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
311
312 {TONE_GERMAN_OLDBUSY,
Hannes Ederbcf91742008-12-12 21:11:28 -0800313 {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},
Karsten Keil960366c2008-07-27 01:56:38 +0200315 {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
316
317 {TONE_AMERICAN_BUSY,
Hannes Ederbcf91742008-12-12 21:11:28 -0800318 {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},
Karsten Keil960366c2008-07-27 01:56:38 +0200320 {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
321
322 {TONE_GERMAN_HANGUP,
Hannes Ederbcf91742008-12-12 21:11:28 -0800323 {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},
Karsten Keil960366c2008-07-27 01:56:38 +0200325 {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
326
327 {TONE_GERMAN_OLDHANGUP,
Hannes Ederbcf91742008-12-12 21:11:28 -0800328 {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},
Karsten Keil960366c2008-07-27 01:56:38 +0200330 {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
331
332 {TONE_AMERICAN_HANGUP,
Hannes Ederbcf91742008-12-12 21:11:28 -0800333 {DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
334 {SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
Karsten Keil960366c2008-07-27 01:56:38 +0200335 {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
336
337 {TONE_SPECIAL_INFO,
Hannes Ederbcf91742008-12-12 21:11:28 -0800338 {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},
Karsten Keil960366c2008-07-27 01:56:38 +0200340 {2666, 2666, 2666, 8002, 0, 0, 0, 0, 0, 0} },
341
342 {TONE_GERMAN_GASSENBESETZT,
Hannes Ederbcf91742008-12-12 21:11:28 -0800343 {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},
Karsten Keil960366c2008-07-27 01:56:38 +0200345 {2000, 2000, 0, 0, 0, 0, 0, 0, 0, 0} },
346
347 {TONE_GERMAN_AUFSCHALTTON,
Hannes Ederbcf91742008-12-12 21:11:28 -0800348 {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},
Karsten Keil960366c2008-07-27 01:56:38 +0200350 {1000, 5000, 1000, 17000, 0, 0, 0, 0, 0, 0} },
351
352 {0,
Hannes Ederbcf91742008-12-12 21:11:28 -0800353 {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
354 {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
Karsten Keil960366c2008-07-27 01:56:38 +0200355 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
356};
357
358/******************
359 * copy tone data *
360 ******************/
361
362/* an sk_buff is generated from the number of samples needed.
363 * the count will be changed and may begin from 0 each pattern period.
364 * the clue is to precalculate the pointers and legths to use only one
365 * memcpy per function call, or two memcpy if the tone sequence changes.
366 *
367 * pattern - the type of the pattern
368 * count - the sample from the beginning of the pattern (phase)
369 * len - the number of bytes
370 *
371 * return - the sk_buff with the sample
372 *
373 * if tones has finished (e.g. knocking tone), dsp->tones is turned off
374 */
375void 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 /* if we have no tone, we copy silence */
382 if (!tone->tone) {
383 memset(data, dsp_silence, len);
384 return;
385 }
386
387 /* process pattern */
388 pat = (struct pattern *)tone->pattern;
389 /* points to the current pattern */
390 index = tone->index; /* gives current sequence index */
391 count = tone->count; /* gives current sample */
392
393 /* copy sample */
394 while (len) {
395 /* find sample to start with */
396 while (42) {
397 /* warp arround */
398 if (!pat->seq[index]) {
399 count = 0;
400 index = 0;
401 }
402 /* check if we are currently playing this tone */
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 /* calculate start and number of samples */
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 /* copy memory */
419 memcpy(data, pat->data[index]+start, num);
420 /* reduce length */
421 data += num;
422 count += num;
423 len -= num;
424 }
425 tone->index = index;
426 tone->count = count;
427
428 /* return sk_buff */
429 return;
430}
431
432
433/*******************************
434 * send HW message to hfc card *
435 *******************************/
436
437static void
438dsp_tone_hw_message(struct dsp *dsp, u8 *sample, int len)
439{
440 struct sk_buff *nskb;
441
442 /* unlocking is not required, because we don't expect a response */
443 nskb = _alloc_mISDN_skb(PH_CONTROL_REQ,
Karsten Keileac74af2009-05-22 11:04:56 +0000444 (len) ? HFC_SPL_LOOP_ON : HFC_SPL_LOOP_OFF, len, sample,
Karsten Keil960366c2008-07-27 01:56:38 +0200445 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 * timer expires *
458 *****************/
459void
460dsp_tone_timeout(void *arg)
461{
462 struct dsp *dsp = arg;
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 /* set next tone */
476 if (pat->data[index] == DATA_S)
Hannes Ederbcf91742008-12-12 21:11:28 -0800477 dsp_tone_hw_message(dsp, NULL, 0);
Karsten Keil960366c2008-07-27 01:56:38 +0200478 else
479 dsp_tone_hw_message(dsp, pat->data[index], *(pat->siz[index]));
480 /* set timer */
481 init_timer(&tone->tl);
482 tone->tl.expires = jiffies + (pat->seq[index] * HZ) / 8000;
483 add_timer(&tone->tl);
484}
485
486
487/********************
488 * set/release tone *
489 ********************/
490
491/*
492 * tones are relaized by streaming or by special loop commands if supported
493 * by hardware. when hardware is used, the patterns will be controlled by
494 * timers.
495 */
496int
497dsp_tone(struct dsp *dsp, int tone)
498{
499 struct pattern *pat;
500 int i;
501 struct dsp_tone *tonet = &dsp->tone;
502
503 tonet->software = 0;
504 tonet->hardware = 0;
505
506 /* we turn off the tone */
507 if (!tone) {
Karsten Keileac74af2009-05-22 11:04:56 +0000508 if (dsp->features.hfc_loops && timer_pending(&tonet->tl))
Karsten Keil960366c2008-07-27 01:56:38 +0200509 del_timer(&tonet->tl);
510 if (dsp->features.hfc_loops)
511 dsp_tone_hw_message(dsp, NULL, 0);
512 tonet->tone = 0;
513 return 0;
514 }
515
516 pat = NULL;
517 i = 0;
518 while (pattern[i].tone) {
519 if (pattern[i].tone == tone) {
520 pat = &pattern[i];
521 break;
522 }
523 i++;
524 }
525 if (!pat) {
526 printk(KERN_WARNING "dsp: given tone 0x%x is invalid\n", tone);
527 return -EINVAL;
528 }
529 if (dsp_debug & DEBUG_DSP_TONE)
530 printk(KERN_DEBUG "%s: now starting tone %d (index=%d)\n",
531 __func__, tone, 0);
532 tonet->tone = tone;
533 tonet->pattern = pat;
534 tonet->index = 0;
535 tonet->count = 0;
536
537 if (dsp->features.hfc_loops) {
538 tonet->hardware = 1;
539 /* set first tone */
540 dsp_tone_hw_message(dsp, pat->data[0], *(pat->siz[0]));
541 /* set timer */
542 if (timer_pending(&tonet->tl))
543 del_timer(&tonet->tl);
544 init_timer(&tonet->tl);
545 tonet->tl.expires = jiffies + (pat->seq[0] * HZ) / 8000;
546 add_timer(&tonet->tl);
547 } else {
548 tonet->software = 1;
549 }
550
551 return 0;
552}
553
554
555
556
557