Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/isdn/mISDN/dsp_tones.c
15111 views
1
/*
2
* Audio support data for ISDN4Linux.
3
*
4
* Copyright Andreas Eversberg ([email protected])
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/gfp.h>
12
#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
44
static 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
};
58
static u32 sizeof_german_all = sizeof(sample_german_all);
59
60
static 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
};
74
static u32 sizeof_german_old = sizeof(sample_german_old);
75
76
static 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
};
90
static u32 sizeof_american_dialtone = sizeof(sample_american_dialtone);
91
92
static 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
};
115
static u32 sizeof_american_ringing = sizeof(sample_american_ringing);
116
117
static 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
};
134
static u32 sizeof_american_busy = sizeof(sample_american_busy);
135
136
static 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
};
146
static u32 sizeof_special1 = sizeof(sample_special1);
147
148
static 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
};
160
static u32 sizeof_special2 = sizeof(sample_special2);
161
162
static 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
};
174
static u32 sizeof_special3 = sizeof(sample_special3);
175
176
static 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
};
190
static u32 sizeof_silence = sizeof(sample_silence);
191
192
struct tones_samples {
193
u32 *len;
194
u8 *data;
195
};
196
static struct
197
tones_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
213
void
214
dsp_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
235
static struct pattern {
236
int tone;
237
u8 *data[10];
238
u32 *siz[10];
239
u32 seq[10];
240
} pattern[] = {
241
{TONE_GERMAN_DIALTONE,
242
{DATA_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
243
{SIZE_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
244
{1900, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
245
246
{TONE_GERMAN_OLDDIALTONE,
247
{DATA_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
248
{SIZE_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
249
{1998, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
250
251
{TONE_AMERICAN_DIALTONE,
252
{DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
253
{SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
254
{8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
255
256
{TONE_GERMAN_DIALPBX,
257
{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},
261
{2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
262
263
{TONE_GERMAN_OLDDIALPBX,
264
{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},
268
{2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
269
270
{TONE_AMERICAN_DIALPBX,
271
{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},
275
{2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
276
277
{TONE_GERMAN_RINGING,
278
{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},
280
{8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
281
282
{TONE_GERMAN_OLDRINGING,
283
{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},
285
{8000, 40000, 0, 0, 0, 0, 0, 0, 0, 0} },
286
287
{TONE_AMERICAN_RINGING,
288
{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},
290
{8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
291
292
{TONE_GERMAN_RINGPBX,
293
{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},
295
{4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
296
297
{TONE_GERMAN_OLDRINGPBX,
298
{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},
300
{4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
301
302
{TONE_AMERICAN_RINGPBX,
303
{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},
305
{4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
306
307
{TONE_GERMAN_BUSY,
308
{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},
310
{4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
311
312
{TONE_GERMAN_OLDBUSY,
313
{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},
315
{1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
316
317
{TONE_AMERICAN_BUSY,
318
{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},
320
{4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
321
322
{TONE_GERMAN_HANGUP,
323
{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},
325
{4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
326
327
{TONE_GERMAN_OLDHANGUP,
328
{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},
330
{1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
331
332
{TONE_AMERICAN_HANGUP,
333
{DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
334
{SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
335
{8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
336
337
{TONE_SPECIAL_INFO,
338
{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},
340
{2666, 2666, 2666, 8002, 0, 0, 0, 0, 0, 0} },
341
342
{TONE_GERMAN_GASSENBESETZT,
343
{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},
345
{2000, 2000, 0, 0, 0, 0, 0, 0, 0, 0} },
346
347
{TONE_GERMAN_AUFSCHALTTON,
348
{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},
350
{1000, 5000, 1000, 17000, 0, 0, 0, 0, 0, 0} },
351
352
{0,
353
{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
354
{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
355
{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
*/
375
void 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
/* wrap around */
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
437
static void
438
dsp_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,
444
(len) ? HFC_SPL_LOOP_ON : HFC_SPL_LOOP_OFF, len, sample,
445
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
*****************/
459
void
460
dsp_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)
477
dsp_tone_hw_message(dsp, NULL, 0);
478
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
*/
496
int
497
dsp_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) {
508
if (dsp->features.hfc_loops && timer_pending(&tonet->tl))
509
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
558
559