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