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