dsp_audio.c revision 960366cf8dbb3359afaca30cf7fdbf69a6d6dda7
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 */
33u8 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		}
217		sorted_alaw[j] = i;
218	}
219
220	/* generate tabels */
221	for (i = 0; i < 256; i++) {
222		/* spl is the source: the law-sample (converted to alaw) */
223		spl = i;
224		if (dsp_options & DSP_OPT_ULAW)
225			spl = dsp_audio_ulaw_to_alaw[i];
226		/* find the 7-bit-sample */
227		for (j = 0; j < 256; j++) {
228			if (sorted_alaw[j] == spl)
229				break;
230		}
231		/* write 7-bit audio value */
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/* mix 2*law -> law */
244u8 dsp_audio_mix_law[65536];
245
246/******************************************************
247 * generate mix table to mix two law samples into one *
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 * generate different volume changes *
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 * change the volume of the given skb *
397 **************************************/
398
399/* this is a helper function for changing volume of skb. the range may be
400 * -8 to 8, which is a shift to the power of 2. 0 == no volume, 3 == volume*8
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	/* get correct conversion table */
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	/* change volume */
428	while (i < ii) {
429		*p = volume_change[*p];
430		p++;
431		i++;
432	}
433}
434
435