Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/isdn/mISDN/dsp_audio.c
15111 views
1
/*
2
* Audio support data for mISDN_dsp.
3
*
4
* Copyright 2002/2003 by Andreas Eversberg ([email protected])
5
* Rewritten by Peter
6
*
7
* This software may be used and distributed according to the terms
8
* of the GNU General Public License, incorporated herein by reference.
9
*
10
*/
11
12
#include <linux/delay.h>
13
#include <linux/mISDNif.h>
14
#include <linux/mISDNdsp.h>
15
#include "core.h"
16
#include "dsp.h"
17
18
/* ulaw[unsigned char] -> signed 16-bit */
19
s32 dsp_audio_ulaw_to_s32[256];
20
/* alaw[unsigned char] -> signed 16-bit */
21
s32 dsp_audio_alaw_to_s32[256];
22
23
s32 *dsp_audio_law_to_s32;
24
EXPORT_SYMBOL(dsp_audio_law_to_s32);
25
26
/* signed 16-bit -> law */
27
u8 dsp_audio_s16_to_law[65536];
28
EXPORT_SYMBOL(dsp_audio_s16_to_law);
29
30
/* alaw -> ulaw */
31
u8 dsp_audio_alaw_to_ulaw[256];
32
/* ulaw -> alaw */
33
static u8 dsp_audio_ulaw_to_alaw[256];
34
u8 dsp_silence;
35
36
37
/*****************************************************
38
* generate table for conversion of s16 to alaw/ulaw *
39
*****************************************************/
40
41
#define AMI_MASK 0x55
42
43
static inline unsigned char linear2alaw(short int linear)
44
{
45
int mask;
46
int seg;
47
int pcm_val;
48
static int seg_end[8] = {
49
0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF
50
};
51
52
pcm_val = linear;
53
if (pcm_val >= 0) {
54
/* Sign (7th) bit = 1 */
55
mask = AMI_MASK | 0x80;
56
} else {
57
/* Sign bit = 0 */
58
mask = AMI_MASK;
59
pcm_val = -pcm_val;
60
}
61
62
/* Convert the scaled magnitude to segment number. */
63
for (seg = 0; seg < 8; seg++) {
64
if (pcm_val <= seg_end[seg])
65
break;
66
}
67
/* Combine the sign, segment, and quantization bits. */
68
return ((seg << 4) |
69
((pcm_val >> ((seg) ? (seg + 3) : 4)) & 0x0F)) ^ mask;
70
}
71
72
73
static inline short int alaw2linear(unsigned char alaw)
74
{
75
int i;
76
int seg;
77
78
alaw ^= AMI_MASK;
79
i = ((alaw & 0x0F) << 4) + 8 /* rounding error */;
80
seg = (((int) alaw & 0x70) >> 4);
81
if (seg)
82
i = (i + 0x100) << (seg - 1);
83
return (short int) ((alaw & 0x80) ? i : -i);
84
}
85
86
static inline short int ulaw2linear(unsigned char ulaw)
87
{
88
short mu, e, f, y;
89
static short etab[] = {0, 132, 396, 924, 1980, 4092, 8316, 16764};
90
91
mu = 255 - ulaw;
92
e = (mu & 0x70) / 16;
93
f = mu & 0x0f;
94
y = f * (1 << (e + 3));
95
y += etab[e];
96
if (mu & 0x80)
97
y = -y;
98
return y;
99
}
100
101
#define BIAS 0x84 /*!< define the add-in bias for 16 bit samples */
102
103
static unsigned char linear2ulaw(short sample)
104
{
105
static int exp_lut[256] = {
106
0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
107
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
108
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
109
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
110
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
111
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
112
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
113
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
114
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
115
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
116
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
117
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
118
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
119
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
120
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
121
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7};
122
int sign, exponent, mantissa;
123
unsigned char ulawbyte;
124
125
/* Get the sample into sign-magnitude. */
126
sign = (sample >> 8) & 0x80; /* set aside the sign */
127
if (sign != 0)
128
sample = -sample; /* get magnitude */
129
130
/* Convert from 16 bit linear to ulaw. */
131
sample = sample + BIAS;
132
exponent = exp_lut[(sample >> 7) & 0xFF];
133
mantissa = (sample >> (exponent + 3)) & 0x0F;
134
ulawbyte = ~(sign | (exponent << 4) | mantissa);
135
136
return ulawbyte;
137
}
138
139
static int reverse_bits(int i)
140
{
141
int z, j;
142
z = 0;
143
144
for (j = 0; j < 8; j++) {
145
if ((i & (1 << j)) != 0)
146
z |= 1 << (7 - j);
147
}
148
return z;
149
}
150
151
152
void dsp_audio_generate_law_tables(void)
153
{
154
int i;
155
for (i = 0; i < 256; i++)
156
dsp_audio_alaw_to_s32[i] = alaw2linear(reverse_bits(i));
157
158
for (i = 0; i < 256; i++)
159
dsp_audio_ulaw_to_s32[i] = ulaw2linear(reverse_bits(i));
160
161
for (i = 0; i < 256; i++) {
162
dsp_audio_alaw_to_ulaw[i] =
163
linear2ulaw(dsp_audio_alaw_to_s32[i]);
164
dsp_audio_ulaw_to_alaw[i] =
165
linear2alaw(dsp_audio_ulaw_to_s32[i]);
166
}
167
}
168
169
void
170
dsp_audio_generate_s2law_table(void)
171
{
172
int i;
173
174
if (dsp_options & DSP_OPT_ULAW) {
175
/* generating ulaw-table */
176
for (i = -32768; i < 32768; i++) {
177
dsp_audio_s16_to_law[i & 0xffff] =
178
reverse_bits(linear2ulaw(i));
179
}
180
} else {
181
/* generating alaw-table */
182
for (i = -32768; i < 32768; i++) {
183
dsp_audio_s16_to_law[i & 0xffff] =
184
reverse_bits(linear2alaw(i));
185
}
186
}
187
}
188
189
190
/*
191
* the seven bit sample is the number of every second alaw-sample ordered by
192
* aplitude. 0x00 is negative, 0x7f is positive amplitude.
193
*/
194
u8 dsp_audio_seven2law[128];
195
u8 dsp_audio_law2seven[256];
196
197
/********************************************************************
198
* generate table for conversion law from/to 7-bit alaw-like sample *
199
********************************************************************/
200
201
void
202
dsp_audio_generate_seven(void)
203
{
204
int i, j, k;
205
u8 spl;
206
u8 sorted_alaw[256];
207
208
/* generate alaw table, sorted by the linear value */
209
for (i = 0; i < 256; i++) {
210
j = 0;
211
for (k = 0; k < 256; k++) {
212
if (dsp_audio_alaw_to_s32[k]
213
< dsp_audio_alaw_to_s32[i])
214
j++;
215
}
216
sorted_alaw[j] = i;
217
}
218
219
/* generate tabels */
220
for (i = 0; i < 256; i++) {
221
/* spl is the source: the law-sample (converted to alaw) */
222
spl = i;
223
if (dsp_options & DSP_OPT_ULAW)
224
spl = dsp_audio_ulaw_to_alaw[i];
225
/* find the 7-bit-sample */
226
for (j = 0; j < 256; j++) {
227
if (sorted_alaw[j] == spl)
228
break;
229
}
230
/* write 7-bit audio value */
231
dsp_audio_law2seven[i] = j >> 1;
232
}
233
for (i = 0; i < 128; i++) {
234
spl = sorted_alaw[i << 1];
235
if (dsp_options & DSP_OPT_ULAW)
236
spl = dsp_audio_alaw_to_ulaw[spl];
237
dsp_audio_seven2law[i] = spl;
238
}
239
}
240
241
242
/* mix 2*law -> law */
243
u8 dsp_audio_mix_law[65536];
244
245
/******************************************************
246
* generate mix table to mix two law samples into one *
247
******************************************************/
248
249
void
250
dsp_audio_generate_mix_table(void)
251
{
252
int i, j;
253
s32 sample;
254
255
i = 0;
256
while (i < 256) {
257
j = 0;
258
while (j < 256) {
259
sample = dsp_audio_law_to_s32[i];
260
sample += dsp_audio_law_to_s32[j];
261
if (sample > 32767)
262
sample = 32767;
263
if (sample < -32768)
264
sample = -32768;
265
dsp_audio_mix_law[(i<<8)|j] =
266
dsp_audio_s16_to_law[sample & 0xffff];
267
j++;
268
}
269
i++;
270
}
271
}
272
273
274
/*************************************
275
* generate different volume changes *
276
*************************************/
277
278
static u8 dsp_audio_reduce8[256];
279
static u8 dsp_audio_reduce7[256];
280
static u8 dsp_audio_reduce6[256];
281
static u8 dsp_audio_reduce5[256];
282
static u8 dsp_audio_reduce4[256];
283
static u8 dsp_audio_reduce3[256];
284
static u8 dsp_audio_reduce2[256];
285
static u8 dsp_audio_reduce1[256];
286
static u8 dsp_audio_increase1[256];
287
static u8 dsp_audio_increase2[256];
288
static u8 dsp_audio_increase3[256];
289
static u8 dsp_audio_increase4[256];
290
static u8 dsp_audio_increase5[256];
291
static u8 dsp_audio_increase6[256];
292
static u8 dsp_audio_increase7[256];
293
static u8 dsp_audio_increase8[256];
294
295
static u8 *dsp_audio_volume_change[16] = {
296
dsp_audio_reduce8,
297
dsp_audio_reduce7,
298
dsp_audio_reduce6,
299
dsp_audio_reduce5,
300
dsp_audio_reduce4,
301
dsp_audio_reduce3,
302
dsp_audio_reduce2,
303
dsp_audio_reduce1,
304
dsp_audio_increase1,
305
dsp_audio_increase2,
306
dsp_audio_increase3,
307
dsp_audio_increase4,
308
dsp_audio_increase5,
309
dsp_audio_increase6,
310
dsp_audio_increase7,
311
dsp_audio_increase8,
312
};
313
314
void
315
dsp_audio_generate_volume_changes(void)
316
{
317
register s32 sample;
318
int i;
319
int num[] = { 110, 125, 150, 175, 200, 300, 400, 500 };
320
int denum[] = { 100, 100, 100, 100, 100, 100, 100, 100 };
321
322
i = 0;
323
while (i < 256) {
324
dsp_audio_reduce8[i] = dsp_audio_s16_to_law[
325
(dsp_audio_law_to_s32[i] * denum[7] / num[7]) & 0xffff];
326
dsp_audio_reduce7[i] = dsp_audio_s16_to_law[
327
(dsp_audio_law_to_s32[i] * denum[6] / num[6]) & 0xffff];
328
dsp_audio_reduce6[i] = dsp_audio_s16_to_law[
329
(dsp_audio_law_to_s32[i] * denum[5] / num[5]) & 0xffff];
330
dsp_audio_reduce5[i] = dsp_audio_s16_to_law[
331
(dsp_audio_law_to_s32[i] * denum[4] / num[4]) & 0xffff];
332
dsp_audio_reduce4[i] = dsp_audio_s16_to_law[
333
(dsp_audio_law_to_s32[i] * denum[3] / num[3]) & 0xffff];
334
dsp_audio_reduce3[i] = dsp_audio_s16_to_law[
335
(dsp_audio_law_to_s32[i] * denum[2] / num[2]) & 0xffff];
336
dsp_audio_reduce2[i] = dsp_audio_s16_to_law[
337
(dsp_audio_law_to_s32[i] * denum[1] / num[1]) & 0xffff];
338
dsp_audio_reduce1[i] = dsp_audio_s16_to_law[
339
(dsp_audio_law_to_s32[i] * denum[0] / num[0]) & 0xffff];
340
sample = dsp_audio_law_to_s32[i] * num[0] / denum[0];
341
if (sample < -32768)
342
sample = -32768;
343
else if (sample > 32767)
344
sample = 32767;
345
dsp_audio_increase1[i] = dsp_audio_s16_to_law[sample & 0xffff];
346
sample = dsp_audio_law_to_s32[i] * num[1] / denum[1];
347
if (sample < -32768)
348
sample = -32768;
349
else if (sample > 32767)
350
sample = 32767;
351
dsp_audio_increase2[i] = dsp_audio_s16_to_law[sample & 0xffff];
352
sample = dsp_audio_law_to_s32[i] * num[2] / denum[2];
353
if (sample < -32768)
354
sample = -32768;
355
else if (sample > 32767)
356
sample = 32767;
357
dsp_audio_increase3[i] = dsp_audio_s16_to_law[sample & 0xffff];
358
sample = dsp_audio_law_to_s32[i] * num[3] / denum[3];
359
if (sample < -32768)
360
sample = -32768;
361
else if (sample > 32767)
362
sample = 32767;
363
dsp_audio_increase4[i] = dsp_audio_s16_to_law[sample & 0xffff];
364
sample = dsp_audio_law_to_s32[i] * num[4] / denum[4];
365
if (sample < -32768)
366
sample = -32768;
367
else if (sample > 32767)
368
sample = 32767;
369
dsp_audio_increase5[i] = dsp_audio_s16_to_law[sample & 0xffff];
370
sample = dsp_audio_law_to_s32[i] * num[5] / denum[5];
371
if (sample < -32768)
372
sample = -32768;
373
else if (sample > 32767)
374
sample = 32767;
375
dsp_audio_increase6[i] = dsp_audio_s16_to_law[sample & 0xffff];
376
sample = dsp_audio_law_to_s32[i] * num[6] / denum[6];
377
if (sample < -32768)
378
sample = -32768;
379
else if (sample > 32767)
380
sample = 32767;
381
dsp_audio_increase7[i] = dsp_audio_s16_to_law[sample & 0xffff];
382
sample = dsp_audio_law_to_s32[i] * num[7] / denum[7];
383
if (sample < -32768)
384
sample = -32768;
385
else if (sample > 32767)
386
sample = 32767;
387
dsp_audio_increase8[i] = dsp_audio_s16_to_law[sample & 0xffff];
388
389
i++;
390
}
391
}
392
393
394
/**************************************
395
* change the volume of the given skb *
396
**************************************/
397
398
/* this is a helper function for changing volume of skb. the range may be
399
* -8 to 8, which is a shift to the power of 2. 0 == no volume, 3 == volume*8
400
*/
401
void
402
dsp_change_volume(struct sk_buff *skb, int volume)
403
{
404
u8 *volume_change;
405
int i, ii;
406
u8 *p;
407
int shift;
408
409
if (volume == 0)
410
return;
411
412
/* get correct conversion table */
413
if (volume < 0) {
414
shift = volume + 8;
415
if (shift < 0)
416
shift = 0;
417
} else {
418
shift = volume + 7;
419
if (shift > 15)
420
shift = 15;
421
}
422
volume_change = dsp_audio_volume_change[shift];
423
i = 0;
424
ii = skb->len;
425
p = skb->data;
426
/* change volume */
427
while (i < ii) {
428
*p = volume_change[*p];
429
p++;
430
i++;
431
}
432
}
433
434
435