WIP FPC-III support
[linux/fpc-iii.git] / drivers / isdn / mISDN / dsp_audio.c
blobbbef98e7a16efb438ef38856d8e043397f674804
1 /*
2 * Audio support data for mISDN_dsp.
4 * Copyright 2002/2003 by Andreas Eversberg (jolly@eversberg.eu)
5 * Rewritten by Peter
7 * This software may be used and distributed according to the terms
8 * of the GNU General Public License, incorporated herein by reference.
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"
20 /* ulaw[unsigned char] -> signed 16-bit */
21 s32 dsp_audio_ulaw_to_s32[256];
22 /* alaw[unsigned char] -> signed 16-bit */
23 s32 dsp_audio_alaw_to_s32[256];
25 s32 *dsp_audio_law_to_s32;
26 EXPORT_SYMBOL(dsp_audio_law_to_s32);
28 /* signed 16-bit -> law */
29 u8 dsp_audio_s16_to_law[65536];
30 EXPORT_SYMBOL(dsp_audio_s16_to_law);
32 /* alaw -> ulaw */
33 u8 dsp_audio_alaw_to_ulaw[256];
34 /* ulaw -> alaw */
35 static u8 dsp_audio_ulaw_to_alaw[256];
36 u8 dsp_silence;
39 /*****************************************************
40 * generate table for conversion of s16 to alaw/ulaw *
41 *****************************************************/
43 #define AMI_MASK 0x55
45 static inline unsigned char linear2alaw(short int linear)
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
54 pcm_val = linear;
55 if (pcm_val >= 0) {
56 /* Sign (7th) bit = 1 */
57 mask = AMI_MASK | 0x80;
58 } else {
59 /* Sign bit = 0 */
60 mask = AMI_MASK;
61 pcm_val = -pcm_val;
64 /* Convert the scaled magnitude to segment number. */
65 for (seg = 0; seg < 8; seg++) {
66 if (pcm_val <= seg_end[seg])
67 break;
69 /* Combine the sign, segment, and quantization bits. */
70 return ((seg << 4) |
71 ((pcm_val >> ((seg) ? (seg + 3) : 4)) & 0x0F)) ^ mask;
75 static inline short int alaw2linear(unsigned char alaw)
77 int i;
78 int seg;
80 alaw ^= AMI_MASK;
81 i = ((alaw & 0x0F) << 4) + 8 /* rounding error */;
82 seg = (((int) alaw & 0x70) >> 4);
83 if (seg)
84 i = (i + 0x100) << (seg - 1);
85 return (short int) ((alaw & 0x80) ? i : -i);
88 static inline short int ulaw2linear(unsigned char ulaw)
90 short mu, e, f, y;
91 static short etab[] = {0, 132, 396, 924, 1980, 4092, 8316, 16764};
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;
103 #define BIAS 0x84 /*!< define the add-in bias for 16 bit samples */
105 static unsigned char linear2ulaw(short sample)
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;
127 /* Get the sample into sign-magnitude. */
128 sign = (sample >> 8) & 0x80; /* set aside the sign */
129 if (sign != 0)
130 sample = -sample; /* get magnitude */
132 /* Convert from 16 bit linear to ulaw. */
133 sample = sample + BIAS;
134 exponent = exp_lut[(sample >> 7) & 0xFF];
135 mantissa = (sample >> (exponent + 3)) & 0x0F;
136 ulawbyte = ~(sign | (exponent << 4) | mantissa);
138 return ulawbyte;
141 void dsp_audio_generate_law_tables(void)
143 int i;
144 for (i = 0; i < 256; i++)
145 dsp_audio_alaw_to_s32[i] = alaw2linear(bitrev8((u8)i));
147 for (i = 0; i < 256; i++)
148 dsp_audio_ulaw_to_s32[i] = ulaw2linear(bitrev8((u8)i));
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]);
158 void
159 dsp_audio_generate_s2law_table(void)
161 int i;
163 if (dsp_options & DSP_OPT_ULAW) {
164 /* generating ulaw-table */
165 for (i = -32768; i < 32768; i++) {
166 dsp_audio_s16_to_law[i & 0xffff] =
167 bitrev8(linear2ulaw(i));
169 } else {
170 /* generating alaw-table */
171 for (i = -32768; i < 32768; i++) {
172 dsp_audio_s16_to_law[i & 0xffff] =
173 bitrev8(linear2alaw(i));
180 * the seven bit sample is the number of every second alaw-sample ordered by
181 * aplitude. 0x00 is negative, 0x7f is positive amplitude.
183 u8 dsp_audio_seven2law[128];
184 u8 dsp_audio_law2seven[256];
186 /********************************************************************
187 * generate table for conversion law from/to 7-bit alaw-like sample *
188 ********************************************************************/
190 void
191 dsp_audio_generate_seven(void)
193 int i, j, k;
194 u8 spl;
195 u8 sorted_alaw[256];
197 /* generate alaw table, sorted by the linear value */
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++;
205 sorted_alaw[j] = i;
208 /* generate tabels */
209 for (i = 0; i < 256; i++) {
210 /* spl is the source: the law-sample (converted to alaw) */
211 spl = i;
212 if (dsp_options & DSP_OPT_ULAW)
213 spl = dsp_audio_ulaw_to_alaw[i];
214 /* find the 7-bit-sample */
215 for (j = 0; j < 256; j++) {
216 if (sorted_alaw[j] == spl)
217 break;
219 /* write 7-bit audio value */
220 dsp_audio_law2seven[i] = j >> 1;
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;
231 /* mix 2*law -> law */
232 u8 dsp_audio_mix_law[65536];
234 /******************************************************
235 * generate mix table to mix two law samples into one *
236 ******************************************************/
238 void
239 dsp_audio_generate_mix_table(void)
241 int i, j;
242 s32 sample;
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++;
258 i++;
263 /*************************************
264 * generate different volume changes *
265 *************************************/
267 static u8 dsp_audio_reduce8[256];
268 static u8 dsp_audio_reduce7[256];
269 static u8 dsp_audio_reduce6[256];
270 static u8 dsp_audio_reduce5[256];
271 static u8 dsp_audio_reduce4[256];
272 static u8 dsp_audio_reduce3[256];
273 static u8 dsp_audio_reduce2[256];
274 static u8 dsp_audio_reduce1[256];
275 static u8 dsp_audio_increase1[256];
276 static u8 dsp_audio_increase2[256];
277 static u8 dsp_audio_increase3[256];
278 static u8 dsp_audio_increase4[256];
279 static u8 dsp_audio_increase5[256];
280 static u8 dsp_audio_increase6[256];
281 static u8 dsp_audio_increase7[256];
282 static u8 dsp_audio_increase8[256];
284 static 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,
303 void
304 dsp_audio_generate_volume_changes(void)
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 };
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];
378 i++;
383 /**************************************
384 * change the volume of the given skb *
385 **************************************/
387 /* this is a helper function for changing volume of skb. the range may be
388 * -8 to 8, which is a shift to the power of 2. 0 == no volume, 3 == volume*8
390 void
391 dsp_change_volume(struct sk_buff *skb, int volume)
393 u8 *volume_change;
394 int i, ii;
395 u8 *p;
396 int shift;
398 if (volume == 0)
399 return;
401 /* get correct conversion table */
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;
411 volume_change = dsp_audio_volume_change[shift];
412 i = 0;
413 ii = skb->len;
414 p = skb->data;
415 /* change volume */
416 while (i < ii) {
417 *p = volume_change[*p];
418 p++;
419 i++;