cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dsp_audio.c (10950B)


      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 */
     21s32 dsp_audio_ulaw_to_s32[256];
     22/* alaw[unsigned char] -> signed 16-bit */
     23s32 dsp_audio_alaw_to_s32[256];
     24
     25s32 *dsp_audio_law_to_s32;
     26EXPORT_SYMBOL(dsp_audio_law_to_s32);
     27
     28/* signed 16-bit -> law */
     29u8 dsp_audio_s16_to_law[65536];
     30EXPORT_SYMBOL(dsp_audio_s16_to_law);
     31
     32/* alaw -> ulaw */
     33u8 dsp_audio_alaw_to_ulaw[256];
     34/* ulaw -> alaw */
     35static u8 dsp_audio_ulaw_to_alaw[256];
     36u8 dsp_silence;
     37
     38
     39/*****************************************************
     40 * generate table for conversion of s16 to alaw/ulaw *
     41 *****************************************************/
     42
     43#define AMI_MASK 0x55
     44
     45static 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
     75static 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
     88static 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
    105static 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
    141void 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
    158void
    159dsp_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 */
    183u8 dsp_audio_seven2law[128];
    184u8 dsp_audio_law2seven[256];
    185
    186/********************************************************************
    187 * generate table for conversion law from/to 7-bit alaw-like sample *
    188 ********************************************************************/
    189
    190void
    191dsp_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 */
    232u8 dsp_audio_mix_law[65536];
    233
    234/******************************************************
    235 * generate mix table to mix two law samples into one *
    236 ******************************************************/
    237
    238void
    239dsp_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
    267static u8 dsp_audio_reduce8[256];
    268static u8 dsp_audio_reduce7[256];
    269static u8 dsp_audio_reduce6[256];
    270static u8 dsp_audio_reduce5[256];
    271static u8 dsp_audio_reduce4[256];
    272static u8 dsp_audio_reduce3[256];
    273static u8 dsp_audio_reduce2[256];
    274static u8 dsp_audio_reduce1[256];
    275static u8 dsp_audio_increase1[256];
    276static u8 dsp_audio_increase2[256];
    277static u8 dsp_audio_increase3[256];
    278static u8 dsp_audio_increase4[256];
    279static u8 dsp_audio_increase5[256];
    280static u8 dsp_audio_increase6[256];
    281static u8 dsp_audio_increase7[256];
    282static u8 dsp_audio_increase8[256];
    283
    284static 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
    303void
    304dsp_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 */
    390void
    391dsp_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}