xref: /linux/drivers/isdn/mISDN/dsp_audio.c (revision 8e07e0e3964ca4e23ce7b68e2096fe660a888942)
1 /*
2  * Audio support data for mISDN_dsp.
3  *
4  * Copyright 2002/2003 by Andreas Eversberg (jolly@eversberg.eu)
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 <linux/export.h>
16 #include <linux/bitrev.h>
17 #include "core.h"
18 #include "dsp.h"
19 
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];
24 
25 s32 *dsp_audio_law_to_s32;
26 EXPORT_SYMBOL(dsp_audio_law_to_s32);
27 
28 /* signed 16-bit -> law */
29 u8 dsp_audio_s16_to_law[65536];
30 EXPORT_SYMBOL(dsp_audio_s16_to_law);
31 
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;
37 
38 
39 /*****************************************************
40  * generate table for conversion of s16 to alaw/ulaw *
41  *****************************************************/
42 
43 #define AMI_MASK 0x55
44 
45 static 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 		/* Sign (7th) bit = 1 */
57 		mask = AMI_MASK | 0x80;
58 	} else {
59 		/* Sign bit = 0 */
60 		mask = AMI_MASK;
61 		pcm_val = -pcm_val;
62 	}
63 
64 	/* Convert the scaled magnitude to segment number. */
65 	for (seg = 0; seg < 8; seg++) {
66 		if (pcm_val <= seg_end[seg])
67 			break;
68 	}
69 	/* Combine the sign, segment, and quantization bits. */
70 	return  ((seg << 4) |
71 		 ((pcm_val >> ((seg)  ?  (seg + 3)  :  4)) & 0x0F)) ^ mask;
72 }
73 
74 
75 static 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 /* 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);
86 }
87 
88 static 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   /*!< define the add-in bias for 16 bit samples */
104 
105 static 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 	/* Get the sample into sign-magnitude. */
128 	sign = (sample >> 8) & 0x80;	  /* set aside the sign */
129 	if (sign != 0)
130 		sample = -sample;	      /* get magnitude */
131 
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);
137 
138 	return ulawbyte;
139 }
140 
141 void 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 
158 void
159 dsp_audio_generate_s2law_table(void)
160 {
161 	int i;
162 
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));
168 		}
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));
174 		}
175 	}
176 }
177 
178 
179 /*
180  * the seven bit sample is the number of every second alaw-sample ordered by
181  * aplitude. 0x00 is negative, 0x7f is positive amplitude.
182  */
183 u8 dsp_audio_seven2law[128];
184 u8 dsp_audio_law2seven[256];
185 
186 /********************************************************************
187  * generate table for conversion law from/to 7-bit alaw-like sample *
188  ********************************************************************/
189 
190 void
191 dsp_audio_generate_seven(void)
192 {
193 	int i, j, k;
194 	u8 spl;
195 	u8 sorted_alaw[256];
196 
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++;
204 		}
205 		sorted_alaw[j] = i;
206 	}
207 
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;
218 		}
219 		/* write 7-bit audio value */
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 /* mix 2*law -> law */
232 u8 dsp_audio_mix_law[65536];
233 
234 /******************************************************
235  * generate mix table to mix two law samples into one *
236  ******************************************************/
237 
238 void
239 dsp_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  * generate different volume changes *
265  *************************************/
266 
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];
283 
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,
301 };
302 
303 void
304 dsp_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  * change the volume of the given skb *
385  **************************************/
386 
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
389  */
390 void
391 dsp_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 	/* 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;
410 	}
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++;
420 	}
421 }
422