dsp_audio.c revision 5d76fc219ce38a226314436563f6b9d405bb6db1
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 "core.h"
17#include "dsp.h"
18
19/* ulaw[unsigned char] -> signed 16-bit */
20s32 dsp_audio_ulaw_to_s32[256];
21/* alaw[unsigned char] -> signed 16-bit */
22s32 dsp_audio_alaw_to_s32[256];
23
24s32 *dsp_audio_law_to_s32;
25EXPORT_SYMBOL(dsp_audio_law_to_s32);
26
27/* signed 16-bit -> law */
28u8 dsp_audio_s16_to_law[65536];
29EXPORT_SYMBOL(dsp_audio_s16_to_law);
30
31/* alaw -> ulaw */
32u8 dsp_audio_alaw_to_ulaw[256];
33/* ulaw -> alaw */
34static u8 dsp_audio_ulaw_to_alaw[256];
35u8 dsp_silence;
36
37
38/*****************************************************
39 * generate table for conversion of s16 to alaw/ulaw *
40 *****************************************************/
41
42#define AMI_MASK 0x55
43
44static inline unsigned char linear2alaw(short int linear)
45{
46	int mask;
47	int seg;
48	int pcm_val;
49	static int seg_end[8] = {
50		0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF
51	};
52
53	pcm_val = linear;
54	if (pcm_val >= 0) {
55		/* Sign (7th) bit = 1 */
56		mask = AMI_MASK | 0x80;
57	} else {
58		/* Sign bit = 0 */
59		mask = AMI_MASK;
60		pcm_val = -pcm_val;
61	}
62
63	/* Convert the scaled magnitude to segment number. */
64	for (seg = 0;  seg < 8;  seg++) {
65		if (pcm_val <= seg_end[seg])
66			break;
67	}
68	/* Combine the sign, segment, and quantization bits. */
69	return  ((seg << 4) |
70		 ((pcm_val >> ((seg)  ?  (seg + 3)  :  4)) & 0x0F)) ^ mask;
71}
72
73
74static inline short int alaw2linear(unsigned char alaw)
75{
76	int i;
77	int seg;
78
79	alaw ^= AMI_MASK;
80	i = ((alaw & 0x0F) << 4) + 8 /* rounding error */;
81	seg = (((int) alaw & 0x70) >> 4);
82	if (seg)
83		i = (i + 0x100) << (seg - 1);
84	return (short int) ((alaw & 0x80)  ?  i  :  -i);
85}
86
87static inline short int ulaw2linear(unsigned char ulaw)
88{
89	short mu, e, f, y;
90	static short etab[] = {0, 132, 396, 924, 1980, 4092, 8316, 16764};
91
92	mu = 255 - ulaw;
93	e = (mu & 0x70) / 16;
94	f = mu & 0x0f;
95	y = f * (1 << (e + 3));
96	y += etab[e];
97	if (mu & 0x80)
98		y = -y;
99	return y;
100}
101
102#define BIAS 0x84   /*!< define the add-in bias for 16 bit samples */
103
104static unsigned char linear2ulaw(short sample)
105{
106	static int exp_lut[256] = {
107		0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
108		4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
109		5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
110		5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
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		6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
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		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7};
123	int sign, exponent, mantissa;
124	unsigned char ulawbyte;
125
126	/* Get the sample into sign-magnitude. */
127	sign = (sample >> 8) & 0x80;	  /* set aside the sign */
128	if (sign != 0)
129		sample = -sample;	      /* get magnitude */
130
131	/* Convert from 16 bit linear to ulaw. */
132	sample = sample + BIAS;
133	exponent = exp_lut[(sample >> 7) & 0xFF];
134	mantissa = (sample >> (exponent + 3)) & 0x0F;
135	ulawbyte = ~(sign | (exponent << 4) | mantissa);
136
137	return ulawbyte;
138}
139
140static int reverse_bits(int i)
141{
142	int z, j;
143	z = 0;
144
145	for (j = 0; j < 8; j++) {
146		if ((i & (1 << j)) != 0)
147			z |= 1 << (7 - j);
148	}
149	return z;
150}
151
152
153void dsp_audio_generate_law_tables(void)
154{
155	int i;
156	for (i = 0; i < 256; i++)
157		dsp_audio_alaw_to_s32[i] = alaw2linear(reverse_bits(i));
158
159	for (i = 0; i < 256; i++)
160		dsp_audio_ulaw_to_s32[i] = ulaw2linear(reverse_bits(i));
161
162	for (i = 0; i < 256; i++) {
163		dsp_audio_alaw_to_ulaw[i] =
164			linear2ulaw(dsp_audio_alaw_to_s32[i]);
165		dsp_audio_ulaw_to_alaw[i] =
166			linear2alaw(dsp_audio_ulaw_to_s32[i]);
167	}
168}
169
170void
171dsp_audio_generate_s2law_table(void)
172{
173	int i;
174
175	if (dsp_options & DSP_OPT_ULAW) {
176		/* generating ulaw-table */
177		for (i = -32768; i < 32768; i++) {
178			dsp_audio_s16_to_law[i & 0xffff] =
179				reverse_bits(linear2ulaw(i));
180		}
181	} else {
182		/* generating alaw-table */
183		for (i = -32768; i < 32768; i++) {
184			dsp_audio_s16_to_law[i & 0xffff] =
185				reverse_bits(linear2alaw(i));
186		}
187	}
188}
189
190
191/*
192 * the seven bit sample is the number of every second alaw-sample ordered by
193 * aplitude. 0x00 is negative, 0x7f is positive amplitude.
194 */
195u8 dsp_audio_seven2law[128];
196u8 dsp_audio_law2seven[256];
197
198/********************************************************************
199 * generate table for conversion law from/to 7-bit alaw-like sample *
200 ********************************************************************/
201
202void
203dsp_audio_generate_seven(void)
204{
205	int i, j, k;
206	u8 spl;
207	u8 sorted_alaw[256];
208
209	/* generate alaw table, sorted by the linear value */
210	for (i = 0; i < 256; i++) {
211		j = 0;
212		for (k = 0; k < 256; k++) {
213			if (dsp_audio_alaw_to_s32[k]
214			    < dsp_audio_alaw_to_s32[i])
215				j++;
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