dsp_audio.c revision eac74af9b547e29c9634ed5eff4d514349e73310
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 "core.h"
16#include "dsp.h"
17
18/* ulaw[unsigned char] -> signed 16-bit */
19s32 dsp_audio_ulaw_to_s32[256];
20/* alaw[unsigned char] -> signed 16-bit */
21s32 dsp_audio_alaw_to_s32[256];
22
23s32 *dsp_audio_law_to_s32;
24EXPORT_SYMBOL(dsp_audio_law_to_s32);
25
26/* signed 16-bit -> law */
27u8 dsp_audio_s16_to_law[65536];
28EXPORT_SYMBOL(dsp_audio_s16_to_law);
29
30/* alaw -> ulaw */
31u8 dsp_audio_alaw_to_ulaw[256];
32/* ulaw -> alaw */
33static u8 dsp_audio_ulaw_to_alaw[256];
34u8 dsp_silence;
35
36
37/*****************************************************
38 * generate table for conversion of s16 to alaw/ulaw *
39 *****************************************************/
40
41#define AMI_MASK 0x55
42
43static 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
73static 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
86static 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
103static 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
139static 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
152void 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
169void
170dsp_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 */
194u8 dsp_audio_seven2law[128];
195u8 dsp_audio_law2seven[256];
196
197/********************************************************************
198 * generate table for conversion law from/to 7-bit alaw-like sample *
199 ********************************************************************/
200
201void
202dsp_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 */
243u8 dsp_audio_mix_law[65536];
244
245/******************************************************
246 * generate mix table to mix two law samples into one *
247 ******************************************************/
248
249void
250dsp_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
278static u8 dsp_audio_reduce8[256];
279static u8 dsp_audio_reduce7[256];
280static u8 dsp_audio_reduce6[256];
281static u8 dsp_audio_reduce5[256];
282static u8 dsp_audio_reduce4[256];
283static u8 dsp_audio_reduce3[256];
284static u8 dsp_audio_reduce2[256];
285static u8 dsp_audio_reduce1[256];
286static u8 dsp_audio_increase1[256];
287static u8 dsp_audio_increase2[256];
288static u8 dsp_audio_increase3[256];
289static u8 dsp_audio_increase4[256];
290static u8 dsp_audio_increase5[256];
291static u8 dsp_audio_increase6[256];
292static u8 dsp_audio_increase7[256];
293static u8 dsp_audio_increase8[256];
294
295static 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
314void
315dsp_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 */
401void
402dsp_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